def __init__(self, *argv): """ Constructor. """ # Set name self._name = 'cstsmapmerge' self._version = '1.1.0' # Initialise class members self._files = None self._in_filename = '' self._tsmap = gammalib.GSkyMap() # Empty sky map self._statusmap = gammalib.GSkyMap() # Empty sky map self._maps = [] self._mapnames = [] self._merged_files = [] self._overwrite = True self._delete = False # Initialise application by calling the appropriate class # constructor. self._init_cscript(argv) # Return return
def residual_spatial(cntcube, modcube): """ Determine spatial residuals Parameters ---------- cntcube : str Counts cube name modcube : str Model cube name Returns ------- map, error : `~gammalib.GSkyMap()` Residual and error sky maps """ # Load counts and model cubes cnt = gammalib.GSkyMap(cntcube) mod = gammalib.GSkyMap(modcube) # Generate residual map map = cnt - mod map.stack_maps() # Generate residual error bars error = mod.copy() error.stack_maps() error = error.sqrt() # Return residual map and error map return map, error
def _map_moments(self, skymap, radius): """ Determine moments of sky map pixels Parameters ---------- skymap : `~gammalib.GSkyMap()` Sky map radius : float radius (deg) for pixel consideration Returns ------- mean, std : tuple of GSkyMap Mean and standard deviation of pixel values within a given radius """ # Copy the input skymap mean = gammalib.GSkyMap(skymap) std = gammalib.GSkyMap(skymap) std *= std # Convolve by disk to get bin-by-bin mean mean.smooth('DISK', radius) std.smooth('DISK', radius) # Compute the standard deviation for each pixel std = std - (mean * mean) std = std.sqrt() # Return mean and standard deviation return mean, std
def create_region_maps(rad_on=0.6, rad_off=[0.8, 1.0]): """ Create region maps Parameters ---------- rad_on : float, optional On region radius (deg) rad_off : list of float, optional Off region minimum and maximum radius (deg) """ # Set centre centre = gammalib.GSkyDir() centre.radec_deg(258.1125, -39.6867) # Create sky maps srcreg = gammalib.GSkyMap('TAN', 'CEL', 258.1125, -39.6867, 0.01, 0.01, 300, 300) bkgreg = gammalib.GSkyMap('TAN', 'CEL', 258.1125, -39.6867, 0.01, 0.01, 300, 300) # Fill sky map for i in range(srcreg.npix()): rad = centre.dist_deg(srcreg.inx2dir(i)) if rad <= rad_on: srcreg[i] = 1 if rad > rad_off[0] and rad < rad_off[1]: bkgreg[i] = 1 # Save maps srcreg.save('rx_srcreg_map.fits', True) bkgreg.save('rx_bkgreg_map.fits', True) # 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 show_yearly_exposures(): """ Show exposure per year """ # Create figure fig = plt.figure('Exposure', (12, 7)) fig.subplots_adjust(left=0.05, right=1.0, top=0.94, bottom=0.05) # Set map index and energy imap = 1 title = 'Yearly exposures at 1 TeV' # Add title fig.suptitle(title, fontsize=16) # Loop over years for index, year in enumerate(range(2021,2031)): # Build file name and title filename = 'gps_expcube_%4.4d-%4.4d.fits' % (year, year) # Load exposure exposure = gammalib.GSkyMap(filename) # Plot ax = fig.add_subplot(10,1,index+1) plot_exposure(exposure, ax, imap, labeled=False) ax.text(-175.0,5.0,'%4.4d' % year, color='w', horizontalalignment='right', verticalalignment='center') # Show figure plt.show() # Return return
def __init__(self, *argv): """ Constructor """ # Set name and version self._name = 'cstsmapsplit' self._version = '1.1.0' # Set data members self._outmap = gammalib.GFilename() self._bins_per_job = 0 self._compute_null = False self._outfile = gammalib.GFilename() self._map = gammalib.GSkyMap() self._cmd = [] self._srcname = '' # Initialise observation container from constructor arguments. self._obs, argv = self._set_input_obs(argv) # Initialise application by calling the appropriate class # constructor. self._init_cscript(argv) # Return return
def show_exposure_period(start, stop): """ Show exposures for period Parameters ---------- start : integer Start year stop : integer Steop year """ # Create figure fig = plt.figure('Exposure', (12, 7)) fig.subplots_adjust(left=0.07, right=1.05, top=0.98, bottom=0.05) # Build file name and title filename = 'gps_expcube_%4.4d-%4.4d.fits' % (start, stop) if start == stop: title = 'Exposure for year %4.4d' % (start) elif start == 2021 and stop == 2022: title = 'Exposure for STP (%4.4d-%4.4d)' % (start, stop) elif start == 2023 and stop == 2030: title = 'Exposure for LTP (%4.4d-%4.4d)' % (start, stop) else: title = 'Exposure for years %4.4d-%4.4d' % (start, stop) # Add title fig.suptitle(title, fontsize=16) # Load exposure exposure = gammalib.GSkyMap(filename) # Plot ax1 = fig.add_subplot(411) plot_exposure(exposure, ax1, 0) # 100 GeV ax1.text(-175.0,5.0,'100 GeV', color='w', horizontalalignment='right', verticalalignment='center') # ax2 = fig.add_subplot(412) plot_exposure(exposure, ax2, 1) # 1 TeV ax2.text(-175.0,5.0,'1 TeV', color='w', horizontalalignment='right', verticalalignment='center') # ax3 = fig.add_subplot(413) plot_exposure(exposure, ax3, 2) # 10 TeV ax3.text(-175.0,5.0,'10 TeV', color='w', horizontalalignment='right', verticalalignment='center') # ax4 = fig.add_subplot(414) plot_exposure(exposure, ax4, 3) # 100 TeV ax4.text(-175.0,5.0,'100 TeV', color='w', horizontalalignment='right', verticalalignment='center') # Show figure plt.show() # Return return
def __init__(self, *argv): """ Constructor. """ # Initialise application by calling the base class constructor self._init_cscript(self.__class__.__name__, ctools.__version__, argv) # Initialise class members self._files = None self._in_filename = '' self._tsmap = gammalib.GSkyMap() # Empty sky map self._statusmap = gammalib.GSkyMap() # Empty sky map self._maps = [] self._mapnames = [] self._merged_files = [] self._overwrite = True self._delete = False # Return return
def read_regions(fpath, init_map): """ Read a regions WCS FITS or ds9 file and return a mask WCS map. Parameters ---------- fpath : str Path to regions file init_map : `~gammalib.GSkyMap` Sky map representing fov of interest. Used for initialisation of regions map. Returns ------- map : `~gammalib.GSkyMap` Sky map. """ # Create starter map for user fov filled with zeros regions_map = init_map.copy() regions_map *= 0.0 # Take care about ds9 region files if fpath.lower().endswith('.reg'): # Read ds9 regions ds9_regions = gammalib.GSkyRegions(fpath) # Loop over regions for reg in ds9_regions: # Make map from region ds9_map = gammalib.GSkyRegionMap(reg) # Add ds9 region map to global map regions_map += ds9_map.map() # Take care about fits WCS files elif gammalib.GFilename(fpath).is_fits(): # Read wcs regions map wcs_regions = gammalib.GSkyMap(fpath) # Add wcs regions map to global map regions_map += wcs_regions else: raise RuntimeError('Invalid regions file detected. Please provide ' + 'a valid ds9 or FITS WCS regions file.') # Return return regions_map
def generate_map(): """ Generate MSH 15-52 map """ # Define files inmodel = 'msh_results_egauss_plaw_lookup_grad_hess_edisp.xml' logfile = 'msh_skymap.log' outfile = 'msh_skymap.fits' modfile = 'msh_skymap.xml' # Continue only if map or result does not yet exist if not os.path.isfile(outfile) and os.path.isfile(inmodel): # Read input model models = gammalib.GModels(inmodel) # Remove MSH 15-52 component models.remove('MSH 15-52') # Save input model models.save(modfile) # Generate residual map resmap = cscripts.csresmap() resmap['inobs'] = 'obs_msh_selected.xml' resmap['inmodel'] = modfile resmap['outmap'] = outfile resmap['emin'] = 0.381 resmap['emax'] = 40.0 resmap['enumbins'] = 40 resmap['nxpix'] = 200 resmap['nypix'] = 200 resmap['binsz'] = 0.005 resmap['coordsys'] = 'CEL' resmap['proj'] = 'TAN' resmap['xref'] = 228.55 resmap['yref'] = -59.17 resmap['algorithm'] = 'SUB' resmap['logfile'] = logfile resmap['chatter'] = 4 resmap.execute() # Load map if it exists if os.path.isfile(outfile): map = gammalib.GSkyMap(outfile) else: map = None # Return map return map
def _check_result_file(self, filename, nx=50, ny=50): """ Check result file """ # Load residual map residual = gammalib.GSkyMap(filename) # Check residual map self.test_value(residual.nmaps(), 1, 'One map') self.test_value(residual.nx(), nx, '%d pixels in X' % nx) self.test_value(residual.ny(), ny, '%d pixels in Y' % ny) # Return return
def _check_result_file(self, filename): """ Check result file """ # Open result file result = gammalib.GSkyMap(filename) # Check dimensions self.test_value(result.nmaps(), 1, 'Check for one map') self.test_value(result.nx(), 200, 'Check for 200 pixels in X') self.test_value(result.ny(), 200, 'Check for 200 pixels in Y') # Return return
def _init_ts_map(self, fitsfile): """ Initialise Test Statistic map. """ # Set filename self._in_filename = fitsfile # Open FITS file fits = gammalib.GFits(fitsfile) # Read TS and status maps self._tsmap = gammalib.GSkyMap() self._tsmap.read(fits[0]) self._statusmap = gammalib.GSkyMap() self._statusmap.read(fits["STATUS MAP"]) # Get other maps self._maps = [] self._mapnames = [] # Loop over extensions for hdu in fits: # Leave out primary and status extension if hdu.extname() != "IMAGE" and hdu.extname() != "STATUS MAP": # Add present maps skymap = gammalib.GSkyMap() skymap.read(hdu) self._maps.append(skymap) self._mapnames.append(hdu.extname()) # Close FITS file fits.close() # Return return
def cntmap(obs, proj="TAN", coord="GAL", xval=0.0, yval=0.0, \ binsz=0.05, nxpix=200, nypix=200, \ outname="cntmap.fits"): """ Creates a counts map by combining the events of all observations. The counts map will be a summed map over all energies. Parameters: obs - Observation container Keywords: proj - Projection type (e.g. TAN, CAR, STG, ...) (default: TAN) coord - Coordinate type (GAL, CEL) (default: GAL) xval - Reference longitude value [deg] (default: 0.0) yval - Reference latitude value [deg] (default: 0.0) binsz - Pixel size [deg/pixel] (default: 0.05) nxpix - Number of pixels in X direction (default: 200) nypix - Number of pixels in Y direction (default: 200) outname - Counts map FITS filename (default: cntmap.fits) """ # Allocate counts map map = gammalib.GSkyMap(proj, coord, xval, yval, -binsz, binsz, nxpix, nypix, 1) # Set maximum pixel number maxpixel = nxpix * nypix # Fill all observations for run in obs: # Loop over all events for event in run.events(): # Determine sky pixel skydir = event.dir().dir() pixel = map.dir2inx(skydir) # Set pixel if pixel < maxpixel: map[pixel] += event.counts() # Save sky map. The clobber flag is set to True, so any existing FITS # file will be overwritten. map.save(outname, True) # Return counts map return map
def __init__(self, *argv): """ Constructor """ # Initialise application by calling the appropriate class constructor self._init_cslikelihood(self.__class__.__name__, ctools.__version__, argv) # Set data members self._outmap = gammalib.GFilename() self._bins_per_job = 0 self._compute_null = False self._outfile = gammalib.GFilename() self._map = gammalib.GSkyMap() self._cmd = [] self._srcname = '' # Return return
def plot_all(cntcube, modcube, smooth=0.02): """ Plot residuals Parameters ---------- cntcube : str Counts cube name modcube : str Model cube name smooth : float, optional Smoothing width (deg) """ # Get map try: resmap, _ = residual_spatial(cntcube, modcube) except: resmap = gammalib.GSkyMap(modcube) resmap.stack_maps() # Create figure fig = plt.figure('Map', (7, 7)) fig.subplots_adjust(left=0.16, right=0.95, top=0.95, bottom=0.10) ax = plt.subplot() # Plot map plot_map(resmap, ax, smooth=smooth) # Plot circles #plot_circle(258.1125, -39.6867, 0.6, color='w', fmt='-', linewidth=1) #plot_circle(258.1125, -39.6867, 0.8, color='w', fmt='--', linewidth=1) #plot_circle(258.1125, -39.6867, 1.0, color='w', fmt='--', linewidth=1) # Show map plt.show() # Save figure filename = os.path.splitext(modcube)[0] + '.png' fig.savefig(filename, dpi=300) # Return return
def _check_result_file(self, filename, nx=20, ny=20): """ Check result file Parameters ---------- filename : str Sky map file name nx : int, optional Number of X pixels ny : int, optional Number of Y pixels """ # Open result file skymap = gammalib.GSkyMap(filename) # Check sky map self._check_map(skymap, nx=nx, ny=ny) # Return return
def _get_number_of_ts_pixels(self, fitsfile): """ Return number of pixels with TS values. Args: fitsfile: FITS file to be merged. Returns: Number of pixels for which TS has been computed. """ # Get status map for this file status = gammalib.GSkyMap(fitsfile + "[STATUS MAP]") # Count number of pixels with TS status set count = 0 for pix in status: if pix > 0.5: count += 1 # Return number of pixels return count
def __init__(self, *argv): """ Constructor """ # Initialise sky map from constructor arguments if len(argv) > 0 and isinstance(argv[0], gammalib.GSkyMap): self._map = argv[0] argv = argv[1:] else: self._map = gammalib.GSkyMap() # Initialise application by calling the base class constructor self._init_cscript(self.__class__.__name__, ctools.__version__, argv) # Set protected members self._models = gammalib.GModels() # Initialise other members self._map_dirs = [] # Return return
def plot_all(filename, smooth=0.02): """ Plot residuals Parameters ---------- filename : str Sky map file name smooth : float, optional Map smoothing parameter (deg) """ # Load Crab sky map resmap = gammalib.GSkyMap(filename) resmap.stack_maps() # Create figure fig = plt.figure('Map', (10, 5)) fig.subplots_adjust(left=0.16, right=0.95, top=0.95, bottom=0.10) ax = plt.subplot() # Plot map plot_map(resmap, ax, smooth=smooth) # Plot circles plot_circles() # Plot pointings plot_pointings() # Show map plt.show() # Save figure filename = os.path.splitext(filename)[0] + '.png' fig.savefig(filename, dpi=300) # Return return
def _check_viscube(self, filename, nx=36, ny=18, nz=60): """ Check visibility cube Parameters ---------- filename : str Visibility cube file name nx : int, optional Number of X pixels ny : int, optional Number of Y pixels """ # Open result file viscube = gammalib.GSkyMap(filename) # Check dimensions self.test_value(viscube.nmaps(), nz, 'Check number of maps') self.test_value(viscube.nx(), nx, 'Check for number of X pixels') self.test_value(viscube.ny(), ny, 'Check for number of Y pixels') # Return return
def _load_skymap(self): """ Load sky map Returns ------- skymap : `~gammalib.GSkyMap()` Sky map """ # Get skymap filename inmap = self['inmap'].filename() # Open sky map file fits = gammalib.GFits(inmap) # Extract primary extension as sky map skymap = gammalib.GSkyMap(fits.image(0)) # Close sky map file fits.close() # Return return skymap.extract(0)
def __init__(self, *argv): """ Constructor Parameters ---------- argv : list of str List of IRAF command line parameter strings of the form ``parameter=3``. Raises ------ TypeError An invalid number of command line arguments was provided. """ # Initialise application by calling the base class constructor self._init_cscript(self.__class__.__name__, ctools.__version__, argv) # Initialise members self._cube = gammalib.GSkyMap() # Return return
def show_residuals(obslist=None, emin=0.2, emax=20.0, ebins=20, npix=200, binsz=0.02, suffix=''): """ Show residuals for all OFF observations Parameters ---------- obslist : list of ints, optional Index of observations to stack emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) ebins : int, optional Number of energy bins npix : int, optional Number of spatial pixels binsz : float, optional Spatial bin size suffix : str, optional Plot filename suffix """ # Set XML filename obsname = '$HESSDATA/obs/obs_off.xml' # Generate background lookup generate_background_lookup(obslist=obslist, suffix=suffix) # If observation list is specified and suffix is empty then build suffix if obslist != None and suffix == '': for obs in obslist: suffix += '_%2.2d' % obs # Set stacked cube filenames cntfile = 'off_stacked_counts%s.fits' % (suffix) modfile = 'off_stacked_model%s.fits' % (suffix) # If stacked cubes exist then load them if os.path.isfile(cntfile) and os.path.isfile(modfile): cntcube_stacked = gammalib.GCTAEventCube(cntfile) modcube_stacked = gammalib.GCTAEventCube(modfile) # ... otherwise generate them else: # Define counts and model cubes for stacking map = gammalib.GSkyMap('TAN', 'CEL', 0.0, 0.0, -binsz, binsz, npix, npix, ebins) ebds = gammalib.GEbounds(ebins, gammalib.GEnergy(emin, 'TeV'), gammalib.GEnergy(emax, 'TeV')) gti = gammalib.GGti(gammalib.GTime(0.0, 's'), gammalib.GTime(1.0, 's')) cntcube_stacked = gammalib.GCTAEventCube(map, ebds, gti) modcube_stacked = gammalib.GCTAEventCube(map, ebds, gti) # Load observations inobs = gammalib.GObservations(obsname) # Loop over runs in observations for i, run in enumerate(inobs): # If an observation list is defined then skip observation if it # is not in list if obslist != None: if i not in obslist: continue # Build observation container with single run obs = gammalib.GObservations() obs.append(run) # Select events obs = select_events(obs, emin=emin, emax=emax) # Generate background model models = get_bkg_model(obs, suffix=suffix) # Attach models to observation container obs.models(models) # Create counts cube cntcube = create_cntcube(obs, emin=emin, emax=emax, ebins=ebins, npix=npix, binsz=binsz) # Create model cube modcube = create_modcube(obs, cntcube) # Stack cubes cntcube_stacked = stack_cube(cntcube_stacked, cntcube) modcube_stacked = stack_cube(modcube_stacked, modcube) # Stop after first run #break # Save cubes cntcube_stacked.save(cntfile, True) modcube_stacked.save(modfile, True) # Plot stacked cubes plot(cntcube_stacked, modcube_stacked, suffix=suffix) plot_sectors(cntcube_stacked, modcube_stacked, suffix=suffix) plot_radial_profiles(cntcube_stacked, modcube_stacked, suffix=suffix) # Return return
def set_source_model(srcmodel, spec='plaw', alpha=1.0, mapname='../map_RXJ1713.fits'): """ Set source model Parameters ---------- srcmodel : str Source model name spec : str, optional Spectral model alpha : float, optional Map scaling factor mapname : str, optional Sky map name Returns ------- source : `~gammalib.GModelSky()` Source model """ # Set spectral component if spec == 'plaw': spectral = gammalib.GModelSpectralPlaw(1.0e-17, -2.0, gammalib.GEnergy(1.0, 'TeV')) spectral['Prefactor'].min(1.0e-25) elif spec == 'eplaw': spectral = gammalib.GModelSpectralExpPlaw( 1.0e-17, -2.0, gammalib.GEnergy(1.0, 'TeV'), gammalib.GEnergy(10.0, 'TeV')) spectral['CutoffEnergy'].min(1.0e6) spectral['CutoffEnergy'].max(1.0e8) spectral['Prefactor'].min(1.0e-25) elif spec == 'inveplaw': spectral = gammalib.GModelSpectralExpInvPlaw( 1.0e-17, -2.0, gammalib.GEnergy(1.0, 'TeV'), gammalib.GEnergy(10.0, 'TeV')) spectral['Prefactor'].min(1.0e-25) elif spec == 'logparabola': spectral = gammalib.GModelSpectralLogParabola( 1.0e-17, -2.0, gammalib.GEnergy(1.0, 'TeV'), -0.3) spectral['Prefactor'].min(1.0e-25) elif spec == 'abdalla2018': spectral = gammalib.GModelSpectralExpPlaw( 2.3e-17, -2.06, gammalib.GEnergy(1.0, 'TeV'), gammalib.GEnergy(12.9, 'TeV')) spectral['Prefactor'].fix() spectral['Index'].fix() spectral['CutoffEnergy'].fix() elif spec == 'abdalla2018Ec': spectral = gammalib.GModelSpectralExpPlaw( 2.3e-17, -2.06, gammalib.GEnergy(1.0, 'TeV'), gammalib.GEnergy(12.9, 'TeV')) spectral['CutoffEnergy'].fix() spectral['Prefactor'].min(1.0e-25) elif spec == 'aharonian2007': spectral = gammalib.GModelSpectralLogParabola( 2.06e-17, -2.02, gammalib.GEnergy(1.0, 'TeV'), -0.29) spectral['Prefactor'].fix() spectral['Index'].fix() spectral['Curvature'].fix() # Set spatial component if 'map' in srcmodel: filename = '%s' % mapname map = gammalib.GSkyMap(filename) map = scale_map(map, alpha) filename = 'map_RXJ1713_%.2f.fits' % alpha map.save(filename, True) spatial = gammalib.GModelSpatialDiffuseMap(filename) elif 'disk' in srcmodel: dir = gammalib.GSkyDir() dir.radec_deg(258.3, -39.7) spatial = gammalib.GModelSpatialRadialDisk(dir, 0.5) spatial['RA'].free() spatial['DEC'].free() elif 'gauss' in srcmodel: dir = gammalib.GSkyDir() dir.radec_deg(258.3, -39.7) spatial = gammalib.GModelSpatialRadialGauss(dir, 0.5) spatial['RA'].free() spatial['DEC'].free() elif 'shell' in srcmodel: dir = gammalib.GSkyDir() dir.radec_deg(258.3, -39.7) spatial = gammalib.GModelSpatialRadialShell(dir, 0.4, 0.2) spatial['RA'].free() spatial['DEC'].free() # Set source model source = gammalib.GModelSky(spatial, spectral) source.name('RX J1713.7-3946') source.tscalc(True) # Return source model return source
def plot_significance_distribution(mappath, nbins, sigma_min, sigma_max, includedreg, excludedreg, title, plotfile): """ Plot the significance distribution and return instance of pyplot figure and axis. Parameters ---------- mappath : str Path to significance map nbins : int Number of bins in histogram sigma_min : float Lower limit of the x axis in the plot sigma_max : float Upper limit of the x axis in the plot includedreg : str Path to global included region file excludedreg : str Path to global excluded region file title : str Title of the plot plotfile : str Name of file for plotting """ # Read significance map significance_map = gammalib.GSkyMap(mappath + '[SIGNIFICANCE]') # Read included regions inclusion_available = False if len(includedreg) > 0: regions_map = read_regions(includedreg, init_map=significance_map) mask_include = skymap_to_numpy_ndarray(regions_map).astype(bool) inclusion_available = True # Read excluded regions src_exclusion_available = False if len(excludedreg) > 0: regions_map = read_regions(excludedreg, init_map=significance_map) mask_exclude = skymap_to_numpy_ndarray(regions_map).astype(bool) src_exclusion_available = True # Convert significance map to flat array data = skymap_to_numpy_ndarray(significance_map) # Initialise dummy mask allowing all pixels mask = np.ones(significance_map.npix()).astype(bool) # Apply inclusion region spatial cuts if inclusion_available: mask &= mask_include data = data[mask] # Apply exclusion region spatial cuts if src_exclusion_available: data_without_sources = skymap_to_numpy_ndarray(significance_map) mask &= ~mask_exclude data_without_sources = data_without_sources[mask] # Compute bin edges, hence use nbins+1 bin_edges = linspace(sigma_min, sigma_max, nbins + 1) # Create figure fig = plt.figure() ax = fig.gca() # Draw significance histogram for full FOV y, _, _ = ax.hist(data, bins=bin_edges, histtype='step', color='k', label='significance') # Draw the default normal distribution. Scale to fit maximum of histogram yvals = [ y.max() * math.exp(-0.5 * (x - 0.0)**2 / (1.0**2)) for x in bin_edges ] ax.plot(bin_edges, yvals, 'b-') msg = 'mean: $0$\nwidth: $1$' ax.text(0.98, 0.80, msg, ha='right', va='top', bbox=dict(edgecolor='blue', facecolor='white'), transform=ax.transAxes) # If exclusion was provided then also plot significances with excluded # source data if src_exclusion_available: # Draw histogram of significances for data with excluded sources y, _, _ = ax.hist(data_without_sources, bins=bin_edges, histtype='step', color='k', alpha=0.5, label='significance without exclusions') # Set initial Gaussian parameters y_max = float(y.max()) par1 = gammalib.GOptimizerPar('Norm', y_max) par2 = gammalib.GOptimizerPar('Mean', 0.0) par3 = gammalib.GOptimizerPar('Sigma', 1.0) pars = gammalib.GOptimizerPars() pars.append(par1) pars.append(par2) pars.append(par3) # Set fit function x = [0.5 * (bin_edges[i] + bin_edges[i + 1]) for i in range(nbins)] fct = gaussian(x, y) # Optimize function and compute errors opt = gammalib.GOptimizerLM() opt.optimize(fct, pars) opt.errors(fct, pars) # Recover parameters and errors norm = pars[0].value() e_norm = pars[0].error() mean = pars[1].value() e_mean = pars[1].error() sigma = pars[2].value() e_sigma = pars[2].error() # Log fit result print( 'Fit of normal distribution to excluded source significance data ' + 'results in: norm=%f+=%f xmean=%f+-%f sigma=%f+-%f' % (norm, e_norm, mean, e_mean, sigma, e_sigma)) # Draw text box msg = 'mean: $%.3f\pm%.3f$\nwidth: $%.3f\pm%.3f$' % \ (mean, e_mean, sigma, e_sigma) ax.text(0.98, 0.95, msg, ha='right', va='top', bbox=dict(edgecolor='red', facecolor='white'), transform=ax.transAxes) # Plot the normal yvals = [ norm * math.exp(-0.5 * (x - mean)**2 / (sigma**2)) for x in bin_edges ] ax.plot(bin_edges, yvals, 'r-') # Configure the plot ax.set_ylim(0.5, ax.get_ylim()[1] * 2.0) ax.set_xlim(sigma_min, sigma_max) ax.set_title(title) ax.set_xlabel('Significance') ax.set_ylabel('Entries') ax.grid() ax.set_yscale('log') # Show or save the plot if len(plotfile) > 0: plt.savefig(plotfile) else: plt.show() # Return return
def _zenith_angle_map(self, nx, ny, dx, dy): """ Compute zenith angle map Parameters ---------- nx : int Number of Right Ascension pixels. ny : int Number of Declination pixels. dx : float Right Ascension pixel size in degrees. dy : float Declination pixel size in degrees. Returns ------- zmap : `~gammalib.GSkyMap` Allsky map comprising the zenith angle for an hour angle of 0. The zenith angle of a position (ra,dec) depends on the declination and the hour angle h and is given by zenith(h,dec) = arccos( sin(lat) * sin(dec) + cos(lat) * cos(dec) * cos(h) ) The hour angle h (or local hour angle, LHA) is defined as the difference between local siderial time (LST) and the Right Ascension h = LST - ra The map is computed for h=-ra which is equivalent to GST=lon (or LST=0). In other words, the map corresponds to the time when ra=0 passes through the local meridian. """ # Initialise zenith angle map zmap = gammalib.GSkyMap('CAR','CEL',0.0,0.0,-dx,dy,nx,ny) # Set hour angle and declination vectors hours = [(float(i)+0.5)*dx for i in range(nx)] decs = [(float(i)+0.5)*dy-90.0 for i in range(ny)] # Get array geographic latitude geolat = self['geolat'].real() # Precompute latitude terms cos_lat = math.cos(geolat*gammalib.deg2rad) sin_lat = math.sin(geolat*gammalib.deg2rad) # Loop over all declinations and hour angles and compute the zenith # angle. Store the zenith angle in the map index = 0 for dec in decs: cos_dec = math.cos(dec*gammalib.deg2rad) sin_dec = math.sin(dec*gammalib.deg2rad) for h in hours: cos_h = math.cos(h*gammalib.deg2rad) zenith = math.acos(sin_lat*sin_dec + cos_lat*cos_dec*cos_h)*gammalib.rad2deg zmap[index] = zenith index += 1 # Log zenith angle map self._log_header2(gammalib.EXPLICIT, 'Zenith angle map') self._log_string(gammalib.EXPLICIT, str(zmap)) # Return zenith angle map return zmap
def _visibility_cube(self): """ Compute visibility cube Compute visibility cube by displacing the zenith angle map for all hour angles. The visibility cube contains the number of hours a given celestial position is visible under a given zenith angle interval. Summing over all zenith angle intervals specifies for how long a given celestial position will be visible. """ # Write header self._log_header1(gammalib.TERSE, 'Compute visibility cube') # Set visibility cube and zenith angle map dimensions and bin size binsz = self['binsz'].real() nx = int(360.0/binsz+0.5) ny = int(180.0/binsz+0.5) dx = 360.0/float(nx) dy = 180.0/float(ny) # Set zenith angle dimension and bin size dz = self['dz'].real() zmax = self['zmax'].real() nz = int(zmax/dz+0.5) dz = zmax/float(nz) # Log dimensions self._log_header2(gammalib.NORMAL, 'Visibility cube dimensions') self._log_value(gammalib.NORMAL, 'Number of RA bins', nx) self._log_value(gammalib.NORMAL, 'Number of Dec bins', ny) self._log_value(gammalib.NORMAL, 'Number of zenith angles', nz) self._log_value(gammalib.NORMAL, 'RA pixel size', str(dx)+' deg') self._log_value(gammalib.NORMAL, 'Dec pixel size', str(dy)+' deg') self._log_value(gammalib.NORMAL, 'Zenith angle bin size', str(dz)+' deg') self._log_value(gammalib.NORMAL, 'Maximum zenith angle', str(zmax)+' deg') # Compute zenith angle map zmap = self._zenith_angle_map(nx,ny,dx,dy) # Setup hour angle weights. They specify for how many hours a given # hour angle is observed during the covered time period. hour_angles = self._hour_angle_weight() # Initialise visibility cube self._cube = gammalib.GSkyMap('CAR','CEL',0.0,0.0,-dx,dy,nx,ny,nz) # Loop over all hour angle weights for hour_angle in hour_angles: # Compute temporal shift in degrees shift = hour_angle['angle'] # Initialise shifted zenith angle map zmap_shift = gammalib.GSkyMap('CAR','CEL',shift,0.0,-dx,dy,nx,ny) # Merge zenith angle map into shifted map zmap_shift += zmap # Loop over all pixels of the shifted map and add the hours during # which the shifted map occurs to the relevant zenith angle bin for i, zenith in enumerate(zmap_shift): iz = int(zenith/dz) if iz < nz: self._cube[i,iz] += hour_angle['hours'] # Return return
def plot_all(crabmap, smooth=0.0): """ Plot residuals Parameters ---------- crabmap : str Crab map file name smooth : float, optional Smoothing width (deg) """ # Set parameters size = 1000 # Load Crab map chandra = gammalib.GSkyMap(crabmap) # Create a slighly larger map crab = gammalib.GSkyMap('TAN', 'CEL', 83.63, 22.015, -6.833e-05, 6.833e-05, size, size) crab += chandra # Create figure fig = plt.figure('Map', (7, 7)) fig.subplots_adjust(left=0.16, right=0.95, top=0.95, bottom=0.10) ax = plt.subplot() # Plot map plot_map(crab, ax, smooth=smooth) # Plot Holler et al. 2017 circle plot_circle(ax, 83.62875, 22.012361, 0.0145, e_ra=0.00033, e_dec=0.0003055, color='white', linewidth=4) plot_circle(ax, 83.62875, 22.012361, 0.0145, e_ra=0.00033, e_dec=0.0003055, color='deepskyblue') ax.text(-0.005, -0.02, 'Holler et al. (2017)', fontsize=14, fontweight='bold', color='deepskyblue') # Plot ctools circle # RA .......................: 83.6206711191164 +/- 0.00293905226757571 deg # DEC ......................: 22.0249161487514 +/- 0.00271599100158073 deg # Sigma ....................: 0.0131191472448878 +/- 0.00513796531189789 deg plot_circle(ax, 83.620671, 22.024916, 0.013119, e_ra=0.002939, e_dec=0.002716, color='white', linewidth=4) plot_circle(ax, 83.620671, 22.024916, 0.013119, e_ra=0.002939, e_dec=0.002716, color='red') ax.text(-0.023, 0.021, 'ctools', fontsize=14, fontweight='bold', color='salmon') # Plot systematic uncertainty plot_circle(ax, 83.63 + 0.028, 22.015 + 0.025, 0.005555, color='white') ax.text(0.023, 0.029, 'systematic uncertainty', fontsize=12, color='white') # Save figure plt.show() fig.savefig('crab_extension.png', dpi=300) # Return return