Beispiel #1
0
    def get_skydir_lthist(self, skydir, cth_bins):
        """Get the livetime distribution (observing profile) for a given sky
        direction with binning in incidence angle defined by
        ``cth_bins``.

        Parameters
        ----------
        skydir : `~astropy.coordinates.SkyCoord`
            Sky coordinate for which the observing profile will be
            computed.

        cth_bins : `~numpy.ndarray`
            Bin edges in cosine of the incidence angle.

        """
        ra = skydir.ra.deg
        dec = skydir.dec.deg

        npts = 1
        bins = utils.split_bin_edges(cth_bins, npts)

        center = edge_to_center(bins)
        width = edge_to_width(bins)
        ipix = hp.ang2pix(self.hpx.nside, np.pi / 2. - np.radians(dec),
                          np.radians(ra), nest=self.hpx.nest)
        lt = np.histogram(self._cth_center,
                          weights=self.data[:, ipix], bins=bins)[0]
        lt = np.sum(lt.reshape(-1, npts), axis=1)
        return lt
Beispiel #2
0
    def get_skydir_lthist(self, skydir, cth_bins):
        """Get the livetime distribution (observing profile) for a given sky
        direction with binning in incidence angle defined by
        ``cth_bins``.

        Parameters
        ----------
        skydir : `~astropy.coordinates.SkyCoord`
            Sky coordinate for which the observing profile will be
            computed.

        cth_bins : `~numpy.ndarray`
            Bin edges in cosine of the incidence angle.

        """
        ra = skydir.ra.deg
        dec = skydir.dec.deg

        npts = 1
        bins = utils.split_bin_edges(cth_bins, npts)

        center = edge_to_center(bins)
        width = edge_to_width(bins)
        ipix = hp.ang2pix(self.hpx.nside, np.pi / 2. - np.radians(dec),
                          np.radians(ra), nest=self.hpx.nest)
        lt = np.histogram(self._cth_center,
                          weights=self.data[:, ipix], bins=bins)[0]
        lt = np.sum(lt.reshape(-1, npts), axis=1)
        return lt
Beispiel #3
0
 def create_empty(cls, tstart, tstop, fill=0.0, nside=64):
     """Create an empty livetime cube."""
     cth_edges = np.linspace(0, 1.0, 41)
     domega = utils.edge_to_width(cth_edges) * 2.0 * np.pi
     hpx = HPX(nside, True, 'CEL', ebins=cth_edges)
     data = np.ones((len(cth_edges) - 1, hpx.npix)) * fill
     return cls(data, hpx, cth_edges, tstart=tstart, tstop=tstop)
Beispiel #4
0
    def get_skydir_lthist(self, skydir, cth_bins):
        """Get the livetime distribution (observing profile) for a given sky
        direction with binning in incidence angle defined by
        ``cth_bins``.

        Parameters
        ----------
        skydir : `~astropy.coordinates.SkyCoord`
            Sky coordinate for which the observing profile will be
            computed.

        cth_bins : `~numpy.ndarray`
            Bin edges in cosine of the incidence angle.

        """
        ra = skydir.ra.deg
        dec = skydir.dec.deg

        bins = np.linspace(cth_bins[0], cth_bins[-1],
                            (len(cth_bins) - 1) * 4 + 1)
        center = edge_to_center(bins)
        width = edge_to_width(bins)
        ipix = hp.ang2pix(self.hpx.nside, np.pi / 2. - np.radians(dec),
                          np.radians(ra), nest=self.hpx.nest)
        lt = np.interp(center, self._cth_center,
                       self.data[:, ipix] / self._cth_width) * width
        lt = np.sum(lt.reshape(-1, 4), axis=1)
        return lt
Beispiel #5
0
 def create_empty(cls, tstart, tstop, fill=0.0, nside=64):
     """Create an empty livetime cube."""
     cth_edges = np.linspace(0, 1.0, 41)
     domega = utils.edge_to_width(cth_edges) * 2.0 * np.pi
     hpx = HPX(nside, True, 'CEL', ebins=cth_edges)
     data = np.ones((len(cth_edges) - 1, hpx.npix)) * fill
     return cls(data, hpx, cth_edges, tstart=tstart, tstop=tstop)
Beispiel #6
0
def compute_ps_counts(ebins, exp, psf, bkg, fn, egy_dim=0, spatial_model='PointSource',
                      spatial_size=1E-3):
    """Calculate the observed signal and background counts given models
    for the exposure, background intensity, PSF, and source flux.

    Parameters
    ----------
    ebins : `~numpy.ndarray`
        Array of energy bin edges.

    exp : `~numpy.ndarray`
        Model for exposure.

    psf : `~fermipy.irfs.PSFModel`
        Model for average PSF.

    bkg : `~numpy.ndarray`
        Array of background intensities.

    fn : `~fermipy.spectrum.SpectralFunction`

    egy_dim : int
        Index of energy dimension in ``bkg`` and ``exp`` arrays.

    """
    ewidth = utils.edge_to_width(ebins)
    ectr = np.exp(utils.edge_to_center(np.log(ebins)))

    r68 = psf.containment_angle(ectr, fraction=0.68)
    if spatial_model != 'PointSource':
        r68[r68 < spatial_size] = spatial_size

    # * np.ones((len(ectr), 31))
    theta_edges = np.linspace(0.0, 3.0, 31)[np.newaxis, :]
    theta_edges = theta_edges * r68[:, np.newaxis]
    theta = 0.5 * (theta_edges[:, :-1] + theta_edges[:, 1:])
    domega = np.pi * (theta_edges[:, 1:]**2 - theta_edges[:, :-1]**2)

    if spatial_model == 'PointSource':
        sig_pdf = domega * psf.interp(ectr[:, np.newaxis], theta)
    elif spatial_model == 'RadialGaussian':
        sig_pdf = domega * utils.convolve2d_gauss(lambda t: psf.interp(ectr[:, np.newaxis, np.newaxis], t),
                                                  theta, spatial_size / 1.5095921854516636, nstep=2000)
    elif spatial_model == 'RadialDisk':
        sig_pdf = domega * utils.convolve2d_disk(lambda t: psf.interp(ectr[:, np.newaxis, np.newaxis], t),
                                                 theta, spatial_size / 0.8246211251235321)
    else:
        raise ValueError('Invalid spatial model: {}'.format(spatial_model))

    sig_pdf *= (np.pi / 180.)**2
    sig_flux = fn.flux(ebins[:-1], ebins[1:])

    # Background and signal counts
    bkgc = bkg[..., np.newaxis] * domega * exp[..., np.newaxis] * \
        ewidth[..., np.newaxis] * (np.pi / 180.)**2
    sigc = sig_pdf * sig_flux[..., np.newaxis] * exp[..., np.newaxis]

    return sigc, bkgc
Beispiel #7
0
 def __init__(self, data, hpx, cth_edges, tstart=None, tstop=None):
     HpxMap.__init__(self, data, hpx)
     self._cth_edges = cth_edges
     self._cth_center = edge_to_center(self._cth_edges)
     self._cth_width = edge_to_width(self._cth_edges)
     self._domega = (self._cth_edges[1:] -
                     self._cth_edges[:-1]) * 2 * np.pi
     self._tstart = tstart
     self._tstop = tstop
Beispiel #8
0
    def plot_projection(self,iaxis,**kwargs):

        data = kwargs.pop('data',self._data)
        noerror = kwargs.pop('noerror',False)
        
        axes = wcs_to_axes(self._wcs,self._data.shape[::-1])
        x = edge_to_center(axes[iaxis])
        w = edge_to_width(axes[iaxis])
        
        c = self.get_data_projection(data,axes,iaxis,erange=self._erange)
        
        if noerror:
            plt.errorbar(x,c,**kwargs)
        else:
            plt.errorbar(x,c,yerr=c**0.5,xerr=w/2.,**kwargs)
Beispiel #9
0
def calc_drm(skydir, ltc, event_class, event_types,
             egy_bins, cth_bins, nbin=64):
    """Calculate the detector response matrix."""
    npts = int(np.ceil(128. / bins_per_dec(egy_bins)))
    egy_bins = np.exp(utils.split_bin_edges(np.log(egy_bins), npts))

    etrue_bins = 10**np.linspace(1.0, 6.5, nbin * 5.5 + 1)
    egy = 10**utils.edge_to_center(np.log10(egy_bins))
    egy_width = utils.edge_to_width(egy_bins)
    etrue = 10**utils.edge_to_center(np.log10(etrue_bins))
    edisp = create_avg_edisp(skydir, ltc, event_class, event_types,
                             egy, etrue, cth_bins)
    edisp = edisp * egy_width[:, None, None]
    edisp = sum_bins(edisp, 0, npts)
    return edisp
Beispiel #10
0
def calc_drm(skydir, ltc, event_class, event_types,
             egy_bins, cth_bins, nbin=64):
    """Calculate the detector response matrix."""
    npts = int(np.ceil(128. / bins_per_dec(egy_bins)))
    egy_bins = np.exp(utils.split_bin_edges(np.log(egy_bins), npts))
    
    etrue_bins = 10**np.linspace(1.0, 6.5, nbin * 5.5 + 1)
    egy = 10**utils.edge_to_center(np.log10(egy_bins))
    egy_width = utils.edge_to_width(egy_bins)
    etrue = 10**utils.edge_to_center(np.log10(etrue_bins))
    edisp = create_avg_edisp(skydir, ltc, event_class, event_types,
                             egy, etrue, cth_bins)
    edisp = edisp * egy_width[:, None, None]
    edisp = sum_bins(edisp,0,npts)
    return edisp
Beispiel #11
0
    def get_src_lthist(self,skydir,cth_edges):

        ra = skydir.ra.deg
        dec = skydir.dec.deg        
        
        edges = np.linspace(cth_edges[0],cth_edges[-1],(len(cth_edges)-1)*4+1)
        center = edge_to_center(edges)
        width = edge_to_width(edges)
        
        ipix = hp.ang2pix(64,np.pi/2. - np.radians(dec),
                          np.radians(ra),nest=True)
        
        lt = np.interp(center,self._cth_center,
                       self._ltmap[ipix,::-1]/self._cth_width)*width
        lt = np.sum(lt.reshape(-1,4),axis=1)  
        return lt
Beispiel #12
0
    def load_ltfile(self,ltfile):
        
        hdulist = pyfits.open(ltfile)
                
        if self._ltmap is None:
            self._ltmap = hdulist[1].data.field(0)
            self._tstart = hdulist[0].header['TSTART']
            self._tstop = hdulist[0].header['TSTOP']
        else:
            self._ltmap += hdulist[1].data.field(0)
            self._tstart = min(self._tstart,hdulist[0].header['TSTART'])
            self._tstop = max(self._tstop,hdulist[0].header['TSTOP'])

        cth_edges = np.array(hdulist[3].data.field(0))
        cth_edges = np.concatenate(([1],cth_edges))
        self._cth_edges = cth_edges[::-1]
        self._cth_center = edge_to_center(self._cth_edges)
        self._cth_width = edge_to_width(self._cth_edges)
Beispiel #13
0
def compute_ps_counts(ebins, exp, psf, bkg, fn, egy_dim=0):
    """Calculate the observed signal and background counts given models
    for the exposure, background intensity, PSF, and source flux.

    Parameters
    ----------
    ebins : `~numpy.ndarray`
        Array of energy bin edges.

    exp : `~numpy.ndarray`
        Model for exposure.

    psf : `~fermipy.irfs.PSFModel`
        Model for average PSF.

    bkg : `~numpy.ndarray`
        Array of background intensities.

    fn : `~fermipy.spectrum.SpectralFunction`

    egy_dim : int
        Index of energy dimension in ``bkg`` and ``exp`` arrays.

    """
    ewidth = utils.edge_to_width(ebins)
    ectr = np.exp(utils.edge_to_center(np.log(ebins)))

    theta_edges = np.linspace(0.0, 3.0, 31)[
        np.newaxis, :] * np.ones((len(ectr), 31))
    theta_edges *= psf.containment_angle(ectr, fraction=0.68)[:, np.newaxis]
    theta = 0.5 * (theta_edges[:, :-1] + theta_edges[:, 1:])
    domega = np.pi * (theta_edges[:, 1:]**2 - theta_edges[:, :-1]**2)

    sig_pdf = domega * \
        psf.interp(ectr[:, np.newaxis], theta) * (np.pi / 180.)**2
    sig_flux = fn.flux(ebins[:-1], ebins[1:])

    # Background and signal counts
    bkgc = bkg[:, np.newaxis] * domega * exp[:, np.newaxis] * \
        ewidth[:, np.newaxis] * (np.pi / 180.)**2
    sigc = sig_pdf * sig_flux[:, np.newaxis] * exp[:, np.newaxis]

    return sigc, bkgc
Beispiel #14
0
def compute_ps_counts(ebins, exp, psf, bkg, fn, egy_dim=0):
    """Calculate the observed signal and background counts given models
    for the exposure, background intensity, PSF, and source flux.

    Parameters
    ----------
    ebins : `~numpy.ndarray`
        Array of energy bin edges.

    exp : `~numpy.ndarray`
        Model for exposure.

    psf : `~fermipy.irfs.PSFModel`
        Model for average PSF.

    bkg : `~numpy.ndarray`
        Array of background intensities.

    fn : `~fermipy.spectrum.SpectralFunction`

    egy_dim : int
        Index of energy dimension in ``bkg`` and ``exp`` arrays.

    """
    ewidth = utils.edge_to_width(ebins)
    ectr = np.exp(utils.edge_to_center(np.log(ebins)))

    theta_edges = np.linspace(0.0, 3.0, 31)[
        np.newaxis, :] * np.ones((len(ectr), 31))
    theta_edges *= psf.containment_angle(ectr, fraction=0.68)[:, np.newaxis]
    theta = 0.5 * (theta_edges[:, :-1] + theta_edges[:, 1:])
    domega = np.pi * (theta_edges[:, 1:]**2 - theta_edges[:, :-1]**2)

    sig_pdf = domega * \
        psf.interp(ectr[:, np.newaxis], theta) * (np.pi / 180.)**2
    sig_flux = fn.flux(ebins[:-1], ebins[1:])

    # Background and signal counts
    bkgc = bkg[:, np.newaxis] * domega * exp[:, np.newaxis] * \
        ewidth[:, np.newaxis] * (np.pi / 180.)**2
    sigc = sig_pdf * sig_flux[:, np.newaxis] * exp[:, np.newaxis]

    return sigc, bkgc
Beispiel #15
0
    def __init__(self, data, hpx, cth_edges, **kwargs):
        HpxMap.__init__(self, data, hpx)
        self._cth_edges = cth_edges
        self._cth_center = edge_to_center(self._cth_edges)
        self._cth_width = edge_to_width(self._cth_edges)
        self._domega = (self._cth_edges[1:] -
                        self._cth_edges[:-1]) * 2 * np.pi
        self._tstart = kwargs.get('tstart', None)
        self._tstop = kwargs.get('tstop', None)
        self._zmin = kwargs.get('zmin', 0.0)
        self._zmax = kwargs.get('zmax', 180.0)
        self._tab_gti = kwargs.get('tab_gti', None)
        self._header = kwargs.get('header', None)
        self._data_wt = kwargs.get('data_wt', None)

        if self._data_wt is None:
            self._data_wt = np.zeros_like(self.data)

        if self._tab_gti is None:
            cols = [Column(name='START', dtype='f8', unit='s'),
                    Column(name='STOP', dtype='f8', unit='s')]
            self._tab_gti = Table(cols)
Beispiel #16
0
    def __init__(self, data, hpx, cth_edges, **kwargs):
        HpxMap.__init__(self, data, hpx)
        self._cth_edges = cth_edges
        self._cth_center = edge_to_center(self._cth_edges)
        self._cth_width = edge_to_width(self._cth_edges)
        self._domega = (self._cth_edges[1:] -
                        self._cth_edges[:-1]) * 2 * np.pi
        self._tstart = kwargs.get('tstart', None)
        self._tstop = kwargs.get('tstop', None)
        self._zmin = kwargs.get('zmin', 0.0)
        self._zmax = kwargs.get('zmax', 180.0)
        self._tab_gti = kwargs.get('tab_gti', None)
        self._header = kwargs.get('header', None)
        self._data_wt = kwargs.get('data_wt', None)

        if self._data_wt is None:
            self._data_wt = np.zeros_like(self.data)

        if self._tab_gti is None:
            cols = [Column(name='START', dtype='f8', unit='s'),
                    Column(name='STOP', dtype='f8', unit='s')]
            self._tab_gti = Table(cols)
Beispiel #17
0
def compute_ps_counts(ebins,
                      exp,
                      psf,
                      bkg,
                      fn,
                      egy_dim=0,
                      spatial_model='PointSource',
                      spatial_size=1E-3):
    """Calculate the observed signal and background counts given models
    for the exposure, background intensity, PSF, and source flux.

    Parameters
    ----------
    ebins : `~numpy.ndarray`
        Array of energy bin edges.

    exp : `~numpy.ndarray`
        Model for exposure.

    psf : `~fermipy.irfs.PSFModel`
        Model for average PSF.

    bkg : `~numpy.ndarray`
        Array of background intensities.

    fn : `~fermipy.spectrum.SpectralFunction`

    egy_dim : int
        Index of energy dimension in ``bkg`` and ``exp`` arrays.

    """
    ewidth = utils.edge_to_width(ebins)
    ectr = np.exp(utils.edge_to_center(np.log(ebins)))

    r68 = psf.containment_angle(ectr, fraction=0.68)
    if spatial_model != 'PointSource':
        r68[r68 < spatial_size] = spatial_size

    # * np.ones((len(ectr), 31))
    theta_edges = np.linspace(0.0, 3.0, 31)[np.newaxis, :]
    theta_edges = theta_edges * r68[:, np.newaxis]
    theta = 0.5 * (theta_edges[:, :-1] + theta_edges[:, 1:])
    domega = np.pi * (theta_edges[:, 1:]**2 - theta_edges[:, :-1]**2)

    if spatial_model == 'PointSource':
        sig_pdf = domega * psf.interp(ectr[:, np.newaxis], theta)
    elif spatial_model == 'RadialGaussian':
        sig_pdf = domega * utils.convolve2d_gauss(
            lambda t: psf.interp(ectr[:, np.newaxis, np.newaxis], t),
            theta,
            spatial_size / 1.5095921854516636,
            nstep=2000)
    elif spatial_model == 'RadialDisk':
        sig_pdf = domega * utils.convolve2d_disk(
            lambda t: psf.interp(ectr[:, np.newaxis, np.newaxis], t), theta,
            spatial_size / 0.8246211251235321)
    else:
        raise ValueError('Invalid spatial model: {}'.format(spatial_model))

    sig_pdf *= (np.pi / 180.)**2
    sig_flux = fn.flux(ebins[:-1], ebins[1:])

    # Background and signal counts
    bkgc = bkg[..., np.newaxis] * domega * exp[..., np.newaxis] * \
        ewidth[..., np.newaxis] * (np.pi / 180.)**2
    sigc = sig_pdf * sig_flux[..., np.newaxis] * exp[..., np.newaxis]

    return sigc, bkgc