def create_from_fitsfile(cls, fitsfile): """ Read a fits file and use it to make a mapping """ from fermipy.skymap import Map index_map = Map.create_from_fits(fitsfile) mult_map = Map.create_from_fits(fitsfile, hdu=1) ff = fits.open(fitsfile) hpx = HPX.create_from_hdu(ff[0]) mapping_data = dict(ipixs=index_map.counts, mult_val=mult_map.counts, npix=mult_map.counts.shape) return cls(hpx, index_map.wcs, mapping_data)
def _scan_position(self, name, **kwargs): saved_state = LikelihoodState(self.like) skydir = kwargs.pop('skydir', self.roi[name].skydir) scan_cdelt = kwargs.pop('scan_cdelt', 0.02) nstep = kwargs.pop('nstep', 5) use_cache = kwargs.get('use_cache', True) use_pylike = kwargs.get('use_pylike', False) optimizer = kwargs.get('optimizer', {}) # Fit without source self.zero_source(name, loglevel=logging.DEBUG) fit_output_nosrc = self._fit(loglevel=logging.DEBUG, **optimizer) self.unzero_source(name, loglevel=logging.DEBUG) saved_state.restore() self.free_norm(name, loglevel=logging.DEBUG) lnlmap = Map.create(skydir, scan_cdelt, (nstep, nstep), coordsys=wcs_utils.get_coordsys(self._skywcs)) src = self.roi.copy_source(name) if use_cache and not use_pylike: self._create_srcmap_cache(src.name, src) scan_skydir = lnlmap.get_pixel_skydirs().transform_to('icrs') loglike = [] for ra, dec in zip(scan_skydir.ra.deg, scan_skydir.dec.deg): spatial_pars = {'ra': ra, 'dec': dec} self.set_source_morphology(name, spatial_pars=spatial_pars, use_pylike=use_pylike) fit_output = self._fit(loglevel=logging.DEBUG, **optimizer) loglike += [fit_output['loglike']] self.set_source_morphology(name, spatial_pars=src.spatial_pars, use_pylike=use_pylike) saved_state.restore() lnlmap.data = np.array(loglike).reshape((nstep, nstep)).T lnlmap.data -= fit_output_nosrc['loglike'] tsmap = Map(2.0 * lnlmap.data, lnlmap.wcs) self._clear_srcmap_cache() return tsmap, fit_output_nosrc['loglike']
def test_calc_int_flux_sensitivity(): ltc = LTCube.create_from_obs_time(3.1536E8) c = SkyCoord(10.0, 10.0, unit='deg', frame='galactic') ebins = 10**np.linspace(2.0, 5.0, 8 * 3 + 1) gdiff = Map.create_from_fits(galdiff_path) iso = np.loadtxt( os.path.expandvars('$FERMI_DIFFUSE_DIR/iso_P8R3_SOURCE_V3_v1.txt'), unpack=True) scalc = SensitivityCalc(gdiff, iso, ltc, ebins, 'P8R3_SOURCE_V3', [['FRONT', 'BACK']]) fn = spectrum.PowerLaw([1E-13, -2.0], scale=1E3) o = scalc.int_flux_threshold(c, fn, 25.0, 3.0) assert_allclose(o['eflux'], 1.15296479181e-06, rtol=3E-3) assert_allclose(o['flux'], 1.66741840222e-09, rtol=3E-3) assert_allclose(o['npred'], 549.71066228, rtol=3E-3) assert_allclose(o['dnde'], 1.66908748971e-14, rtol=3E-3) assert_allclose(o['e2dnde'], 1.66908748971e-07, rtol=3E-3) assert_allclose(o['bins']['flux'], np.array([ 4.180875e-10, 3.135214e-10, 2.351078e-10, 1.763060e-10, 1.322108e-10, 9.914417e-11, 7.434764e-11, 5.575286e-11, 4.180876e-11, 3.135216e-11, 2.351078e-11, 1.763060e-11, 1.322108e-11, 9.914417e-12, 7.434764e-12, 5.575286e-12, 4.180875e-12, 3.135214e-12, 2.351078e-12, 1.763060e-12, 1.322108e-12, 9.914417e-13, 7.434764e-13, 5.575286e-13 ]), rtol=1E-3)
def test_calc_int_flux_sensitivity(): ltc = LTCube.create_from_obs_time(3.1536E8) c = SkyCoord(10.0, 10.0, unit='deg', frame='galactic') ebins = 10**np.linspace(2.0, 5.0, 8 * 3 + 1) gdiff = Map.create_from_fits(galdiff_path) iso = np.loadtxt( os.path.expandvars('$FERMIPY_ROOT/data/iso_P8R2_SOURCE_V6_v06.txt'), unpack=True) scalc = SensitivityCalc(gdiff, iso, ltc, ebins, 'P8R2_SOURCE_V6', [['FRONT', 'BACK']]) fn = spectrum.PowerLaw([1E-13, -2.0], scale=1E3) o = scalc.int_flux_threshold(c, fn, 25.0, 3.0) assert_allclose(o['eflux'], 1.0719847971553671e-06, rtol=3E-3) assert_allclose(o['flux'], 1.550305083355546e-09, rtol=3E-3) assert_allclose(o['npred'], 511.16725330021416, rtol=3E-3) assert_allclose(o['dnde'], 1.5518569402958423e-14, rtol=3E-3) assert_allclose(o['e2dnde'], 1.5518569402958427e-07, rtol=3E-3) assert_allclose( o['bins']['flux'], np.array([ 3.88128407e-10, 2.91055245e-10, 2.18260643e-10, 1.63672392e-10, 1.22736979e-10, 9.20397499e-11, 6.90200755e-11, 5.17577549e-11, 3.88128407e-11, 2.91055245e-11, 2.18260643e-11, 1.63672392e-11, 1.22736979e-11, 9.20397499e-12, 6.90200755e-12, 5.17577549e-12, 3.88128407e-12, 2.91055245e-12, 2.18260643e-12, 1.63672392e-12, 1.22736979e-12, 9.20397499e-13, 6.90200755e-13, 5.17577549e-13 ]), rtol=1E-3)
def test_calc_int_flux_sensitivity(): ltc = LTCube.create_from_obs_time(3.1536E8) c = SkyCoord(10.0, 10.0, unit='deg', frame='galactic') ebins = 10**np.linspace(2.0, 5.0, 8 * 3 + 1) gdiff = Map.create_from_fits(galdiff_path) iso = np.loadtxt(os.path.expandvars('$FERMIPY_ROOT/data/iso_P8R2_SOURCE_V6_v06.txt'), unpack=True) scalc = flux_sensitivity.SensitivityCalc(gdiff, iso, ltc, ebins, 'P8R2_SOURCE_V6', [['FRONT', 'BACK']]) fn = spectrum.PowerLaw([1E-13, -2.0], scale=1E3) o = scalc.int_flux_threshold(c, fn, 25.0, 3.0) assert_allclose(o['eflux'], 1.0719847971553671e-06, rtol=1E-3) assert_allclose(o['flux'], 1.550305083355546e-09, rtol=1E-3) assert_allclose(o['npred'], 511.16725330021416, rtol=1E-3) assert_allclose(o['dnde'], 1.5518569402958423e-14, rtol=1E-3) assert_allclose(o['e2dnde'], 1.5518569402958427e-07, rtol=1E-3) assert_allclose(o['bins']['flux'], np.array([3.88128407e-10, 2.91055245e-10, 2.18260643e-10, 1.63672392e-10, 1.22736979e-10, 9.20397499e-11, 6.90200755e-11, 5.17577549e-11, 3.88128407e-11, 2.91055245e-11, 2.18260643e-11, 1.63672392e-11, 1.22736979e-11, 9.20397499e-12, 6.90200755e-12, 5.17577549e-12, 3.88128407e-12, 2.91055245e-12, 2.18260643e-12, 1.63672392e-12, 1.22736979e-12, 9.20397499e-13, 6.90200755e-13, 5.17577549e-13]), rtol=1E-3)
def test_calc_diff_flux_sensitivity(): ltc = LTCube.create_from_obs_time(3.1536E8) c = SkyCoord(10.0, 10.0, unit='deg', frame='galactic') ebins = 10**np.linspace(2.0, 5.0, 8 * 3 + 1) gdiff = Map.create_from_fits(galdiff_path) iso = np.loadtxt(os.path.expandvars('$FERMIPY_ROOT/data/iso_P8R2_SOURCE_V6_v06.txt'), unpack=True) scalc = flux_sensitivity.SensitivityCalc(gdiff, iso, ltc, ebins, 'P8R2_SOURCE_V6', [['FRONT', 'BACK']]) fn = spectrum.PowerLaw([1E-13, -2.0], scale=1E3) o = scalc.diff_flux_threshold(c, fn, 25.0, 3.0) assert_allclose(o['eflux'], np.array([9.46940878e-07, 8.18350327e-07, 7.08228859e-07, 6.25785181e-07, 5.45241744e-07, 4.80434705e-07, 4.16747935e-07, 3.68406513e-07, 3.16719850e-07, 2.79755007e-07, 2.50862769e-07, 2.31349646e-07, 2.16286209e-07, 2.08381335e-07, 2.02673929e-07, 2.05372045e-07, 2.14355673e-07, 2.29584275e-07, 2.53220397e-07, 2.80878974e-07, 3.19989251e-07, 3.74686765e-07, 4.49321103e-07, 5.48865583e-07]), rtol=1E-3) assert_allclose(o['flux'], np.array([8.22850449e-09, 5.33257909e-09, 3.46076145e-09, 2.29310172e-09, 1.49825986e-09, 9.89993669e-10, 6.43978699e-10, 4.26899204e-10, 2.75215778e-10, 1.82295486e-10, 1.22584132e-10, 8.47748218e-11, 5.94328933e-11, 4.29394879e-11, 3.13181379e-11, 2.37979404e-11, 1.86265760e-11, 1.49602959e-11, 1.23736187e-11, 1.02924147e-11, 8.79292634e-12, 7.72087281e-12, 6.94312304e-12, 6.36010146e-12]), rtol=1E-3)
def test_calc_diff_flux_sensitivity(create_diffuse_dir): ltc = LTCube.create_from_obs_time(3.1536E8) c = SkyCoord(10.0, 10.0, unit='deg', frame='galactic') ebins = 10**np.linspace(2.0, 5.0, 8 * 3 + 1) gdiff = Map.create_from_fits(galdiff_path) iso = np.loadtxt(os.path.expandvars('$FERMI_DIFFUSE_DIR/iso_P8R3_SOURCE_V3_v1.txt'), unpack=True) scalc = SensitivityCalc(gdiff, iso, ltc, ebins, 'P8R3_SOURCE_V3', [['FRONT', 'BACK']]) fn = spectrum.PowerLaw([1E-13, -2.0], scale=1E3) o = scalc.diff_flux_threshold(c, fn, 25.0, 3.0) assert_allclose(o['eflux'], np.array([9.93077714e-07, 8.59371115e-07, 7.44896026e-07, 6.61397166e-07, 5.67842613e-07, 4.93802411e-07, 4.22501374e-07, 3.69299411e-07, 3.16648674e-07, 2.81050363e-07, 2.52941925e-07, 2.35549281e-07, 2.27269823e-07, 2.33109741e-07, 2.28212061e-07, 2.22473996e-07, 2.26623213e-07, 2.46539227e-07, 2.61423960e-07, 3.04766386e-07, 3.35688695e-07, 4.09265051e-07, 4.79776973e-07, 5.93001330e-07]), rtol=3E-3) assert_allclose(o['flux'], np.array([8.62941353e-09, 5.59988099e-09, 3.63993562e-09, 2.42359683e-09, 1.56036437e-09, 1.01753944e-09, 6.52869186e-10, 4.27933870e-10, 2.75153929e-10, 1.83139573e-10, 1.23600112e-10, 8.63137188e-11, 6.24510606e-11, 4.80350743e-11, 3.52644113e-11, 2.57796669e-11, 1.96925718e-11, 1.60651237e-11, 1.27744860e-11, 1.11677353e-11, 9.22432852e-12, 8.43340011e-12, 7.41374161e-12, 6.87153420e-12]), rtol=3E-3)
def write_to_fitsfile(self, fitsfile, clobber=True): """Write this mapping to a FITS file, to avoid having to recompute it """ from fermipy.skymap import Map hpx_header = self._hpx.make_header() index_map = Map(self.ipixs, self.wcs) mult_map = Map(self.mult_val, self.wcs) prim_hdu = index_map.create_primary_hdu() mult_hdu = index_map.create_image_hdu() for key in ['COORDSYS', 'ORDERING', 'PIXTYPE', 'ORDERING', 'ORDER', 'NSIDE', 'FIRSTPIX', 'LASTPIX']: prim_hdu.header[key] = hpx_header[key] mult_hdu.header[key] = hpx_header[key] hdulist = fits.HDUList([prim_hdu, mult_hdu]) hdulist.writeto(fitsfile, overwrite=clobber)
def write_to_fitsfile(self, fitsfile, clobber=True): """Write this mapping to a FITS file, to avoid having to recompute it """ from fermipy.skymap import Map hpx_header = self._hpx.make_header() index_map = Map(self.ipixs, self.wcs) mult_map = Map(self.mult_val, self.wcs) prim_hdu = index_map.create_primary_hdu() mult_hdu = index_map.create_image_hdu() for key in [ 'COORDSYS', 'ORDERING', 'PIXTYPE', 'ORDERING', 'ORDER', 'NSIDE', 'FIRSTPIX', 'LASTPIX' ]: prim_hdu.header[key] = hpx_header[key] mult_hdu.header[key] = hpx_header[key] hdulist = fits.HDUList([prim_hdu, mult_hdu]) hdulist.writeto(fitsfile, overwrite=clobber)
def test_calc_diff_flux_sensitivity(): ltc = LTCube.create_from_obs_time(3.1536E8) c = SkyCoord(10.0, 10.0, unit='deg', frame='galactic') ebins = 10**np.linspace(2.0, 5.0, 8 * 3 + 1) gdiff = Map.create_from_fits(galdiff_path) iso = np.loadtxt( os.path.expandvars('$FERMIPY_ROOT/data/iso_P8R2_SOURCE_V6_v06.txt'), unpack=True) scalc = SensitivityCalc(gdiff, iso, ltc, ebins, 'P8R2_SOURCE_V6', [['FRONT', 'BACK']]) fn = spectrum.PowerLaw([1E-13, -2.0], scale=1E3) o = scalc.diff_flux_threshold(c, fn, 25.0, 3.0) assert_allclose( o['eflux'], np.array([ 9.46940878e-07, 8.18350327e-07, 7.08228859e-07, 6.25785181e-07, 5.45241744e-07, 4.80434705e-07, 4.16747935e-07, 3.68406513e-07, 3.16719850e-07, 2.79755007e-07, 2.50862769e-07, 2.31349646e-07, 2.16286209e-07, 2.08381335e-07, 2.02673929e-07, 2.05372045e-07, 2.14355673e-07, 2.29584275e-07, 2.53220397e-07, 2.80878974e-07, 3.19989251e-07, 3.74686765e-07, 4.49321103e-07, 5.48865583e-07 ]), rtol=3E-3) assert_allclose( o['flux'], np.array([ 8.22850449e-09, 5.33257909e-09, 3.46076145e-09, 2.29310172e-09, 1.49825986e-09, 9.89993669e-10, 6.43978699e-10, 4.26899204e-10, 2.75215778e-10, 1.82295486e-10, 1.22584132e-10, 8.47748218e-11, 5.94328933e-11, 4.29394879e-11, 3.13181379e-11, 2.37979404e-11, 1.86265760e-11, 1.49602959e-11, 1.23736187e-11, 1.02924147e-11, 8.79292634e-12, 7.72087281e-12, 6.94312304e-12, 6.36010146e-12 ]), rtol=3E-3)
def main(): import sys import argparse # Argument defintion usage = "usage: %(prog)s [options]" description = "Plot a WCS-based image" parser = argparse.ArgumentParser(usage, description=__abstract__) parser.add_argument("-i", "--input", type=argparse.FileType('r'), required=True, help="Input file") parser.add_argument("-e", "--extension", type=str, default=None, help="FITS HDU with map") parser.add_argument("--ebin", type=str, default=None, help="Energy bin, integer or 'ALL'") parser.add_argument("--zscale", type=str, default='log', help="Scaling for color scale") parser.add_argument("--zmin", type=float, default=None, help="Minimum z-axis value") parser.add_argument("--zmax", type=float, default=None, help="Maximum z-axis value") parser.add_argument("-o", "--output", type=argparse.FileType('w'), help="Output file. Leave blank for interactive.") # Parse the command line args = parser.parse_args(sys.argv[1:]) # Get the map themap = Map.create_from_fits(args.input.name) if args.extension is None: counts = themap.counts else: fin = pf.open(args.input.name) counts = fin[args.extension].data outdata = [] if args.ebin == "ALL": for i, data in enumerate(counts): ip = ImagePlotter(data=data.T, proj=themap.wcs.dropaxis(2)) fig = plt.figure(i) im, ax = ip.plot(zscale=args.zscale, vmin=args.zmin, vmax=args.zmax) outdata.append(fig) elif args.ebin is None: ip = ImagePlotter(data=counts.sum(0).T, proj=themap.wcs.dropaxis(2)) im, ax = ip.plot(zscale=args.zscale, vmin=args.zmin, vmax=args.zmax) outdata.append((im, ax)) else: try: ibin = int(args.ebin) ip = ImagePlotter(data=counts[ibin].T, proj=themap.wcs.dropaxis(2)) im, ax = ip.plot(zscale=args.zscale, vmin=args.zmin, vmax=args.zmax) outdata.append((im, ax)) except: raise ValueError("--ebin argument must be an integer or 'ALL'") if args.output is None: plt.show() else: if len(outdata) == 1: plt.savefig(args.output.name) else: base, ext = os.path.splitext(args.output.name) for i, fig in enumerate(outdata): fig.savefig("%s_%02i%s" % (base, i, ext))
def main(): usage = "usage: %(prog)s -c config.yaml" description = "Run the analysis" parser = argparse.ArgumentParser(usage=usage, description=description) parser.add_argument('-c', '--conf', required=True) parser.add_argument('--overwrite', required=False, default=0, help='Overwrite existing files', type=int) parser.add_argument('--state', default=['setup'], choices=[ 'setup', 'lcbinexp', 'avgspec', 'tsresid', 'avgsed', 'lcbin', 'srcprob' ], help='Analysis state') parser.add_argument('-i', required=False, default=0, help='Set local or scratch calculation', type=int) parser.add_argument( '--dt', required=False, default=0., help= 'time interval for light curve binning, if none, use binning of config file', type=float) parser.add_argument( '--specin', required=False, default=-2.1, help='Spectral index used for gtexposure in lieu of target in xml file', type=float) parser.add_argument( '--targetname', required=False, default="", help='Source name used for binned light curve exposure calculation') parser.add_argument( '--srcmdl', required=False, default="srcmdl", help='srcmdl name for gtsrcprob / gtexposure calculation') args = parser.parse_args() gta, config, fit_config, job_id = setup.init_gta(args.conf, i=args.i, logging_level="INFO") logging.info('Running fermipy setup') pps = PreparePointSource(config, logging={'verbosity': 3}) if args.state == 'setup': pps.setup() return pps if args.state == 'lcbinexp': pps._bin_data_lc(overwrite=args.overwrite, dtime=args.dt) if 'target' in config['selection'].keys(): target = pps.roi.sources[0].name # assume central source files = [ fn for fn in glob(fit_config['avgspec']) if fn.find('.xml') > 0 ] utils.copy2scratch(files, gta.workdir) else: target = args.targetname logging.info( "Running lc bin with target {0:s} and specin {1:.2f}".format( target, args.specin)) pps._compute_lc_exp(overwrite=args.overwrite, specin=args.specin, target=target, srcmdl=args.srcmdl) return pps if args.state == 'srcprob': # copy srcmodels of average fit files = [ fn for fn in glob(fit_config['avgspec']) if fn.find('.xml') > 0 ] utils.copy2scratch(files, gta.workdir) logging.info("Running diffrsp with srcmdl {0:s}".format(args.srcmdl)) pps._compute_diffrsp(args.srcmdl, overwrite=args.overwrite) logging.info("Running srcprob with srcmdl {0:s}".format(args.srcmdl)) pps._compute_srcprob(args.srcmdl, overwrite=args.overwrite) return pps elif args.state == 'avgspec': gta.setup() logging.info('Running fermipy optimize and fit') # run the fitting of the entire time and energy range o = gta.optimize() # perform an initial fit logging.debug(o) gta.print_roi() # Free all parameters of all Sources within X deg of ROI center #gta.free_sources(distance=fit_config['ps_dist_all']) # Free Normalization of all Sources within X deg of ROI center gta.free_sources(distance=fit_config['ps_dist_norm'], pars=fa.allnorm) # Free spectra parameters of all Sources within X deg of ROI center gta.free_sources(distance=fit_config['ps_dist_idx'], pars=fa.allidx) # Free all parameters of isotropic and galactic diffuse components gta.free_source('galdiff', pars='norm', free=fit_config['gal_norm_free']) gta.free_source('galdiff', pars=['index'], free=fit_config['gal_idx_free']) gta.free_source('isodiff', pars='norm', free=fit_config['iso_norm_free']) # Free sources with TS > X gta.free_sources(minmax_ts=[fit_config['ts_norm'], None], pars=fa.allnorm) # Fix sources with TS < Y gta.free_sources(minmax_ts=[None, fit_config['ts_fixed']], free=False, pars=fa.allnorm + fa.allidx) # Fix sources Npred < Z gta.free_sources(minmax_npred=[None, fit_config['npred_fixed']], free=False, pars=fa.allnorm + fa.allidx) # gives "failed to create spline" in get_parameter_limits function #gta = fa.utils.add_ebl_atten(gta,config['selection']['target'],fit_config['z']) f = gta.fit() #logging.debug(f) #relocalize central source and refit loc = gta.localize(config['selection']['target'], make_plots=True, free_background=fit_config['reloc_bkg'], free_radius=fit_config['reloc_rad'], update=True) logging.info( 'new position is {0[pos_offset]:.3f} degrees from old position'. format(loc)) logging.info( 'Pos uncertainty is {0[pos_r68]:.3f} (68%); {0[pos_r95]:.3f} (95%) degrees' .format(loc)) logging.info('Refitting with new source position ...') logging.info('free source parameters:') for s in gta.get_sources(): for k in s.spectral_pars.keys(): if s.spectral_pars[k]['free']: logging.info('{0:s}: {1:s}'.format(s.name, k)) f = gta.fit() gta.print_roi() gta.write_roi(args.state) if args.state == 'tsresid': gta.setup() gta.load_roi('avgspec') # reload the average spectral fit max_sqrt_ts = 1000. irun = 0 # define the test source model = { 'Scale': 1000., 'Index': fit_config['new_src_pl_index'], 'SpatialModel': 'PointSource' } #model = {'Index' : 2.0, 'SpatialModel' : 'PointSource'} # run ts map and add new sources with sqrt(ts) > 5 # reoptimize iteratively for each new source # this is only done for outer RoI while max_sqrt_ts >= fit_config['max_sqrt_ts']: # run ts and residual maps ts_maps = gta.tsmap('avgspec', model=model, write_fits=True, write_npy=True, make_plots=True) # get the skydirs coords = ts_maps['sqrt_ts'].get_pixel_skydirs() #sqrt_ts = ts_maps['sqrt_ts'].get_map_values(coords.ra, coords.dec) # these are all nans. workaround: load fits file sqrt_ts_map = Map.create_from_fits(path.join( gta.workdir, ts_maps['file']), hdu='SQRT_TS_MAP') n_map = Map.create_from_fits(path.join(gta.workdir, ts_maps['file']), hdu='N_MAP') sqrt_ts = sqrt_ts_map.get_map_values(coords.ra, coords.dec) amplitudes = n_map.get_map_values(coords.ra, coords.dec) # get the angular separation from RoI center sep = gta.roi.skydir.separation(coords) # mask nan values and pixels close to central source m = np.isfinite(sqrt_ts) & (sep.value > fit_config['new_src_search_rad']) if not np.sum(m): logging.warning( 'No pixels that are finite at distance > {0[new_src_search_rad]:.2f}' .format(fit_config)) raise RuntimeError # get max ts value max_sqrt_ts = np.max(sqrt_ts[m]) if max_sqrt_ts < fit_config['max_sqrt_ts']: break # get the coords of max ts idx = np.argmax(sqrt_ts[m]) logging.info( 'Found new source with sqrt(ts) = {0:.2f} at ra,dec = {1:.2f}, {2:.2f}' .format(sqrt_ts[m][idx], coords.ra[m][idx].value, coords.dec[m][idx].value)) # add a new source c = SkyCoord(ra=coords.ra[m][idx], dec=coords.dec[m][idx], frame='icrs') if c.dec.value < 0.: sign = '-' else: sign = '+' newname = 'j{0:02.0f}{1:02.0f}{2:s}{3:02.0f}{4:02.0f}'.format( c.ra.hms.h, c.ra.hms.m, sign, np.abs(c.dec.dms.d), np.abs(c.dec.dms.m)) gta.add_source( newname, { 'ra': coords.ra[m][idx].value, 'dec': coords.dec[m][idx].value, 'SpectrumType': 'PowerLaw', 'Index': fit_config['new_src_pl_index'], 'Scale': 1000, 'Prefactor': amplitudes[m][idx], 'SpatialModel': 'PointSource' }) logging.debug('Amplitude of source: {0}'.format( amplitudes[m][idx])) gta.free_source(newname, pars=['norm', 'index'], free=True) f = gta.fit() gta.print_roi() irun += 1 resid_maps = gta.residmap('avgspec', model=model, make_plots=True, write_fits=True, write_npy=True) # if new sources where added, save output if irun > 0: gta.print_roi() # gta = reset_diff_filenames(gta) gta.write_roi('avgspec') if args.state == 'avgsed': gta.setup() gta.load_roi('avgspec') # reload the average spectral fit logging.info('Running sed for {0[target]:s}'.format( config['selection'])) sed = gta.sed( config['selection']['target'], #outfile = 'sed.fits', #free_radius = sed_config['free_radius'], #free_background= sed_config['free_background'], #make_plots = sed_config['make_plots'], #cov_scale = sed_config['cov_scale'], #use_local_index = sed_config['use_local_index'], #bin_index = sed_config['bin_index'] ) if args.state == 'lcmonthly': gta.setup() gta.load_roi('avgspec') # reload the average spectral fit logging.info( 'Running the 30-day bin light curve for {0[target]:s}'.format( config['selection'])) lc = gta.lightcurve(config['selection']['target'], binsz=30. * 24. * 60. * 60.) # run the analysis for the full flare durations #if args.state == 'fullflare-avg': if args.state.find('-avg') >= 0: # stage the full time array analysis results to the tmp dir # do not copy png images files = [ fn for fn in glob(fit_config['avgspec']) if fn.find('.xml') > 0 or fn.find('.npy') > 0 ] utils.copy2scratch(files, gta.workdir) if args.state == 'fullflare-avg': gta.load_roi('avgspec') # reload the average spectral fit elif args.state == 'gtiflare-avg': gta.load_roi('fullflare-avg') # reload the average spectral fit o = gta.optimize() # perform an initial fit logging.debug(o) gta.print_roi() # Free all parameters of all Sources within X deg of ROI center #gta.free_sources(distance=fit_config['ps_dist_all']) # Free Normalization of all Sources within X deg of ROI center gta.free_sources(distance=fit_config['ps_dist_norm_fullflare'], pars=fa.allnorm) # Free spectra parameters of all Sources within X deg of ROI center gta.free_sources(distance=fit_config['ps_dist_idx_fullflare'], pars=fa.allidx) # Free all parameters of isotropic and galactic diffuse components gta.free_source('galdiff', pars=fa.allnorm, free=fit_config['gal_norm_free_fullflare']) gta.free_source('galdiff', pars=fa.allidx, free=fit_config['gal_idx_free_fullflare']) gta.free_source('isodiff', pars=fa.allnorm, free=fit_config['iso_norm_free_fullflare']) # Free sources with TS > X gta.free_sources(minmax_ts=[fit_config['ts_norm'], None], pars=fa.allnorm) # Fix sources with TS < Y gta.free_sources(minmax_ts=[None, fit_config['ts_fixed']], free=False, pars=fa.allidx + fa.allnorm) # Fix indeces for sources with TS < Z gta.free_sources(minmax_ts=[None, fit_config['ts_fixed_idx']], free=False, pars=fa.allidx) # Fix sources Npred < Z gta.free_sources(minmax_npred=[None, fit_config['npred_fixed']], free=False, pars=fa.allidx + fa.allnorm) # gives "failed to create spline" in get_parameter_limits function #gta = fa.utils.add_ebl_atten(gta,config['selection']['target'],fit_config['z']) logging.info('free source parameters:') for s in gta.get_sources(): for k in s.spectral_pars.keys(): if s.spectral_pars[k]['free']: logging.info('{0:s}: {1:s}'.format(s.name, k)) f = gta.fit() retries = f['config']['retries'] tsfix = fit_config['ts_fixed'] while not f['fit_success'] and retries > 0: gta.free_source(config['selection']['target'], pars=['beta', 'Index2'], free=False) # Fix more sources tsfix *= 3 gta.free_sources(minmax_ts=[None, tsfix], free=False, pars=fa.allidx + fa.allnorm) logging.info("retrying fit") for s in gta.get_sources(): for k in s.spectral_pars.keys(): if s.spectral_pars[k]['free']: logging.info('{0:s}: {1:s}'.format(s.name, k)) o = gta.optimize() gta.print_roi() f = gta.fit() retries -= 1 gta.write_roi(args.state) logging.info('Running sed for {0[target]:s}'.format( config['selection'])) sed = gta.sed(config['selection']['target'], prefix=args.state) model = { 'Scale': 1000., 'Index': fit_config['new_src_pl_index'], 'SpatialModel': 'PointSource' } resid_maps = gta.residmap(args.state, model=model, make_plots=True, write_fits=True, write_npy=True) return f, gta
def localize(self, name, **kwargs): """Find the best-fit position of a source. Localization is performed in two steps. First a TS map is computed centered on the source with half-width set by ``dtheta_max``. A fit is then performed to the maximum TS peak in this map. The source position is then further refined by scanning the likelihood in the vicinity of the peak found in the first step. The size of the scan region is set to encompass the 99% positional uncertainty contour as determined from the peak fit. Parameters ---------- name : str Source name. dtheta_max : float Maximum offset in RA/DEC in deg from the nominal source position that will be used to define the boundaries of the TS map search region. nstep : int Number of steps in longitude/latitude that will be taken when refining the source position. The bounds of the scan range are set to the 99% positional uncertainty as determined from the TS map peak fit. The total number of sampling points will be nstep**2. fix_background : bool Fix background parameters when fitting the source position. update : bool Update the model for this source with the best-fit position. If newname=None this will overwrite the existing source map of this source with one corresponding to its new location. newname : str Name that will be assigned to the relocalized source when update=True. If newname is None then the existing source name will be used. make_plots : bool Generate plots. write_fits : bool Write the output to a FITS file. write_npy : bool Write the output dictionary to a numpy file. optimizer : dict Dictionary that overrides the default optimizer settings. Returns ------- localize : dict Dictionary containing results of the localization analysis. This dictionary is also saved to the dictionary of this source in 'localize'. """ name = self.roi.get_source_by_name(name).name schema = ConfigSchema(self.defaults['localize'], optimizer=self.defaults['optimizer']) schema.add_option('make_plots', False) schema.add_option('write_fits', True) schema.add_option('write_npy', True) schema.add_option('newname', name) schema.add_option('prefix', '') config = utils.create_dict(self.config['localize'], optimizer=self.config['optimizer']) config = schema.create_config(config, **kwargs) nstep = config['nstep'] dtheta_max = config['dtheta_max'] update = config['update'] newname = config['newname'] prefix = config['prefix'] self.logger.info('Running localization for %s' % name) saved_state = LikelihoodState(self.like) if config['fix_background']: self.free_sources(free=False, loglevel=logging.DEBUG) src = self.roi.copy_source(name) skydir = src.skydir skywcs = self._skywcs src_pix = skydir.to_pixel(skywcs) tsmap_fit, tsmap = self._localize_tsmap(name, prefix=prefix, dtheta_max=dtheta_max) self.logger.debug( 'Completed localization with TS Map.\n' '(ra,dec) = (%10.4f,%10.4f)\n' '(glon,glat) = (%10.4f,%10.4f)', tsmap_fit['ra'], tsmap_fit['dec'], tsmap_fit['glon'], tsmap_fit['glat']) # Fit baseline (point-source) model self.free_norm(name) fit_output = self._fit(loglevel=logging.DEBUG, **config['optimizer']) # Save likelihood value for baseline fit loglike0 = fit_output['loglike'] self.logger.debug('Baseline Model Likelihood: %f', loglike0) self.zero_source(name) o = { 'name': name, 'config': config, 'fit_success': True, 'loglike_base': loglike0, 'loglike_loc': np.nan, 'dloglike_loc': np.nan } cdelt0 = np.abs(skywcs.wcs.cdelt[0]) cdelt1 = np.abs(skywcs.wcs.cdelt[1]) scan_step = 2.0 * tsmap_fit['r95'] / (nstep - 1.0) self.logger.debug( 'Refining localization search to ' 'region of width: %.4f deg', tsmap_fit['r95']) scan_map = Map.create(SkyCoord(tsmap_fit['ra'], tsmap_fit['dec'], unit='deg'), scan_step, (nstep, nstep), coordsys=wcs_utils.get_coordsys(skywcs)) scan_skydir = scan_map.get_pixel_skydirs() lnlscan = dict(wcs=scan_map.wcs.to_header().items(), loglike=np.zeros((nstep, nstep)), dloglike=np.zeros((nstep, nstep)), dloglike_fit=np.zeros((nstep, nstep))) for i, t in enumerate(scan_skydir): model_name = '%s_localize' % (name.replace(' ', '').lower()) src.set_name(model_name) src.set_position(t) self.add_source(model_name, src, free=True, init_source=False, save_source_maps=False, loglevel=logging.DEBUG) fit_output = self._fit(loglevel=logging.DEBUG, **config['optimizer']) loglike1 = fit_output['loglike'] lnlscan['loglike'].flat[i] = loglike1 self.delete_source(model_name, loglevel=logging.DEBUG) lnlscan['dloglike'] = lnlscan['loglike'] - np.max(lnlscan['loglike']) scan_tsmap = Map(2.0 * lnlscan['dloglike'].T, scan_map.wcs) self.unzero_source(name) saved_state.restore() self._sync_params(name) self._update_roi() scan_fit, new_skydir = fit_error_ellipse(scan_tsmap, dpix=3) o.update(scan_fit) o['loglike_loc'] = np.max( lnlscan['loglike']) + 0.5 * scan_fit['offset'] o['dloglike_loc'] = o['loglike_loc'] - o['loglike_base'] # lnlscan['dloglike_fit'] = \ # utils.parabola(np.linspace(0,nstep-1.0,nstep)[:,np.newaxis], # np.linspace(0,nstep-1.0,nstep)[np.newaxis,:], # *scan_fit['popt']).reshape((nstep,nstep)) o['lnlscan'] = lnlscan # Best fit position and uncertainty from fit to TS map o['tsmap_fit'] = tsmap_fit # Best fit position and uncertainty from pylike scan o['scan_fit'] = scan_fit pix = new_skydir.to_pixel(skywcs) o['xpix'] = float(pix[0]) o['ypix'] = float(pix[1]) o['deltax'] = (o['xpix'] - src_pix[0]) * cdelt0 o['deltay'] = (o['ypix'] - src_pix[1]) * cdelt1 o['offset'] = skydir.separation(new_skydir).deg if o['offset'] > dtheta_max: o['fit_success'] = False if not o['fit_success']: self.logger.error( 'Localization failed.\n' '(ra,dec) = (%10.4f,%10.4f)\n' '(glon,glat) = (%10.4f,%10.4f)\n' 'offset = %8.4f deltax = %8.4f ' 'deltay = %8.4f', o['ra'], o['dec'], o['glon'], o['glat'], o['offset'], o['deltax'], o['deltay']) else: self.logger.info( 'Localization succeeded with ' 'coordinates:\n' '(ra,dec) = (%10.4f,%10.4f)\n' '(glon,glat) = (%10.4f,%10.4f)\n' 'offset = %8.4f r68 = %8.4f', o['ra'], o['dec'], o['glon'], o['glat'], o['offset'], o['r68']) self.roi[name]['localize'] = copy.deepcopy(o) if config['make_plots']: self._plotter.make_localization_plots(o, tsmap, self.roi, prefix=prefix, skydir=scan_skydir) if update and o['fit_success']: self.logger.info('Updating source %s ' 'to localized position.', name) src = self.delete_source(name) src.set_position(new_skydir) src.set_name(newname, names=src.names) self.add_source(newname, src, free=True) fit_output = self.fit(loglevel=logging.DEBUG) o['loglike_loc'] = fit_output['loglike'] o['dloglike_loc'] = o['loglike_loc'] - o['loglike_base'] src = self.roi.get_source_by_name(newname) self.roi[newname]['localize'] = copy.deepcopy(o) self.logger.info('LogLike: %12.3f DeltaLogLike: %12.3f', o['loglike_loc'], o['dloglike_loc']) if o['fit_success']: src = self.roi.get_source_by_name(newname) src['pos_sigma'] = o['sigma'] src['pos_sigma_semimajor'] = o['sigma_semimajor'] src['pos_sigma_semiminor'] = o['sigma_semiminor'] src['pos_r68'] = o['r68'] src['pos_r95'] = o['r95'] src['pos_r99'] = o['r99'] src['pos_angle'] = np.degrees(o['theta']) self.logger.info('Finished localization.') return o
def run_flux_sensitivity(**kwargs): index = kwargs.get('index', 2.0) sedshape = kwargs.get('sedshape', 'PowerLaw') cutoff = kwargs.get('cutoff', 1e3) curvindex = kwargs.get('curvindex', 1.0) beta = kwargs.get('beta', 0.0) emin = kwargs.get('emin', 10**1.5) emax = kwargs.get('emax', 10**6.0) nbin = kwargs.get('nbin', 18) glon = kwargs.get('glon', 0.0) glat = kwargs.get('glat', 0.0) ltcube_filepath = kwargs.get('ltcube', None) galdiff_filepath = kwargs.get('galdiff', None) isodiff_filepath = kwargs.get('isodiff', None) galdiff_fit_filepath = kwargs.get('galdiff_fit', None) isodiff_fit_filepath = kwargs.get('isodiff_fit', None) wcs_npix = kwargs.get('wcs_npix', 40) wcs_cdelt = kwargs.get('wcs_cdelt', 0.5) wcs_proj = kwargs.get('wcs_proj', 'AIT') map_type = kwargs.get('map_type', None) spatial_model = kwargs.get('spatial_model', 'PointSource') spatial_size = kwargs.get('spatial_size', 1E-2) obs_time_yr = kwargs.get('obs_time_yr', None) event_class = kwargs.get('event_class', 'P8R2_SOURCE_V6') min_counts = kwargs.get('min_counts', 3.0) ts_thresh = kwargs.get('ts_thresh', 25.0) nside = kwargs.get('hpx_nside', 16) output = kwargs.get('output', None) event_types = [['FRONT', 'BACK']] if sedshape == 'PowerLaw': fn = spectrum.PowerLaw([1E-13, -index], scale=1E3) elif sedshape == 'PLSuperExpCutoff': fn = spectrum.PLSuperExpCutoff([1E-13, -index, cutoff, curvindex], scale=1E3) elif sedshape == 'LogParabola': fn = spectrum.LogParabola([1E-13, -index, beta], scale=1E3) log_ebins = np.linspace(np.log10(emin), np.log10(emax), nbin + 1) ebins = 10**log_ebins ectr = np.exp(utils.edge_to_center(np.log(ebins))) c = SkyCoord(glon, glat, unit='deg', frame='galactic') if ltcube_filepath is None: if obs_time_yr is None: raise Exception('No observation time defined.') ltc = LTCube.create_from_obs_time(obs_time_yr * 365 * 24 * 3600.) else: ltc = LTCube.create(ltcube_filepath) if obs_time_yr is not None: ltc._counts *= obs_time_yr * 365 * \ 24 * 3600. / (ltc.tstop - ltc.tstart) gdiff = skymap.Map.create_from_fits(galdiff_filepath) gdiff_fit = None if galdiff_fit_filepath is not None: gdiff_fit = skymap.Map.create_from_fits(galdiff_fit_filepath) if isodiff_filepath is None: isodiff = utils.resolve_file_path('iso_%s_v06.txt' % event_class, search_dirs=[ os.path.join( '$FERMIPY_ROOT', 'data'), '$FERMI_DIFFUSE_DIR' ]) isodiff = os.path.expandvars(isodiff) else: isodiff = isodiff_filepath iso = np.loadtxt(isodiff, unpack=True) iso_fit = None if isodiff_fit_filepath is not None: iso_fit = np.loadtxt(isodiff_fit_filepath, unpack=True) scalc = SensitivityCalc(gdiff, iso, ltc, ebins, event_class, event_types, gdiff_fit=gdiff_fit, iso_fit=iso_fit, spatial_model=spatial_model, spatial_size=spatial_size) # Compute Maps map_diff_flux = None map_diff_npred = None map_int_flux = None map_int_npred = None map_nstep = 500 if map_type == 'hpx': hpx = HPX(nside, True, 'GAL', ebins=ebins) map_diff_flux = HpxMap(np.zeros((nbin, hpx.npix)), hpx) map_diff_npred = HpxMap(np.zeros((nbin, hpx.npix)), hpx) map_skydir = map_diff_flux.hpx.get_sky_dirs() for i in range(0, len(map_skydir), map_nstep): s = slice(i, i + map_nstep) o = scalc.diff_flux_threshold(map_skydir[s], fn, ts_thresh, min_counts) map_diff_flux.data[:, s] = o['flux'].T map_diff_npred.data[:, s] = o['npred'].T hpx = HPX(nside, True, 'GAL') map_int_flux = HpxMap(np.zeros((hpx.npix)), hpx) map_int_npred = HpxMap(np.zeros((hpx.npix)), hpx) map_skydir = map_int_flux.hpx.get_sky_dirs() for i in range(0, len(map_skydir), map_nstep): s = slice(i, i + map_nstep) o = scalc.int_flux_threshold(map_skydir[s], fn, ts_thresh, min_counts) map_int_flux.data[s] = o['flux'] map_int_npred.data[s] = o['npred'] elif map_type == 'wcs': wcs_shape = [wcs_npix, wcs_npix] wcs_size = wcs_npix * wcs_npix map_diff_flux = Map.create(c, wcs_cdelt, wcs_shape, 'GAL', wcs_proj, ebins=ebins) map_diff_npred = Map.create(c, wcs_cdelt, wcs_shape, 'GAL', wcs_proj, ebins=ebins) map_skydir = map_diff_flux.get_pixel_skydirs() for i in range(0, len(map_skydir), map_nstep): idx = np.unravel_index(np.arange(i, min(i + map_nstep, wcs_size)), wcs_shape) s = (slice(None), idx[1], idx[0]) o = scalc.diff_flux_threshold(map_skydir[slice(i, i + map_nstep)], fn, ts_thresh, min_counts) map_diff_flux.data[s] = o['flux'].T map_diff_npred.data[s] = o['npred'].T map_int_flux = Map.create(c, wcs_cdelt, wcs_shape, 'GAL', wcs_proj) map_int_npred = Map.create(c, wcs_cdelt, wcs_shape, 'GAL', wcs_proj) map_skydir = map_int_flux.get_pixel_skydirs() for i in range(0, len(map_skydir), map_nstep): idx = np.unravel_index(np.arange(i, min(i + map_nstep, wcs_size)), wcs_shape) s = (idx[1], idx[0]) o = scalc.int_flux_threshold(map_skydir[slice(i, i + map_nstep)], fn, ts_thresh, min_counts) map_int_flux.data[s] = o['flux'] map_int_npred.data[s] = o['npred'] o = scalc.diff_flux_threshold(c, fn, ts_thresh, min_counts) cols = [ Column(name='e_min', dtype='f8', data=scalc.ebins[:-1], unit='MeV'), Column(name='e_ref', dtype='f8', data=o['e_ref'], unit='MeV'), Column(name='e_max', dtype='f8', data=scalc.ebins[1:], unit='MeV'), Column(name='flux', dtype='f8', data=o['flux'], unit='ph / (cm2 s)'), Column(name='eflux', dtype='f8', data=o['eflux'], unit='MeV / (cm2 s)'), Column(name='dnde', dtype='f8', data=o['dnde'], unit='ph / (MeV cm2 s)'), Column(name='e2dnde', dtype='f8', data=o['e2dnde'], unit='MeV / (cm2 s)'), Column(name='npred', dtype='f8', data=o['npred'], unit='ph') ] tab_diff = Table(cols) cols = [ Column(name='index', dtype='f8'), Column(name='e_min', dtype='f8', unit='MeV'), Column(name='e_ref', dtype='f8', unit='MeV'), Column(name='e_max', dtype='f8', unit='MeV'), Column(name='flux', dtype='f8', unit='ph / (cm2 s)'), Column(name='eflux', dtype='f8', unit='MeV / (cm2 s)'), Column(name='dnde', dtype='f8', unit='ph / (MeV cm2 s)'), Column(name='e2dnde', dtype='f8', unit='MeV / (cm2 s)'), Column(name='npred', dtype='f8', unit='ph'), Column(name='ebin_e_min', dtype='f8', unit='MeV', shape=(len(ectr), )), Column(name='ebin_e_ref', dtype='f8', unit='MeV', shape=(len(ectr), )), Column(name='ebin_e_max', dtype='f8', unit='MeV', shape=(len(ectr), )), Column(name='ebin_flux', dtype='f8', unit='ph / (cm2 s)', shape=(len(ectr), )), Column(name='ebin_eflux', dtype='f8', unit='MeV / (cm2 s)', shape=(len(ectr), )), Column(name='ebin_dnde', dtype='f8', unit='ph / (MeV cm2 s)', shape=(len(ectr), )), Column(name='ebin_e2dnde', dtype='f8', unit='MeV / (cm2 s)', shape=(len(ectr), )), Column(name='ebin_npred', dtype='f8', unit='ph', shape=(len(ectr), )) ] cols_ebounds = [ Column(name='E_MIN', dtype='f8', unit='MeV', data=ebins[:-1]), Column(name='E_MAX', dtype='f8', unit='MeV', data=ebins[1:]), ] tab_int = Table(cols) tab_ebounds = Table(cols_ebounds) index = np.linspace(1.0, 5.0, 4 * 4 + 1) for g in index: fn = spectrum.PowerLaw([1E-13, -g], scale=10**3.5) o = scalc.int_flux_threshold(c, fn, ts_thresh, 3.0) row = [g] for colname in tab_int.columns: if colname == 'index': continue if 'ebin' in colname: row += [o['bins'][colname.replace('ebin_', '')]] else: row += [o[colname]] tab_int.add_row(row) hdulist = fits.HDUList() hdulist.append(fits.table_to_hdu(tab_diff)) hdulist.append(fits.table_to_hdu(tab_int)) hdulist.append(fits.table_to_hdu(tab_ebounds)) hdulist[1].name = 'DIFF_FLUX' hdulist[2].name = 'INT_FLUX' hdulist[3].name = 'EBOUNDS' if map_type is not None: hdu = map_diff_flux.create_image_hdu() hdu.name = 'MAP_DIFF_FLUX' hdulist.append(hdu) hdu = map_diff_npred.create_image_hdu() hdu.name = 'MAP_DIFF_NPRED' hdulist.append(hdu) hdu = map_int_flux.create_image_hdu() hdu.name = 'MAP_INT_FLUX' hdulist.append(hdu) hdu = map_int_npred.create_image_hdu() hdu.name = 'MAP_INT_NPRED' hdulist.append(hdu) hdulist.writeto(output, clobber=True)
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. """ 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) if loge_bounds is not None: if len(loge_bounds) == 0: loge_bounds = [None, None] elif len(loge_bounds) == 1: loge_bounds += [None] 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]) skywcs = self._skywcs skydir = wcs_utils.pix_to_skydir(cpix[0], cpix[1], skywcs) 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']).counts.astype('float')[ eslice, ...] cm = c.counts_map().counts.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) 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').counts.astype('float')[ eslice, ...] model_npred += np.sum(mm) model += [mm] self.delete_source('tsmap_testsource') 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'], self._skywcs) 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)] map_wcs = skywcs.deepcopy() map_wcs.wcs.crpix[0] -= ymin map_wcs.wcs.crpix[1] -= xmin else: xyrange = [range(self.npix), range(self.npix)] map_wcs = skywcs 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] 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 = Map(ts_values, map_wcs) sqrt_ts_map = Map(ts_values**0.5, map_wcs) npred_map = Map(amp_values * model_npred, map_wcs) amp_map = Map(amp_values * src.get_norm(), map_wcs) 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, 'config': kwargs } fits_file = utils.format_filename(self.config['fileio']['workdir'], 'tsmap.fits', prefix=[prefix, modelname]) if kwargs['write_fits']: fits_utils.write_maps(ts_map, {'SQRT_TS_MAP': sqrt_ts_map, 'NPRED_MAP': npred_map, 'N_MAP': amp_map}, fits_file) o['file'] = os.path.basename(fits_file) if kwargs['write_npy']: np.save(os.path.splitext(fits_file)[0] + '.npy', o) return o
def _make_residual_map(self, prefix, config, **kwargs): write_fits = kwargs.get('write_fits', True) write_npy = kwargs.get('write_npy', True) src_dict = copy.deepcopy(config.setdefault('model', {})) exclude = config.setdefault('exclude', None) loge_bounds = config.setdefault('loge_bounds', None) if loge_bounds is not None: if len(loge_bounds) == 0: loge_bounds = [None, None] elif len(loge_bounds) == 1: loge_bounds += [None] loge_bounds[0] = (loge_bounds[0] if loge_bounds[0] is not None else self.energies[0]) loge_bounds[1] = (loge_bounds[1] if loge_bounds[1] is not None else self.energies[-1]) else: loge_bounds = [self.energies[0], self.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]) skywcs = self._skywcs skydir = wcs_utils.pix_to_skydir(cpix[0], cpix[1], skywcs) if src_dict is None: src_dict = {} 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) kernel = None if src_dict['SpatialModel'] == 'Gaussian': kernel = utils.make_gaussian_kernel(src_dict['SpatialWidth'], cdelt=self.components[0].binsz, npix=101) kernel /= np.sum(kernel) cpix = [50, 50] self.add_source('residmap_testsource', src_dict, free=True, init_source=False, save_source_maps=False) src = self.roi.get_source_by_name('residmap_testsource') modelname = utils.create_model_name(src) npix = self.components[0].npix mmst = np.zeros((npix, npix)) cmst = np.zeros((npix, npix)) emst = np.zeros((npix, npix)) sm = get_source_kernel(self, 'residmap_testsource', kernel) ts = np.zeros((npix, npix)) sigma = np.zeros((npix, npix)) excess = np.zeros((npix, npix)) self.delete_source('residmap_testsource') for i, c in enumerate(self.components): imin = utils.val_to_edge(c.energies, loge_bounds[0])[0] imax = utils.val_to_edge(c.energies, loge_bounds[1])[0] mc = c.model_counts_map(exclude=exclude).counts.astype('float') cc = c.counts_map().counts.astype('float') ec = np.ones(mc.shape) ccs = convolve_map(cc, sm[i], cpix, imin=imin, imax=imax) mcs = convolve_map(mc, sm[i], cpix, imin=imin, imax=imax) ecs = convolve_map(ec, sm[i], cpix, imin=imin, imax=imax) cms = np.sum(ccs, axis=0) mms = np.sum(mcs, axis=0) ems = np.sum(ecs, axis=0) cmst += cms mmst += mms emst += ems # cts = 2.0 * (poisson_lnl(cms, cms) - poisson_lnl(cms, mms)) excess += cms - mms ts = 2.0 * (poisson_lnl(cmst, cmst) - poisson_lnl(cmst, mmst)) sigma = np.sqrt(ts) sigma[excess < 0] *= -1 emst /= np.max(emst) sigma_map = Map(sigma, skywcs) model_map = Map(mmst / emst, skywcs) data_map = Map(cmst / emst, skywcs) excess_map = Map(excess / emst, skywcs) o = { 'name': utils.join_strings([prefix, modelname]), 'file': None, 'sigma': sigma_map, 'model': model_map, 'data': data_map, 'excess': excess_map, 'config': config } fits_file = utils.format_filename(self.config['fileio']['workdir'], 'residmap.fits', prefix=[prefix, modelname]) if write_fits: fits_utils.write_maps( sigma_map, { 'DATA_MAP': data_map, 'MODEL_MAP': model_map, 'EXCESS_MAP': excess_map }, fits_file) o['file'] = os.path.basename(fits_file) if write_npy: np.save(os.path.splitext(fits_file)[0] + '.npy', o) return o
def run_flux_sensitivity(**kwargs): index = kwargs.get('index', 2.0) sedshape = kwargs.get('sedshape', 'PowerLaw') cutoff = kwargs.get('cutoff', 1e3) curvindex = kwargs.get('curvindex', 1.0) beta = kwargs.get('beta', 0.0) dmmass = kwargs.get('DMmass', 100.0) dmchannel = kwargs.get('DMchannel', 'bb') emin = kwargs.get('emin', 10**1.5) emax = kwargs.get('emax', 10**6.0) nbin = kwargs.get('nbin', 18) glon = kwargs.get('glon', 0.0) glat = kwargs.get('glat', 0.0) ltcube_filepath = kwargs.get('ltcube', None) galdiff_filepath = kwargs.get('galdiff', None) isodiff_filepath = kwargs.get('isodiff', None) galdiff_fit_filepath = kwargs.get('galdiff_fit', None) isodiff_fit_filepath = kwargs.get('isodiff_fit', None) wcs_npix = kwargs.get('wcs_npix', 40) wcs_cdelt = kwargs.get('wcs_cdelt', 0.5) wcs_proj = kwargs.get('wcs_proj', 'AIT') map_type = kwargs.get('map_type', None) spatial_model = kwargs.get('spatial_model', 'PointSource') spatial_size = kwargs.get('spatial_size', 1E-2) obs_time_yr = kwargs.get('obs_time_yr', None) event_class = kwargs.get('event_class', 'P8R2_SOURCE_V6') min_counts = kwargs.get('min_counts', 3.0) ts_thresh = kwargs.get('ts_thresh', 25.0) nside = kwargs.get('hpx_nside', 16) output = kwargs.get('output', None) event_types = [['FRONT', 'BACK']] if sedshape == 'PowerLaw': fn = spectrum.PowerLaw([1E-13, -index], scale=1E3) elif sedshape == 'PLSuperExpCutoff': fn = spectrum.PLSuperExpCutoff( [1E-13, -index, cutoff, curvindex], scale=1E3) elif sedshape == 'LogParabola': fn = spectrum.LogParabola([1E-13, -index, beta], scale=1E3) elif sedshape == 'DM': fn = spectrum.DMFitFunction([1E-26, dmmass], chan=dmchannel) log_ebins = np.linspace(np.log10(emin), np.log10(emax), nbin + 1) ebins = 10**log_ebins ectr = np.exp(utils.edge_to_center(np.log(ebins))) c = SkyCoord(glon, glat, unit='deg', frame='galactic') if ltcube_filepath is None: if obs_time_yr is None: raise Exception('No observation time defined.') ltc = LTCube.create_from_obs_time(obs_time_yr * 365 * 24 * 3600.) else: ltc = LTCube.create(ltcube_filepath) if obs_time_yr is not None: ltc._counts *= obs_time_yr * 365 * \ 24 * 3600. / (ltc.tstop - ltc.tstart) gdiff = skymap.Map.create_from_fits(galdiff_filepath) gdiff_fit = None if galdiff_fit_filepath is not None: gdiff_fit = skymap.Map.create_from_fits(galdiff_fit_filepath) if isodiff_filepath is None: isodiff = utils.resolve_file_path('iso_%s_v06.txt' % event_class, search_dirs=[os.path.join('$FERMIPY_ROOT', 'data'), '$FERMI_DIFFUSE_DIR']) isodiff = os.path.expandvars(isodiff) else: isodiff = isodiff_filepath iso = np.loadtxt(isodiff, unpack=True) iso_fit = None if isodiff_fit_filepath is not None: iso_fit = np.loadtxt(isodiff_fit_filepath, unpack=True) scalc = SensitivityCalc(gdiff, iso, ltc, ebins, event_class, event_types, gdiff_fit=gdiff_fit, iso_fit=iso_fit, spatial_model=spatial_model, spatial_size=spatial_size) # Compute Maps map_diff_flux = None map_diff_npred = None map_int_flux = None map_int_npred = None map_nstep = 500 if map_type == 'hpx': hpx = HPX(nside, True, 'GAL', ebins=ebins) map_diff_flux = HpxMap(np.zeros((nbin, hpx.npix)), hpx) map_diff_npred = HpxMap(np.zeros((nbin, hpx.npix)), hpx) map_skydir = map_diff_flux.hpx.get_sky_dirs() for i in range(0, len(map_skydir), map_nstep): s = slice(i, i + map_nstep) o = scalc.diff_flux_threshold( map_skydir[s], fn, ts_thresh, min_counts) map_diff_flux.data[:, s] = o['flux'].T map_diff_npred.data[:, s] = o['npred'].T hpx = HPX(nside, True, 'GAL') map_int_flux = HpxMap(np.zeros((hpx.npix)), hpx) map_int_npred = HpxMap(np.zeros((hpx.npix)), hpx) map_skydir = map_int_flux.hpx.get_sky_dirs() for i in range(0, len(map_skydir), map_nstep): s = slice(i, i + map_nstep) o = scalc.int_flux_threshold( map_skydir[s], fn, ts_thresh, min_counts) map_int_flux.data[s] = o['flux'] map_int_npred.data[s] = o['npred'] elif map_type == 'wcs': wcs_shape = [wcs_npix, wcs_npix] wcs_size = wcs_npix * wcs_npix map_diff_flux = Map.create( c, wcs_cdelt, wcs_shape, 'GAL', wcs_proj, ebins=ebins) map_diff_npred = Map.create( c, wcs_cdelt, wcs_shape, 'GAL', wcs_proj, ebins=ebins) map_skydir = map_diff_flux.get_pixel_skydirs() for i in range(0, len(map_skydir), map_nstep): idx = np.unravel_index( np.arange(i, min(i + map_nstep, wcs_size)), wcs_shape) s = (slice(None), idx[1], idx[0]) o = scalc.diff_flux_threshold( map_skydir[slice(i, i + map_nstep)], fn, ts_thresh, min_counts) map_diff_flux.data[s] = o['flux'].T map_diff_npred.data[s] = o['npred'].T map_int_flux = Map.create(c, wcs_cdelt, wcs_shape, 'GAL', wcs_proj) map_int_npred = Map.create(c, wcs_cdelt, wcs_shape, 'GAL', wcs_proj) map_skydir = map_int_flux.get_pixel_skydirs() for i in range(0, len(map_skydir), map_nstep): idx = np.unravel_index( np.arange(i, min(i + map_nstep, wcs_size)), wcs_shape) s = (idx[1], idx[0]) o = scalc.int_flux_threshold( map_skydir[slice(i, i + map_nstep)], fn, ts_thresh, min_counts) map_int_flux.data[s] = o['flux'] map_int_npred.data[s] = o['npred'] o = scalc.diff_flux_threshold(c, fn, ts_thresh, min_counts) cols = [Column(name='e_min', dtype='f8', data=scalc.ebins[:-1], unit='MeV'), Column(name='e_ref', dtype='f8', data=o['e_ref'], unit='MeV'), Column(name='e_max', dtype='f8', data=scalc.ebins[1:], unit='MeV'), Column(name='flux', dtype='f8', data=o[ 'flux'], unit='ph / (cm2 s)'), Column(name='eflux', dtype='f8', data=o[ 'eflux'], unit='MeV / (cm2 s)'), Column(name='dnde', dtype='f8', data=o['dnde'], unit='ph / (MeV cm2 s)'), Column(name='e2dnde', dtype='f8', data=o['e2dnde'], unit='MeV / (cm2 s)'), Column(name='npred', dtype='f8', data=o['npred'], unit='ph')] tab_diff = Table(cols) cols = [Column(name='index', dtype='f8'), Column(name='e_min', dtype='f8', unit='MeV'), Column(name='e_ref', dtype='f8', unit='MeV'), Column(name='e_max', dtype='f8', unit='MeV'), Column(name='flux', dtype='f8', unit='ph / (cm2 s)'), Column(name='eflux', dtype='f8', unit='MeV / (cm2 s)'), Column(name='dnde', dtype='f8', unit='ph / (MeV cm2 s)'), Column(name='e2dnde', dtype='f8', unit='MeV / (cm2 s)'), Column(name='npred', dtype='f8', unit='ph'), Column(name='ebin_e_min', dtype='f8', unit='MeV', shape=(len(ectr),)), Column(name='ebin_e_ref', dtype='f8', unit='MeV', shape=(len(ectr),)), Column(name='ebin_e_max', dtype='f8', unit='MeV', shape=(len(ectr),)), Column(name='ebin_flux', dtype='f8', unit='ph / (cm2 s)', shape=(len(ectr),)), Column(name='ebin_eflux', dtype='f8', unit='MeV / (cm2 s)', shape=(len(ectr),)), Column(name='ebin_dnde', dtype='f8', unit='ph / (MeV cm2 s)', shape=(len(ectr),)), Column(name='ebin_e2dnde', dtype='f8', unit='MeV / (cm2 s)', shape=(len(ectr),)), Column(name='ebin_npred', dtype='f8', unit='ph', shape=(len(ectr),))] cols_ebounds = [Column(name='E_MIN', dtype='f8', unit='MeV', data=ebins[:-1]), Column(name='E_MAX', dtype='f8', unit='MeV', data=ebins[1:]), ] tab_int = Table(cols) tab_ebounds = Table(cols_ebounds) index = np.linspace(1.0, 5.0, 4 * 4 + 1) for g in index: fn = spectrum.PowerLaw([1E-13, -g], scale=10**3.5) o = scalc.int_flux_threshold(c, fn, ts_thresh, 3.0) row = [g] for colname in tab_int.columns: if colname == 'index': continue if 'ebin' in colname: row += [o['bins'][colname.replace('ebin_', '')]] else: row += [o[colname]] tab_int.add_row(row) hdulist = fits.HDUList() hdulist.append(fits.table_to_hdu(tab_diff)) hdulist.append(fits.table_to_hdu(tab_int)) hdulist.append(fits.table_to_hdu(tab_ebounds)) hdulist[1].name = 'DIFF_FLUX' hdulist[2].name = 'INT_FLUX' hdulist[3].name = 'EBOUNDS' if map_type is not None: hdu = map_diff_flux.create_image_hdu() hdu.name = 'MAP_DIFF_FLUX' hdulist.append(hdu) hdu = map_diff_npred.create_image_hdu() hdu.name = 'MAP_DIFF_NPRED' hdulist.append(hdu) hdu = map_int_flux.create_image_hdu() hdu.name = 'MAP_INT_FLUX' hdulist.append(hdu) hdu = map_int_npred.create_image_hdu() hdu.name = 'MAP_INT_NPRED' hdulist.append(hdu) hdulist.writeto(output, overwrite=True)
def setup(self, force_create_srcmap=False, overwrite=False, **kwargs): """ Same as GTBinnedAnalysis.setup function, which does not create srcmap, running the setup for each component Parameters ---------- overwrite : bool Run all pre-processing steps even if the output file of that step is present in the working directory. """ for c in self.components: loglevel = kwargs.get('loglevel', c.loglevel) c.logger.log(loglevel, 'Running setup for component %s', c.name) use_external_srcmap = c.config['gtlike']['use_external_srcmap'] # Run data selection if not use_external_srcmap: c._select_data(overwrite=overwrite, **kwargs) # Create LT Cube if c._ext_ltcube is not None: c.logger.log(loglevel, 'Using external LT cube.') else: c._create_ltcube(overwrite=overwrite, **kwargs) c.logger.debug('Loading LT Cube %s', c.files['ltcube']) c._ltc = LTCube.create(c.files['ltcube']) # Extract tmin, tmax from LT cube c._tmin = c._ltc.tstart c._tmax = c._ltc.tstop c.logger.debug('Creating PSF model') c._psf = irfs.PSFModel.create(c.roi.skydir, c._ltc, c.config['gtlike']['irfs'], c.config['selection']['evtype'], c.energies) # Bin data and create exposure cube if not use_external_srcmap: c._bin_data(overwrite=overwrite, **kwargs) c._create_expcube(overwrite=overwrite, **kwargs) c._bexp = Map.create_from_fits(c.files['bexpmap']) # Make spatial maps for extended sources for s in c.roi.sources: if s.diffuse: continue if not s.extended: continue c.make_template(s, c.config['file_suffix']) # Write ROI XML c.roi.write_xml(c.files['srcmdl']) # Create source maps file if force_create_srcmap: if not use_external_srcmap: c._create_srcmaps(overwrite=overwrite) if not c.config['data']['cacheft1'] and os.path.isfile( c.files['ft1']): c.logger.debug('Deleting FT1 file.') os.remove(c.files['ft1']) c.logger.log(loglevel, 'Finished setup for component %s', c.name) return