Example #1
0
def test_wcsndmap_read_write(tmp_path, npix, binsz, frame, proj, skydir, axes):
    geom = WcsGeom.create(npix=npix,
                          binsz=binsz,
                          proj=proj,
                          frame=frame,
                          axes=axes)
    path = tmp_path / "tmp.fits"

    m0 = WcsNDMap(geom)
    fill_poisson(m0, mu=0.5)
    m0.write(path, overwrite=True)
    m1 = WcsNDMap.read(path)
    m2 = Map.read(path)
    m3 = Map.read(path, map_type="wcs")
    assert_allclose(m0.data, m1.data)
    assert_allclose(m0.data, m2.data)
    assert_allclose(m0.data, m3.data)

    m0.write(path, sparse=True, overwrite=True)
    m1 = WcsNDMap.read(path)
    m2 = Map.read(path)
    m3 = Map.read(path, map_type="wcs")
    assert_allclose(m0.data, m1.data)
    assert_allclose(m0.data, m2.data)
    assert_allclose(m0.data, m3.data)

    # Specify alternate HDU name for IMAGE and BANDS table
    m0.write(path, hdu="IMAGE", hdu_bands="TEST", overwrite=True)
    m1 = WcsNDMap.read(path)
    m2 = Map.read(path)
    m3 = Map.read(path, map_type="wcs")
Example #2
0
def test_wcsndmap_read_write(tmpdir, npix, binsz, coordsys, proj, skydir,
                             axes):
    geom = WcsGeom.create(npix=npix,
                          binsz=binsz,
                          proj=proj,
                          coordsys=coordsys,
                          axes=axes)
    filename = str(tmpdir / "map.fits")

    m0 = WcsNDMap(geom)
    fill_poisson(m0, mu=0.5)
    m0.write(filename, overwrite=True)
    m1 = WcsNDMap.read(filename)
    m2 = Map.read(filename)
    m3 = Map.read(filename, map_type="wcs")
    assert_allclose(m0.data, m1.data)
    assert_allclose(m0.data, m2.data)
    assert_allclose(m0.data, m3.data)

    m0.write(filename, sparse=True, overwrite=True)
    m1 = WcsNDMap.read(filename)
    m2 = Map.read(filename)
    m3 = Map.read(filename, map_type="wcs")
    assert_allclose(m0.data, m1.data)
    assert_allclose(m0.data, m2.data)
    assert_allclose(m0.data, m3.data)

    # Specify alternate HDU name for IMAGE and BANDS table
    m0.write(filename, hdu="IMAGE", hdu_bands="TEST", overwrite=True)
    m1 = WcsNDMap.read(filename)
    m2 = Map.read(filename)
    m3 = Map.read(filename, map_type="wcs")
Example #3
0
def images():
    """Load some `counts`, `counts_off`, `acceptance_on`, `acceptance_off" images"""
    filename = "$GAMMAPY_DATA/tests/unbundled/hess/survey/hess_survey_snippet.fits.gz"
    return {
        "counts": WcsNDMap.read(filename, hdu="ON"),
        "counts_off": WcsNDMap.read(filename, hdu="OFF"),
        "acceptance": WcsNDMap.read(filename, hdu="ONEXPOSURE"),
        "acceptance_off": WcsNDMap.read(filename, hdu="OFFEXPOSURE"),
        "exposure": WcsNDMap.read(filename, hdu="EXPGAMMAMAP"),
    }
Example #4
0
def sky_image_plot(which):
    filename = f"results/maps/{which}.fits.gz"
    map = WcsNDMap.read(filename)
    fig, ax, im = map.plot(stretch="sqrt")

    filename = f"results/maps/{which}.png"
    log.info(f"Writing {filename}")
    fig.savefig(filename)
Example #5
0
def sky_image_plot(which):
    import matplotlib.pyplot as plt

    # TODO: smooth and plot counts image
    # TODO: overplot on and off regions

    filename = f"results/skyimage/{which}.fits.gz"
    map = WcsNDMap.read(filename)
    fig, ax, im = map.plot(stretch="sqrt")

    filename = f"results/skyimage/{which}.png"
    log.info(f"Writing {filename}")
    fig.savefig(filename)
Example #6
0
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','avgspec','avgspec_ebl','lcbin', 'lcmonthly'],
                            help='Analysis state')
    parser.add_argument('-i', required=False, default = 0, 
                        help='Set local or scratch calculation', type=int)
    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('--addnewsrcs', default = 0,  
                        help='Search for and add new sources and create residual map',
                        type=int)
    parser.add_argument('--reloadfit', default = 0,  
                        help='Reload ROI from avgspec xml file',
                        type=int)
    parser.add_argument('--relocalize', default = 0,  
                        help='Relocalize central source',
                        type=int)
    parser.add_argument('--createsed', default = 0,  
                        help='Create SED from best fit model',
                        type=int)
    parser.add_argument('--forcespec', default = 0,  
                        help='Recompute model parameters',
                        type=int)
    parser.add_argument('--freezesupexp', default = 0,  
                        help='freeze super exponential index parameters',
                        type=int)
    parser.add_argument('--restorecatspec', default = 0,  
                        help='Restore intitial catalog spectrum',
                        type=int)
    parser.add_argument('--sethardexpcutoff', default = 0,  
                        help='Manually change parameters of PL with SuperExpCutoff',
                        type=int)
    parser.add_argument('--pivotE_free', default = 0,  
                        help='let the pivot energy free during fit if spectrum is changed',
                        type=int)
    parser.add_argument('--forcepl', default = 0,  
                        help='Force the target source to have power-law shape',
                        type=int)
    parser.add_argument('--profile2d', default = 0,  
                        help='Compute 2D likelihood surface for PL index and normalization',
                        type=int)
    parser.add_argument('--srcprob', default = 0,  
                        help='Calculate the source probability for the photons,' \
                            ' only works when no sub orbit time scales are used',
                        type=int)
    parser.add_argument('--psf', default = 0,  
                        help='Calculate the psf',
                        type=int)
    parser.add_argument('--make_plots', default = 0, type=int,   
                        help='Create plots',
                        )
    parser.add_argument('--drm', default = 0,  
                        help='Calculate the detector response matrix',
                        type=int)
    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')

    if args.make_plots:
        init_matplotlib_backend()

    if args.reloadfit:
        files = [fn for fn in glob(fit_config['avgspec']) if fn.find('.xml') > 0 or fn.find('.npy') > 0]
        if len(files):
            utils.copy2scratch(files, gta.workdir)
        else:
            logging.error("No files found in {0:s}".format(fit_config['avgspec']))
            args.reloadfit = False

    if args.state == 'lcbin':
        pps = PreparePointSource(config,logging={'verbosity' : 3})
        pps.setup()
        pps._bin_data_lc(overwrite = args.overwrite)
        pps._compute_lc_exp(overwrite = args.overwrite,
                        specin = args.specin)
        return pps

    elif args.state == 'setup':
        try:
            gta.setup()
        except RuntimeError as e:
            logging.error("setup ended with runtime error:\n{0}.".format(e))

        if args.psf:
            logging.info("Running psf")
            gta.compute_psf(overwrite = True)

        if args.drm:
            logging.info("Running drm")
            gta.compute_drm(overwrite = True)

        return None, gta, fit_config


    elif args.state.find('avgspec') >= 0:
        gta.setup()

        if args.psf:
            logging.info("Running psf")
            gta.compute_psf(overwrite = True)

        if args.drm:
            logging.info("Running drm")
            gta.compute_drm(overwrite = True)

        if not type(config['selection']['target']) == str:
            # target name not given
            # take closest source to ROI center if separation 
            # is less then 0.1 degree
            logging.warning("Target name is {0}".format(config['selection']['target']))
            sep = gta.roi.sources[0]['offset'] 
            logging.warning("Source closets to ROI center is {0:.3f} degree away".format(sep))
            if sep < 0.1:
                config['selection']['target'] = gta.roi.sources[0]['name']
                logging.info("Set target to {0:s}".format(config['selection']['target']))
            else: # add source at center of ROI
                csrc = SkyCoord(ra = config['selection']['ra'],
                        dec = config['selection']['dec'], frame = 'fk5', unit = 'degree')
                if csrc.dec.value < 0.:
                    sign = '-'
                else:
                    sign = '+'
                newname = 'j{0:02.0f}{1:02.0f}{2:s}{3:02.0f}{4:02.0f}'.format(
                                        csrc.ra.hms.h, csrc.ra.hms.m, sign, 
                                        np.abs(csrc.dec.dms.d), np.abs(csrc.dec.dms.m))
                gta.add_source(newname,{
                                'ra' : config['selection']['ra'], 'dec' : config['selection']['dec'],
                                'SpectrumType' : 'PowerLaw', 'Index' : fit_config['new_src_pl_index'],
                                'Scale' : fit_config['pivotE'] if 'pivotE' in fit_config.keys() else 1000.,
                                'Prefactor' : 1e-11,
                                'SpatialModel' : 'PointSource' })
                config['selection']['target'] = newname
                logging.info("Set target to {0:s}".format(config['selection']['target']))

        if args.reloadfit:
            # save old spectrum
            spec_cat = gta.roi.get_source_by_name(config['selection']['target'])
            try:
                gta.load_roi(args.state) # reload the average spectral fit
            except:
                logging.error("Could not reload fit. Continuing anyway.")
        logging.info('Running fermipy optimize and fit')
        # gives "failed to create spline" in get_parameter_limits function

        if 'source_spec' in fit_config.keys():
            m = gta.roi.get_source_by_name(config['selection']['target'])
            if not m['SpectrumType'] == fit_config['source_spec'] or args.forcespec:
                if fit_config['source_spec'] == 'PowerLaw':
                    gta, _ = set_src_spec_pl(gta, gta.get_source_name(config['selection']['target']), 
                                             fit_config['pivotE'] if 'pivotE' in fit_config.keys() else None,
                                             e0_free = args.pivotE_free)
                elif fit_config['source_spec'] == 'PLSuperExpCutoff':
                    gta, _ = set_src_spec_plexpcut(gta, gta.get_source_name(config['selection']['target']),
                                                   fit_config['pivotE'] if 'pivotE' in fit_config.keys() else None,
                                                   e0_free = args.pivotE_free)
                #elif fit_config['source_spec'] == 'LogParabola':
                    #gta = set_src_spec_lp(gta, gta.get_source_name(config['selection']['target']))
                else:
                    logging.warning("Spectrum {0:s} not supported, spectrum not changed".format(fit_config['source_spec']))

        # restore spectrum from catalog
        if args.restorecatspec:
            #for k in ['alpha','Index','Index1']:
                #if k in spec_cat.spectral_pars.keys():
                    #spec_cat.spectral_pars[k]['value'] -= 0.5
            #spec_cat.spectral_pars['Eb']['free'] = True
            #spec_cat.spectral_pars['Eb']['value'] = 2000.
            #spec_cat.spectral_pars['alpha']['value'] = 1.8
            #print spec_cat.spectral_pars
            gta.set_source_spectrum(config['selection']['target'],
                spectrum_type = spec_cat['SpectrumType'],
                spectrum_pars= spec_cat.spectral_pars)
            logging.info("restored catalog spectrum")

        # for some sources modeled with PL with super exponential cutoff I 
        # have to do this to get a nice SED, but not for 3C454.3!
        if gta.roi.get_source_by_name(config['selection']['target'])['SpectrumType'] ==\
            'PLSuperExpCutoff' and args.sethardexpcutoff :
            pars = {}
            old_spec_pars = copy.deepcopy(gta.roi.get_source_by_name(config['selection']['target']))
            for k in ['Prefactor','Scale','Index1','Index2','Cutoff']:
                pars[k] = old_spec_pars.spectral_pars[k]
            if config['selection']['target'] == '3C454.3':
                # values from Romoli et al 2017
                pars['Prefactor']['value'] = 4.7
                pars['Index1']['value'] = 1.87
                pars['Index2']['value'] = 0.4
                pars['Cutoff']['value'] = 1100.
                pars['Cutoff']['scale'] = 1.
                pars['Cutoff']['min'] = 100.
                pars['Cutoff']['max'] = 10000.
            else:
                pars['Index1']['value'] = 1.8
                pars['Index2']['value'] = 1.
                pars['Cutoff']['value'] = 5e4
            gta.set_source_spectrum(config['selection']['target'],
            #    spectrum_type = 'PLSuperExpCutoff2',
                spectrum_type = 'PLSuperExpCutoff',
                spectrum_pars= pars)
            logging.info("changed spectral parameters to {0}".format(
                gta.roi.get_source_by_name(config['selection']['target']).spectral_pars))
        else:
            old_spec_pars = None

        if args.forcepl and not \
            gta.roi.get_source_by_name(config['selection']['target'])['SpectrumType'] == 'PowerLaw':

            gta, _ = set_src_spec_pl(gta, gta.get_source_name(config['selection']['target']))
            args.state += "_pl"

        if args.state.find('ebl') >= 0:
            gta = fa.utils.add_ebl_atten(gta,config['selection']['target'],fit_config['z'])
            
        gta = set_free_pars_avg(gta, fit_config, freezesupexp = args.freezesupexp)
        f,gta = fit_with_retries(gta, fit_config, config['selection']['target'], 
                                    alt_spec_pars = old_spec_pars)

        logging.debug(f)
        try:
            get_best_fit_covar(gta, config['selection']['target'], prefix = args.state)
        except IndexError:
            logging.error("Covariance matrix calculation failed")

        #relocalize central source and refit
        if args.relocalize and type(config['selection']['target']) == str:
            loc = gta.localize(config['selection']['target'], make_plots=args.make_plots,
                                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()
            #f,gta = fit_with_retries(gta, fit_config, config['selection']['target'])

        gta.print_roi()
        gta.write_roi(args.state)

    elif 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.)

    model = {'Scale': 1000., 'Index' : fit_config['new_src_pl_index'], 'SpatialModel' : 'PointSource'}
    if args.addnewsrcs:
        gta.load_roi(args.state) # reload the average spectral fit

        max_sqrt_ts = 1000.
        irun = 0
        # define the test source
        #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(args.state,model=model, 
                write_fits = True, write_npy = True, make_plots = args.make_plots)
            # get the skydirs
            #coords = ts_maps['sqrt_ts'].get_pixel_skydirs()
            coords = ts_maps['sqrt_ts'].geom.get_coord()
            if ts_maps['sqrt_ts'].geom.coordsys == 'CEL':
                frame = 'fk5'
            elif ts_maps['sqrt_ts'].geom.coordsys == 'GAL':
                frame = 'galactic'
            c = SkyCoord(coords[0], coords[1], unit = 'deg', 
                frame = frame)

            #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_map = WcsNDMap.read(path.join(gta.workdir,ts_maps['file']),hdu = 'SQRT_TS_MAP')
            n_map = WcsNDMap.read(path.join(gta.workdir,ts_maps['file']),hdu = 'N_MAP')

            sqrt_ts = sqrt_ts_map.data
            amplitudes = n_map.data
            
            # get the angular separation from RoI center
            sep = gta.roi.skydir.separation(c)
            # 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], c.ra[m][idx].value, c.dec[m][idx].value))
            # add a new source
            csrc = SkyCoord(ra = c.ra[m][idx], dec = c.dec[m][idx], frame = 'fk5')
            if csrc.dec.value < 0.:
                sign = '-'
            else:
                sign = '+'
            newname = 'j{0:02.0f}{1:02.0f}{2:s}{3:02.0f}{4:02.0f}'.format(
                                        csrc.ra.hms.h, csrc.ra.hms.m, sign, 
                                        np.abs(csrc.dec.dms.d), np.abs(csrc.dec.dms.m))
            gta.add_source(newname,{
                                'ra' : c.ra[m][idx].value, 'dec' : c.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

        # if new sources where added, save output
        if irun > 0:
            gta.print_roi()
#            gta = reset_diff_filenames(gta)
            # refit the model with new sources present
            gta = set_free_pars_avg(gta, fit_config)
            f,gta = fit_with_retries(gta, fit_config, config['selection']['target'])
            gta.write_roi(args.state)

    else:
        ts_maps = gta.tsmap(args.state,model=model, 
            write_fits = True, write_npy = True, make_plots = args.make_plots)
    try:
        resid_maps = gta.residmap(args.state,model=model, make_plots=args.make_plots, write_fits = True, write_npy = True)
    except:
        logging.error("Residual map computation and plotting failed")

    if args.profile2d:
        compute_profile2d(gta, config['selection']['target'], prefix = args.state, 
            sigma = 5., xsteps = 30, ysteps = 31)

    if args.createsed:
        if fit_config.get('force_free_index', False):
            gta.free_index(config['selection']['target'], free = False)
            gta.free_index(config['selection']['target'], free = True)
        gta.load_roi(args.state) # reload the average spectral fit
        logging.info('Running sed for {0[target]:s}'.format(config['selection']))
        sed = gta.sed(config['selection']['target'],
                        prefix = args.state,
                        #outfile = 'sed.fits',
                        #free_radius =  #sed_config['free_radius'],
                        #free_background= #sed_config['free_background'],
                        #free_pars = fa.allnorm,
                        make_plots = args.make_plots,
                        #cov_scale = sed_config['cov_scale'],
                        #use_local_index = sed_config['use_local_index'],
                        #use_local_index = True, # sed_config['use_local_index'],
                        #bin_index = sed_config['bin_index']
                        )
        logging.info("SED covariance: {0}".format(sed['param_covariance']))

        # generate additional SEDs
        for src in fit_config.get('additional_seds', []):
            sed = gta.sed(src,
                          prefix = args.state,
                          #outfile = 'sed.fits',
                          #free_radius =  #sed_config['free_radius'],
                          #free_background= #sed_config['free_background'],
                          #free_pars = fa.allnorm,
                          make_plots = args.make_plots,
                          #cov_scale = sed_config['cov_scale'],
                          #use_local_index = sed_config['use_local_index'],
                          #use_local_index = True, # sed_config['use_local_index'],
                          #bin_index = sed_config['bin_index']
                          )

    if args.srcprob:
        logging.info("Running srcprob with srcmdl {0:s}".format(args.state))
        gta.compute_srcprob(xmlfile=args.state, overwrite = True)

    return f, gta, fit_config