def get_model_radius(model):
    """
    extracts radius for extended source
    :param model: ~gammalib.GModelSky
    :return: radius: float
    """
    try:
        if model.spatial().type() == 'DiffuseMapCube':
            # region not implemented in gammalib, extract manually extent of the map
            # call the energies method to load the cube
            model.spatial().energies()
            # half size along x direction
            slice = model.spatial().cube().extract(0)
            ctr_pix = gammalib.GSkyPixel((slice.nx() - 1) / 2,
                                         (slice.ny() - 1) / 2)
            ctr_dir = slice.pix2dir(ctr_pix)
            bor_pix = gammalib.GSkyPixel(0., (slice.ny() - 1) / 2)
            bor_dir = slice.pix2dir(bor_pix)
            radius = bor_dir.dist_deg(ctr_dir)
        else:
            circle = gammalib.GSkyRegionCircle(model.spatial().region())
            radius = circle.radius()
    except:
        print('Cannot extract radius for model {} with spatial model type {}'.
              format(model.name(),
                     model.spatial().type()))
    return radius
Beispiel #2
0
    def _get_parameters_bkgmethod_reflected(self):
        """
        Get parameters for REFLECTED background method
        """
        # Get source shape
        self._srcshape = self['srcshape'].string()

        # Set source region (so far only CIRCLE is supported)
        if self._srcshape == 'CIRCLE':

            # Query source direction
            self._query_src_direction()

            # Query minimum number of background regions and number of
            # background regions to skip next to On region
            self['bkgregmin'].integer()
            self['bkgregskip'].integer()

            # Set circular source region
            self._rad = self['rad'].real()
            self._src_reg.append(
                gammalib.GSkyRegionCircle(self._src_dir, self._rad))

        # Query usage of background model
        self['use_model_bkg'].boolean()

        # Return
        return
Beispiel #3
0
def set_map(obsdef, radius=2.0):
    """
    Set map from observation definition dictionary

    Parameters
    ----------
    obsdef : list of dict
        List of pointing definitions
    """
    # Create sky map
    map = gammalib.GSkyMap('CAR', 'GAL', 340.0, 0.0, -0.1, 0.1, 950, 100)

    # Loop over observations
    for obs in obsdef:

        # Set sky region
        centre   = gammalib.GSkyDir()
        centre.lb_deg(obs['lon'], obs['lat'])
        circle   = gammalib.GSkyRegionCircle(centre, radius)
        region   = gammalib.GSkyRegionMap(circle)
        exposure = region.map().copy()
        exposure *= obs['duration']/3600.0

        # Add sky region
        map += exposure

    # Return map
    return map
Beispiel #4
0
    def _reflected_regions(self, obs):
        """
        Calculate list of reflected regions for a single observation (pointing)

        Parameters
        ----------
        obs : `~gammalib.GCTAObservation()`
            CTA observation

        Returns
        -------
        regions : `~gammalib.GSkyRegions`
            List of reflected regions
        """
        # Initialise list of reflected regions
        regions = gammalib.GSkyRegions()

        # Get offset angle of source
        pnt_dir = obs.pointing().dir()
        offset = pnt_dir.dist_deg(self._src_dir)

        # Skip observation if it is too close to source
        if offset <= self._rad:
            msg = ' Skip because observation is pointed at %.3f deg <= '\
                  '"rad=%.3f" from source.' \
                  % (offset, self._rad)
            self._log_string(gammalib.NORMAL, msg)

        # Skip observation if it is pointed too far from the source
        elif offset >= self['maxoffset'].real():
            msg = ' Skip because observation is pointed at %.3f deg >= '\
                  '"maxoffset=%.3f" from source.' \
                  % (offset, self['maxoffset'].real())
            self._log_string(gammalib.NORMAL, msg)

        # ... otherwise
        else:
            posang = pnt_dir.posang_deg(self._src_dir)
            if self._srcshape == 'CIRCLE':

                # Determine number of background regions to skip
                N_skip = self['bkgregskip'].integer()
                N_start = 1 + N_skip
                N_lim = 1 + 2 * N_skip

                # Compute the angular separation of reflected regions wrt
                # camera center. The factor 1.05 ensures background regions
                # do not overlap due to numerical precision issues
                alpha = 1.05 * 2.0 * self._rad / offset

                # Compute number of reflected regions by dividing the angular
                # separation by 2 pi.
                N = int(2.0 * math.pi / alpha)

                # If there are not enough reflected regions then skip the
                # observation ...
                if N < self['bkgregmin'].integer() + N_lim:
                    msg = ' Skip because the number %d of reflected regions '\
                          'for background estimation is smaller than '\
                          '"bkgregmin"=%d.' % (N-N_lim, self['bkgregmin'].integer())
                    self._log_string(gammalib.NORMAL, msg)

                # ... otherwise loop over position angle to create reflected
                # regions
                else:

                    # Log appending of reflected regions
                    msg = ' Use %d reflected regions.' % (N - N_lim)
                    self._log_string(gammalib.NORMAL, msg)

                    # Append reflected regions
                    alpha = 360.0 / N
                    for s in range(N_start, N - N_skip):
                        dphi = s * alpha
                        ctr_dir = pnt_dir.clone()
                        ctr_dir.rotate_deg(posang + dphi, offset)
                        region = gammalib.GSkyRegionCircle(ctr_dir, self._rad)
                        if self._has_exclusion:
                            if self._excl_reg.overlaps(region):
                                msg = ' Reflected region overlaps with '\
                                      'exclusion region.'
                                self._log_string(gammalib.EXPLICIT, msg)
                            else:
                                regions.append(region)
                        else:
                            regions.append(region)

        # Return reflected regions
        return regions
Beispiel #5
0
    #   Extracting free parameters
    freepars = [ par.name() for par in models[ args.gname ].spectral() \
        if par.is_free() ]

    #   Set the GSkydir for pointing direction and source position
    pdir = gammalib.GSkyDir()
    rdir = gammalib.GSkyDir()
    pdir.radec_deg(args.pntra, args.pntdec)
    rdir.radec_deg(args.ROIra, args.ROIdec)

    #   Compute angular distance between directions
    dirs_sep = pdir.dist_deg(rdir)

    #   Creating two GSkyRegionCircle regions to check that
    #   Region of simulation contains ROI region
    pntregion = gammalib.GSkyRegionCircle(pdir, args.pntradius)
    roiregion = gammalib.GSkyRegionCircle(rdir, args.ROIradius)

    #   Check if pointing region contains ROI region
    is_inside = pntregion.contains(roiregion)

    if is_inside:

        print(("\n\nPonting region with:\n" +
               "\tRA     : {:.3f} deg\n".format(args.pntra) +
               "\tDec    : {:.3f} deg\n".format(args.pntdec) +
               "\tRadius : {:.2f} deg\n\n".format(args.pntradius) +
               "contains ROI region.\n\nROI region:\n" +
               "\tRA     : {:.3f} deg\n".format(args.ROIra) +
               "\tDec    : {:.3f} deg\n".format(args.ROIdec) +
               "\tRadius : {:.2f} deg".format(args.ROIradius) +
Beispiel #6
0
    def _select_model(self, model, obs):
        """
        Select model

        Parameters
        ----------
        model : `~gammalib.GModel`
            Model
        obs : `~gammalib.GObservations`
            Observation container

        Returns
        -------
        select : bool
            Model selection flag
        """
        # Get selection parameters
        roilimit  = self['roilimit'].real()
        roimargin = self['roimargin'].real()
        ethres    = self['ethres'].real()
        fluxlimit = self['fluxlimit'].real()
        tslimit   = self['tslimit'].real()

        # Initialise selection flag to True
        select = True
        msg    = 'Select by default'

        # If the model has a spatial component then check of overlap
        if hasattr(model, 'spatial'):

            # Determine the model bounding box
            model_bounds = model.spatial().region()

            # Initialise with an unselect model
            select = False
            msg    = 'Exclude since outside any RoI'

            # Loop over all observations and check whether the model falls
            # into one of them
            for o in obs:

                # Get RoI centre and radius. The RoI radius is limited by
                # roilimit. A margin given by roimargin is added to the RoI
                # radius.
                #obs_centre = o.roi().centre().dir() # Segmentation fault
                #obs_radius = o.roi().radius()       # Segmentation fault
                obs_roi    = o.roi()
                obs_centre = obs_roi.centre().dir()
                obs_radius = obs_roi.radius()
                if obs_radius > roilimit:
                    obs_radius = roilimit
                obs_radius += roimargin

                # Set circular sky region
                obs_bounds = gammalib.GSkyRegionCircle(obs_centre, obs_radius)

                # If model overlaps with RoI then signal overlap
                if obs_bounds.overlaps(model_bounds):
                    select = True
                    msg    = 'Select due to overlap with at least one RoI'
                    break

        # If model is selected and if model has a TS value then apply TS
        # selection
        if select and model.has_ts():
            if model.ts() < tslimit:
                select = False
                msg    = 'Exclude since below TS limit (TS=%.3f)' % model.ts()

        # If model is selected and if model is a sky model then apply flux
        # limit selection
        if select and model.classname() == 'GModelSky':
            emin = gammalib.GEnergy(ethres,   'TeV')
            emax = gammalib.GEnergy(1000.0, 'TeV')
            flux = model.spectral().flux(emin, emax)
            if flux < fluxlimit:
                select = False
                msg    = 'Exclude since below flux limit (Flux=%.3e ph/cm2/s)' % flux

        # Log model selection
        self._log_value(gammalib.NORMAL, model.name(), msg)

        # Return selection flag
        return select