def test_save_model_pha_ascii(clean_astro_ui, tmp_path): """Can we write out data for save_model? DataPHA and ASCII""" ui.load_arrays(1, [1, 2], [5, 10], ui.DataPHA) # we need a response egrid = np.asarray([0.1, 0.2, 0.4]) elo = egrid[:-1] ehi = egrid[1:] rmf = create_delta_rmf(elo, ehi, e_min=elo, e_max=ehi) ui.set_rmf(rmf) yarf = np.asarray([10, 20]) arf = create_arf(elo, ehi, yarf) ui.set_arf(arf) ui.set_source(ui.const1d.cmdl) cmdl.c0 = 2 out = tmp_path / 'model.dat' ui.save_model(str(out), ascii=True) cts = out.read_text() check_output(cts, ['XLO', 'XHI', 'MODEL'], [[0.1, 0.2, 20], [0.2, 0.4, 40]])
def test_save_model_pha_fits(clean_astro_ui, tmp_path): """Can we write out data for save_model? DataPHA and FITS """ from sherpa.astro.io import read_table_blocks ui.load_arrays(1, [1, 2], [5, 10], ui.DataPHA) # we need a response egrid = np.asarray([0.1, 0.2, 0.4]) elo = egrid[:-1] ehi = egrid[1:] rmf = create_delta_rmf(elo, ehi, e_min=elo, e_max=ehi) ui.set_rmf(rmf) yarf = np.asarray([10, 20]) arf = create_arf(elo, ehi, yarf) ui.set_arf(arf) ui.set_source(ui.const1d.cmdl) cmdl.c0 = 2 out = tmp_path / 'model.dat' outfile = str(out) ui.save_model(outfile) ans = read_table_blocks(outfile) blocks = ans[1] assert len(blocks) == 2 check_table(blocks[2], { 'XLO': [0.1, 0.2], 'XHI': [0.2, 0.4], 'MODEL': [20, 40] })
def image_model_sherpa(exposure, psf, sources, model_image, overwrite): """Compute source model image with Sherpa. Inputs: * Source list (JSON file) * PSF (JSON file) * Exposure image (FITS file) Outputs: * Source model flux image (FITS file) * Source model excess image (FITS file) """ import sherpa.astro.ui as sau from ..image.models.psf import Sherpa from ..image.models.utils import read_json log.info('Reading exposure: {0}'.format(exposure)) # Note: We don't really need the exposure as data, # but this is a simple way to init the dataspace to the correct shape sau.load_data(exposure) sau.load_table_model('exposure', exposure) log.info('Reading PSF: {0}'.format(psf)) Sherpa(psf).set() log.info('Reading sources: {0}'.format(sources)) read_json(sources, sau.set_source) name = sau.get_source().name full_model = 'exposure * psf({})'.format(name) sau.set_full_model(full_model) log.info('Computing and writing model_image: {0}'.format(model_image)) sau.save_model(model_image, clobber=overwrite) sau.clean() sau.delete_psf()
def sherpa_model_image(exposure, psf, sources, model_image, overwrite): """Compute source model image with Sherpa. Inputs: * Source list (JSON file) * PSF (JSON file) * Exposure image (FITS file) Outputs: * Source model flux image (FITS file) * Source model excess image (FITS file) """ import logging logging.basicConfig(level=logging.DEBUG, format='%(levelname)s - %(message)s') import sherpa.astro.ui as sau # @UnresolvedImport from ..morphology.psf import Sherpa from ..morphology.utils import read_json logging.info('Reading exposure: {0}'.format(exposure)) # Note: We don't really need the exposure as data, # but this is a simple way to init the dataspace to the correct shape sau.load_data(exposure) sau.load_table_model('exposure', exposure) logging.info('Reading PSF: {0}'.format(psf)) Sherpa(psf).set() logging.info('Reading sources: {0}'.format(sources)) read_json(sources, sau.set_source) name = sau.get_source().name full_model = 'exposure * psf({})'.format(name) sau.set_full_model(full_model) logging.info('Computing and writing model_image: {0}'.format(model_image)) sau.save_model(model_image, clobber=overwrite)
# Results are automatically printed to the screen sau.fit() sau.covar() # Sherpa uses fwhm instead of sigma as extension parameter ... need to convert # http://cxc.harvard.edu/sherpa/ahelp/gauss2d.html fwhm_to_sigma = 1. / np.sqrt(8 * np.log(2)) cov = sau.get_covar_results() sigma = fwhm_to_sigma * cov.parvals[0] sigma_err = fwhm_to_sigma * cov.parmaxes[0] print('sigma: {0} +- {1}'.format(sigma, sigma_err)) # Compute correlation coefficient for sigma and norm c = cov.extra_output c_norm = c[3, 3] c_sigma = fwhm_to_sigma**2 * c[0, 0] c_norm_sigma = fwhm_to_sigma * c[0, 3] corr_norm_sigma = c_norm_sigma / np.sqrt(c_norm * c_sigma) print('corr_norm_sigma: {0}'.format(corr_norm_sigma)) # Save model excess image sau.save_model('model_sherpa.fits.gz', clobber=True) # Compute TS L1 = sau.calc_stat() sau.set_source('const2d.background') sau.fit() L0 = sau.calc_stat() TS = 2 * (L0 - L1) print('TS: {:.5f}'.format(TS))
import sherpa.astro.ui as sau # Define width of the source and the PSF sigma_psf, sigma_source = 3, 4 # for relation of sigma and fwhm see # http://cxc.harvard.edu/sherpa/ahelp/gauss2d.html sigma_to_fwhm = np.sqrt(8 * np.log(2)) # ~ 2.35 sigma = np.sqrt(sigma_psf ** 2 + sigma_source ** 2) fwhm = sigma_to_fwhm * sigma # Seed the random number generator to make the output reproducible np.random.seed(0) sau.dataspace2d((200, 200)) sau.set_source('normgauss2d.source + const2d.background') sau.set_par('source.xpos', 100) sau.set_par('source.ypos', 100) sau.set_par('source.ampl', 1e3) sau.set_par('source.fwhm', fwhm) sau.set_par('background.c0', 1) sau.fake() sau.save_model('model.fits.gz', clobber=True) sau.save_data('counts.fits.gz', clobber=True) sau.set_source('source') sau.save_model('source.fits.gz', clobber=True) sau.set_source('background') sau.save_model('background.fits.gz', clobber=True)
sau.fit() sau.covar() # Sherpa uses fwhm instead of sigma as extension parameter ... need to convert # http://cxc.harvard.edu/sherpa/ahelp/gauss2d.html fwhm_to_sigma = 1. / np.sqrt(8 * np.log(2)) cov = sau.get_covar_results() sigma = fwhm_to_sigma * cov.parvals[0] sigma_err = fwhm_to_sigma * cov.parmaxes[0] print('sigma: {0} +- {1}'.format(sigma, sigma_err)) # Compute correlation coefficient for sigma and norm c = cov.extra_output c_norm = c[3, 3] c_sigma = fwhm_to_sigma ** 2 * c[0, 0] c_norm_sigma = fwhm_to_sigma * c[0, 3] corr_norm_sigma = c_norm_sigma / np.sqrt(c_norm * c_sigma) print('corr_norm_sigma: {0}'.format(corr_norm_sigma)) # Save model excess image sau.save_model('model_sherpa.fits.gz', clobber=True) # Compute TS L1 = sau.calc_stat() sau.set_source('const2d.background') sau.fit() L0 = sau.calc_stat() TS = 2 * (L0 - L1) print('TS: {:.5f}'.format(TS))
# Results are automatically printed to the screen sau.fit() sau.covar() # Sherpa uses fwhm instead of sigma as extension parameter ... need to convert # http://cxc.harvard.edu/sherpa/ahelp/gauss2d.html fwhm_to_sigma = 1.0 / np.sqrt(8 * np.log(2)) cov = sau.get_covar_results() sigma = fwhm_to_sigma * cov.parvals[0] sigma_err = fwhm_to_sigma * cov.parmaxes[0] print("sigma: {0} +- {1}".format(sigma, sigma_err)) # Compute correlation coefficient for sigma and norm c = cov.extra_output c_norm = c[3, 3] c_sigma = fwhm_to_sigma ** 2 * c[0, 0] c_norm_sigma = fwhm_to_sigma * c[0, 3] corr_norm_sigma = c_norm_sigma / np.sqrt(c_norm * c_sigma) print("corr_norm_sigma: {0}".format(corr_norm_sigma)) # Save model excess image sau.save_model("model_sherpa.fits.gz", clobber=True) # Compute TS L1 = sau.calc_stat() sau.set_source("const2d.background") sau.fit() L0 = sau.calc_stat() TS = 2 * (L0 - L1) print("TS: {:.5f}".format(TS))
import sherpa.astro.ui as sau # Define width of the source and the PSF sigma_psf, sigma_source = 3, 4 # for relation of sigma and fwhm see # http://cxc.harvard.edu/sherpa/ahelp/gauss2d.html sigma_to_fwhm = np.sqrt(8 * np.log(2)) # ~ 2.35 sigma = np.sqrt(sigma_psf**2 + sigma_source**2) fwhm = sigma_to_fwhm * sigma # Seed the random number generator to make the output reproducible np.random.seed(0) sau.dataspace2d((200, 200)) sau.set_source('normgauss2d.source + const2d.background') sau.set_par('source.xpos', 100) sau.set_par('source.ypos', 100) sau.set_par('source.ampl', 1e3) sau.set_par('source.fwhm', fwhm) sau.set_par('background.c0', 1) sau.fake() sau.save_model('model.fits.gz', clobber=True) sau.save_data('counts.fits.gz', clobber=True) sau.set_source('source') sau.save_model('source.fits.gz', clobber=True) sau.set_source('background') sau.save_model('background.fits.gz', clobber=True)