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
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
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
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
# 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) +
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