Beispiel #1
0
def test_wcsndmap_fill_by_coord(npix, binsz, coordsys, proj, skydir, axes):
    geom = WcsGeom.create(npix=npix,
                          binsz=binsz,
                          skydir=skydir,
                          proj=proj,
                          coordsys=coordsys,
                          axes=axes)
    m = WcsNDMap(geom)
    coords = m.geom.get_coord()
    fill_coords = tuple([np.concatenate((t, t)) for t in coords])
    fill_vals = fill_coords[1]
    m.fill_by_coord(fill_coords, fill_vals)
    assert_allclose(m.get_by_coord(coords), 2.0 * coords[1])

    # Test with SkyCoords
    m = WcsNDMap(geom)
    coords = m.geom.get_coord()
    skydir = SkyCoord(coords[0],
                      coords[1],
                      unit="deg",
                      frame=coordsys_to_frame(geom.coordsys))
    skydir_cel = skydir.transform_to("icrs")
    skydir_gal = skydir.transform_to("galactic")
    fill_coords_cel = (skydir_cel, ) + tuple(coords[2:])
    fill_coords_gal = (skydir_gal, ) + tuple(coords[2:])
    m.fill_by_coord(fill_coords_cel, coords[1])
    m.fill_by_coord(fill_coords_gal, coords[1])
    assert_allclose(m.get_by_coord(coords), 2.0 * coords[1])
Beispiel #2
0
def test_wcsndmap_set_get_by_coord(npix, binsz, coordsys, proj, skydir, axes):
    geom = WcsGeom.create(npix=npix,
                          binsz=binsz,
                          skydir=skydir,
                          proj=proj,
                          coordsys=coordsys,
                          axes=axes)
    m = WcsNDMap(geom)
    coords = m.geom.get_coord()
    m.set_by_coord(coords, coords[0])
    assert_allclose(coords[0], m.get_by_coord(coords))

    if not geom.is_allsky:
        coords[1][...] = 0.0
        assert_allclose(np.nan * np.ones(coords[0].shape),
                        m.get_by_coord(coords))

    # Test with SkyCoords
    m = WcsNDMap(geom)
    coords = m.geom.get_coord()
    skydir = SkyCoord(coords[0],
                      coords[1],
                      unit="deg",
                      frame=coordsys_to_frame(geom.coordsys))
    skydir_cel = skydir.transform_to("icrs")
    skydir_gal = skydir.transform_to("galactic")

    m.set_by_coord((skydir_gal, ) + tuple(coords[2:]), coords[0])
    assert_allclose(coords[0], m.get_by_coord(coords))
    assert_allclose(
        m.get_by_coord((skydir_cel, ) + tuple(coords[2:])),
        m.get_by_coord((skydir_gal, ) + tuple(coords[2:])),
    )

    # Test with MapCoord
    m = WcsNDMap(geom)
    coords = m.geom.get_coord()
    coords_dict = dict(lon=coords[0], lat=coords[1])
    if axes:
        for i, ax in enumerate(axes):
            coords_dict[ax.name] = coords[i + 2]
    map_coords = MapCoord.create(coords_dict, coordsys=coordsys)
    m.set_by_coord(map_coords, coords[0])
    assert_allclose(coords[0], m.get_by_coord(map_coords))
Beispiel #3
0
def test_hpxmap_set_get_by_coord(nside, nested, coordsys, region, axes):
    m = create_map(nside, nested, coordsys, region, axes)
    coords = m.geom.get_coord(flat=True)
    m.set_by_coord(coords, coords[0])
    assert_allclose(coords[0], m.get_by_coord(coords))

    # Test with SkyCoords
    m = create_map(nside, nested, coordsys, region, axes)
    coords = m.geom.get_coord(flat=True)
    skydir = SkyCoord(coords[0],
                      coords[1],
                      unit="deg",
                      frame=coordsys_to_frame(m.geom.coordsys))
    skydir_cel = skydir.transform_to("icrs")
    skydir_gal = skydir.transform_to("galactic")
    m.set_by_coord((skydir_gal, ) + tuple(coords[2:]), coords[0])
    assert_allclose(coords[0], m.get_by_coord(coords))
    assert_allclose(
        m.get_by_coord((skydir_cel, ) + tuple(coords[2:])),
        m.get_by_coord((skydir_gal, ) + tuple(coords[2:])),
    )
Beispiel #4
0
    def _make_tsmap_fast(self, prefix, **kwargs):
        """
        Make a TS map from a GTAnalysis instance.  This is a
        simplified implementation optimized for speed that only fits
        for the source normalization (all background components are
        kept fixed). The spectral/spatial characteristics of the test
        source can be defined with the src_dict argument.  By default
        this method will generate a TS map for a point source with an
        index=2.0 power-law spectrum.

        Parameters
        ----------
        model : dict or `~fermipy.roi_model.Source`
           Dictionary or Source object defining the properties of the
           test source that will be used in the scan.

        """
        loglevel = kwargs.get('loglevel', self.loglevel)

        src_dict = copy.deepcopy(kwargs.setdefault('model', {}))
        src_dict = {} if src_dict is None else src_dict

        multithread = kwargs.setdefault('multithread', False)
        threshold = kwargs.setdefault('threshold', 1E-2)
        max_kernel_radius = kwargs.get('max_kernel_radius')
        loge_bounds = kwargs.setdefault('loge_bounds', None)
        use_pylike = kwargs.setdefault('use_pylike', True)

        if loge_bounds:
            if len(loge_bounds) != 2:
                raise Exception('Wrong size of loge_bounds array.')
            loge_bounds[0] = (loge_bounds[0] if loge_bounds[0] is not None else
                              self.log_energies[0])
            loge_bounds[1] = (loge_bounds[1] if loge_bounds[1] is not None else
                              self.log_energies[-1])
        else:
            loge_bounds = [self.log_energies[0], self.log_energies[-1]]

        # Put the test source at the pixel closest to the ROI center
        xpix, ypix = (np.round(
            (self.npix - 1.0) / 2.), np.round((self.npix - 1.0) / 2.))
        cpix = np.array([xpix, ypix])

        map_geom = self._geom.to_image()
        frame = coordsys_to_frame(map_geom.coordsys)
        skydir = SkyCoord(*map_geom.pix_to_coord((cpix[0], cpix[1])),
                          frame=frame,
                          unit='deg')
        skydir = skydir.transform_to('icrs')

        src_dict['ra'] = skydir.ra.deg
        src_dict['dec'] = skydir.dec.deg
        src_dict.setdefault('SpatialModel', 'PointSource')
        src_dict.setdefault('SpatialWidth', 0.3)
        src_dict.setdefault('Index', 2.0)
        src_dict.setdefault('Prefactor', 1E-13)

        counts = []
        bkg = []
        model = []
        c0_map = []
        eslices = []
        enumbins = []
        model_npred = 0
        for c in self.components:

            imin = utils.val_to_edge(c.log_energies, loge_bounds[0])[0]
            imax = utils.val_to_edge(c.log_energies, loge_bounds[1])[0]

            eslice = slice(imin, imax)
            bm = c.model_counts_map(
                exclude=kwargs['exclude']).data.astype('float')[eslice, ...]
            cm = c.counts_map().data.astype('float')[eslice, ...]

            bkg += [bm]
            counts += [cm]
            c0_map += [cash(cm, bm)]
            eslices += [eslice]
            enumbins += [cm.shape[0]]

        self.add_source('tsmap_testsource',
                        src_dict,
                        free=True,
                        init_source=False,
                        use_single_psf=True,
                        use_pylike=use_pylike,
                        loglevel=logging.DEBUG)
        src = self.roi['tsmap_testsource']
        # self.logger.info(str(src_dict))
        modelname = utils.create_model_name(src)
        for c, eslice in zip(self.components, eslices):
            mm = c.model_counts_map('tsmap_testsource').data.astype('float')[
                eslice, ...]
            model_npred += np.sum(mm)
            model += [mm]

        self.delete_source('tsmap_testsource', loglevel=logging.DEBUG)

        for i, mm in enumerate(model):

            dpix = 3
            for j in range(mm.shape[0]):

                ix, iy = np.unravel_index(np.argmax(mm[j, ...]), mm[j,
                                                                    ...].shape)

                mx = mm[j, ix, :] > mm[j, ix, iy] * threshold
                my = mm[j, :, iy] > mm[j, ix, iy] * threshold
                dpix = max(dpix, np.round(np.sum(mx) / 2.))
                dpix = max(dpix, np.round(np.sum(my) / 2.))

            if max_kernel_radius is not None and \
                    dpix > int(max_kernel_radius / self.components[i].binsz):
                dpix = int(max_kernel_radius / self.components[i].binsz)

            xslice = slice(max(int(xpix - dpix), 0),
                           min(int(xpix + dpix + 1), self.npix))
            model[i] = model[i][:, xslice, xslice]

        ts_values = np.zeros((self.npix, self.npix))
        amp_values = np.zeros((self.npix, self.npix))

        wrap = functools.partial(_ts_value_newton,
                                 counts=counts,
                                 bkg=bkg,
                                 model=model,
                                 C_0_map=c0_map)

        if kwargs['map_skydir'] is not None:

            map_offset = wcs_utils.skydir_to_pix(kwargs['map_skydir'],
                                                 map_geom.wcs)

            map_delta = 0.5 * kwargs['map_size'] / self.components[0].binsz
            xmin = max(int(np.ceil(map_offset[1] - map_delta)), 0)
            xmax = min(int(np.floor(map_offset[1] + map_delta)) + 1, self.npix)
            ymin = max(int(np.ceil(map_offset[0] - map_delta)), 0)
            ymax = min(int(np.floor(map_offset[0] + map_delta)) + 1, self.npix)

            xslice = slice(xmin, xmax)
            yslice = slice(ymin, ymax)
            xyrange = [range(xmin, xmax), range(ymin, ymax)]

            wcs = map_geom.wcs.deepcopy()
            npix = (ymax - ymin, xmax - xmin)
            crpix = (map_geom._crpix[0] - ymin, map_geom._crpix[1] - xmin)
            wcs.wcs.crpix[0] -= ymin
            wcs.wcs.crpix[1] -= xmin

            # FIXME: We should implement this with a proper cutout method
            map_geom = WcsGeom(wcs, npix, crpix=crpix)
        else:
            xyrange = [range(self.npix), range(self.npix)]
            xslice = slice(0, self.npix)
            yslice = slice(0, self.npix)

        positions = []
        for i, j in itertools.product(xyrange[0], xyrange[1]):
            p = [[k // 2, i, j] for k in enumbins]
            positions += [p]

        self.logger.log(loglevel, 'Fitting test source.')
        if multithread:
            pool = Pool()
            results = pool.map(wrap, positions)
            pool.close()
            pool.join()
        else:
            results = map(wrap, positions)

        for i, r in enumerate(results):
            ix = positions[i][0][1]
            iy = positions[i][0][2]
            ts_values[ix, iy] = r[0]
            amp_values[ix, iy] = r[1]

        ts_values = ts_values[xslice, yslice]
        amp_values = amp_values[xslice, yslice]

        ts_map = WcsNDMap(map_geom, ts_values)
        sqrt_ts_map = WcsNDMap(map_geom, ts_values**0.5)
        npred_map = WcsNDMap(map_geom, amp_values * model_npred)
        amp_map = WcsNDMap(map_geom, amp_values * src.get_norm())

        o = {
            'name': utils.join_strings([prefix, modelname]),
            'src_dict': copy.deepcopy(src_dict),
            'file': None,
            'ts': ts_map,
            'sqrt_ts': sqrt_ts_map,
            'npred': npred_map,
            'amplitude': amp_map,
            'loglike': -self.like(),
            'config': kwargs
        }

        return o
Beispiel #5
0
    def _make_ts_cube(self, prefix, **kwargs):

        map_skydir = kwargs.get('map_skydir')
        map_size = kwargs.get('map_size')
        exclude = kwargs.get('exclude', [])

        # We take the coordinate system and the bin size from the underlying map
        skywcs = self._geom.wcs
        galactic = wcs_utils.is_galactic(skywcs)
        pixsize = max(np.abs(skywcs.wcs.cdelt))

        # If the map_size is not specified we need to find the right number of pixels
        if map_size is None:
            npix = max(self._geom.npix)[0]
            map_size = pixsize * npix
        else:
            npix = int(np.round(map_size / pixsize))

        saved_state = LikelihoodState(self.like)

        for ex_src in exclude:
            self.zero_source(ex_src)

        if map_skydir is None:
            # Take the center of the wcs
            map_geom = self._geom.to_image()
            frame = coordsys_to_frame(map_geom.coordsys)
            map_skydir = SkyCoord(*map_geom.pix_to_coord(
                self._geom.wcs.wcs.crpix),
                                  frame=frame,
                                  unit='deg')
            map_skydir = map_skydir.transform_to('icrs')

        refdir = pyLike.SkyDir(map_skydir.ra.deg, map_skydir.dec.deg)

        src_dict = copy.deepcopy(kwargs.setdefault('model', {}))
        src_dict = {} if src_dict is None else src_dict

        src_dict['ra'] = map_skydir.ra.deg
        src_dict['dec'] = map_skydir.dec.deg
        src_dict.setdefault('SpatialModel', 'PointSource')
        src_dict.setdefault('SpatialWidth', 0.3)
        src_dict.setdefault('Index', 2.0)
        src_dict.setdefault('Prefactor', 1.0)
        src_dict['name'] = 'tscube_testsource'

        src = Source.create_from_dict(src_dict)
        if 'Prefactor' in src.spectral_pars:
            src.spectral_pars['Prefactor']['scale'] = 1.0e-10

        modelname = utils.create_model_name(src)
        pylike_src = self.components[0]._create_source(src)
        pylike_src.spectrum().normPar().setBounds(0, 1E6)

        skyproj = pyLike.FitScanner.buildSkyProj(str("AIT"), refdir, pixsize,
                                                 npix, galactic)

        optFactory = pyLike.OptimizerFactory_instance()
        optObject = optFactory.create(str("MINUIT"), self.like.composite)

        fitScanner = pyLike.FitScanner(self.like.composite, optObject, skyproj,
                                       npix, npix)
        fitScanner.set_quiet(True)
        fitScanner.setTestSource(pylike_src)

        self.logger.info("Running tscube")
        outfile = utils.format_filename(self.config['fileio']['workdir'],
                                        'tscube.fits',
                                        prefix=[prefix])

        fitScanner.run_tscube(True, kwargs['do_sed'], kwargs['nnorm'],
                              kwargs['norm_sigma'], kwargs['cov_scale_bb'],
                              kwargs['cov_scale'], kwargs['tol'],
                              kwargs['max_iter'], kwargs['tol_type'],
                              kwargs['remake_test_source'],
                              kwargs['st_scan_level'], str(''),
                              kwargs['init_lambda'])

        self.logger.info("Writing FITS output")

        fitScanner.writeFitsFile(str(outfile), str("gttscube"), "", False,
                                 pyLike.FitScanner.TSMAP_ONLY)
        saved_state.restore()

        convert_tscube(str(outfile), str(outfile))

        tscube = castro.TSCube.create_from_fits(outfile)
        ts_map = tscube.tsmap
        norm_map = tscube.normmap
        npred_map = copy.deepcopy(norm_map)
        npred_map.data *= tscube.refSpec.ref_npred.sum()
        amp_map = copy.deepcopy(norm_map)
        amp_map.data *= pylike_src.spectrum().normPar().getValue()
        sqrt_ts_map = copy.deepcopy(ts_map)
        sqrt_ts_map.data[...] = np.abs(sqrt_ts_map.data)**0.5

        o = {
            'name': utils.join_strings([prefix, modelname]),
            'src_dict': copy.deepcopy(src_dict),
            'file': os.path.basename(outfile),
            'ts': ts_map,
            'sqrt_ts': sqrt_ts_map,
            'npred': npred_map,
            'amplitude': amp_map,
            'config': kwargs,
            'tscube': tscube
        }

        if not kwargs['write_fits']:
            os.remove(outfile)
            o['file'] = None

        self.logger.info("Done")
        return o
Beispiel #6
0
    def _make_tsmap_fast(self, prefix, **kwargs):
        """
        Make a TS map from a GTAnalysis instance.  This is a
        simplified implementation optimized for speed that only fits
        for the source normalization (all background components are
        kept fixed). The spectral/spatial characteristics of the test
        source can be defined with the src_dict argument.  By default
        this method will generate a TS map for a point source with an
        index=2.0 power-law spectrum.

        Parameters
        ----------
        model : dict or `~fermipy.roi_model.Source`
           Dictionary or Source object defining the properties of the
           test source that will be used in the scan.

        """
        loglevel = kwargs.get('loglevel', self.loglevel)

        src_dict = copy.deepcopy(kwargs.setdefault('model', {}))
        src_dict = {} if src_dict is None else src_dict

        multithread = kwargs.setdefault('multithread', False)
        threshold = kwargs.setdefault('threshold', 1E-2)
        max_kernel_radius = kwargs.get('max_kernel_radius')
        loge_bounds = kwargs.setdefault('loge_bounds', None)
        use_pylike = kwargs.setdefault('use_pylike', True)

        if loge_bounds:
            if len(loge_bounds) != 2:
                raise Exception('Wrong size of loge_bounds array.')
            loge_bounds[0] = (loge_bounds[0] if loge_bounds[0] is not None
                              else self.log_energies[0])
            loge_bounds[1] = (loge_bounds[1] if loge_bounds[1] is not None
                              else self.log_energies[-1])
        else:
            loge_bounds = [self.log_energies[0], self.log_energies[-1]]

        # Put the test source at the pixel closest to the ROI center
        xpix, ypix = (np.round((self.npix - 1.0) / 2.),
                      np.round((self.npix - 1.0) / 2.))
        cpix = np.array([xpix, ypix])

        map_geom = self._geom.to_image()
        frame = coordsys_to_frame(map_geom.coordsys)
        skydir = SkyCoord(*map_geom.pix_to_coord((cpix[0], cpix[1])),
                          frame=frame, unit='deg')
        skydir = skydir.transform_to('icrs')

        src_dict['ra'] = skydir.ra.deg
        src_dict['dec'] = skydir.dec.deg
        src_dict.setdefault('SpatialModel', 'PointSource')
        src_dict.setdefault('SpatialWidth', 0.3)
        src_dict.setdefault('Index', 2.0)
        src_dict.setdefault('Prefactor', 1E-13)

        counts = []
        bkg = []
        model = []
        c0_map = []
        eslices = []
        enumbins = []
        model_npred = 0
        for c in self.components:

            imin = utils.val_to_edge(c.log_energies, loge_bounds[0])[0]
            imax = utils.val_to_edge(c.log_energies, loge_bounds[1])[0]

            eslice = slice(imin, imax)
            bm = c.model_counts_map(exclude=kwargs['exclude']).data.astype('float')[
                eslice, ...]
            cm = c.counts_map().data.astype('float')[eslice, ...]

            bkg += [bm]
            counts += [cm]
            c0_map += [cash(cm, bm)]
            eslices += [eslice]
            enumbins += [cm.shape[0]]

        self.add_source('tsmap_testsource', src_dict, free=True,
                        init_source=False, use_single_psf=True,
                        use_pylike=use_pylike,
                        loglevel=logging.DEBUG)
        src = self.roi['tsmap_testsource']
        # self.logger.info(str(src_dict))
        modelname = utils.create_model_name(src)
        for c, eslice in zip(self.components, eslices):
            mm = c.model_counts_map('tsmap_testsource').data.astype('float')[
                eslice, ...]
            model_npred += np.sum(mm)
            model += [mm]

        self.delete_source('tsmap_testsource', loglevel=logging.DEBUG)

        for i, mm in enumerate(model):

            dpix = 3
            for j in range(mm.shape[0]):

                ix, iy = np.unravel_index(
                    np.argmax(mm[j, ...]), mm[j, ...].shape)

                mx = mm[j, ix, :] > mm[j, ix, iy] * threshold
                my = mm[j, :, iy] > mm[j, ix, iy] * threshold
                dpix = max(dpix, np.round(np.sum(mx) / 2.))
                dpix = max(dpix, np.round(np.sum(my) / 2.))

            if max_kernel_radius is not None and \
                    dpix > int(max_kernel_radius / self.components[i].binsz):
                dpix = int(max_kernel_radius / self.components[i].binsz)

            xslice = slice(max(int(xpix - dpix), 0),
                           min(int(xpix + dpix + 1), self.npix))
            model[i] = model[i][:, xslice, xslice]

        ts_values = np.zeros((self.npix, self.npix))
        amp_values = np.zeros((self.npix, self.npix))

        wrap = functools.partial(_ts_value_newton, counts=counts,
                                 bkg=bkg, model=model,
                                 C_0_map=c0_map)

        if kwargs['map_skydir'] is not None:

            map_offset = wcs_utils.skydir_to_pix(kwargs['map_skydir'],
                                                 map_geom.wcs)

            map_delta = 0.5 * kwargs['map_size'] / self.components[0].binsz
            xmin = max(int(np.ceil(map_offset[1] - map_delta)), 0)
            xmax = min(int(np.floor(map_offset[1] + map_delta)) + 1, self.npix)
            ymin = max(int(np.ceil(map_offset[0] - map_delta)), 0)
            ymax = min(int(np.floor(map_offset[0] + map_delta)) + 1, self.npix)

            xslice = slice(xmin, xmax)
            yslice = slice(ymin, ymax)
            xyrange = [range(xmin, xmax), range(ymin, ymax)]

            wcs = map_geom.wcs.deepcopy()
            npix = (ymax - ymin, xmax - xmin)
            crpix = (map_geom._crpix[0] - ymin, map_geom._crpix[1] - xmin)
            wcs.wcs.crpix[0] -= ymin
            wcs.wcs.crpix[1] -= xmin

            # FIXME: We should implement this with a proper cutout method
            map_geom = WcsGeom(wcs, npix, crpix=crpix)
        else:
            xyrange = [range(self.npix), range(self.npix)]
            xslice = slice(0, self.npix)
            yslice = slice(0, self.npix)

        positions = []
        for i, j in itertools.product(xyrange[0], xyrange[1]):
            p = [[k // 2, i, j] for k in enumbins]
            positions += [p]

        self.logger.log(loglevel, 'Fitting test source.')
        if multithread:
            pool = Pool()
            results = pool.map(wrap, positions)
            pool.close()
            pool.join()
        else:
            results = map(wrap, positions)

        for i, r in enumerate(results):
            ix = positions[i][0][1]
            iy = positions[i][0][2]
            ts_values[ix, iy] = r[0]
            amp_values[ix, iy] = r[1]

        ts_values = ts_values[xslice, yslice]
        amp_values = amp_values[xslice, yslice]

        ts_map = WcsNDMap(map_geom, ts_values)
        sqrt_ts_map = WcsNDMap(map_geom, ts_values**0.5)
        npred_map = WcsNDMap(map_geom, amp_values * model_npred)
        amp_map = WcsNDMap(map_geom, amp_values * src.get_norm())

        o = {'name': utils.join_strings([prefix, modelname]),
             'src_dict': copy.deepcopy(src_dict),
             'file': None,
             'ts': ts_map,
             'sqrt_ts': sqrt_ts_map,
             'npred': npred_map,
             'amplitude': amp_map,
             'loglike': -self.like(),
             'config': kwargs
             }

        return o