'''fits outputs for imag
Created on 21 february 2019
@author: Catalano Camille, APC
'''
from astropy.io import fits
import astropy.table as astt
from common.io import fits_tools
from common.instru.array_convention import yzegp_to_ijdet_array
[docs]def save_sky_images(sky_images, file_path, tstart, tstop, energy_ranges, creator='IMAG?', proc_id="01"):
"""
save images in a fits file ECL-SKY-IMA
use common keywords
filename is 'ECL-SKY-IMA-' + proc_id + '.fits'
file contains:
- Intensity: cleaned sky count image
- Variance: cleaned sky variance image
- SNR: cleaned sky signal to noise ratio image
- Exposure: initial sky Exposure image
- Model: Added sources model images (for debug)
- Initial Sky: Initial sky intensity image (for debug)
save also the models images in a fits file: see save_models
:param sky_images: list of sky images and models
:type sky_images: list(SkyImages)
:param file_path: PATH to the directory where to write the file
:type file_path: string
:param tstart: start time of the observation in s from mjdref
:type tstart: float
:param tstop: end time of the observation in s from mjdref
:type tstop: float
:param energy_ranges: energy ranges (in PI) of the images [[low_energy, high_energy],[]]
:type energy_ranges: [[int, int]]
:param creator: program that has generated the file. Default='IMAG?'
:type creator: string
:param proc_id: id of the process. Default="01".
:type proc_id: string
"""
# construction of the fits file
prihdr = fits.Header()
prihdu = fits.PrimaryHDU(header=prihdr)
hdu_list = [prihdu]
hdu_images = []
grp_table = astt.Table([[],[],[],[],[],[],[],[],[],[],[]],names=('member_xtension', 'member_name', 'member_version', 'member_position', 'member_location', 'member_uri_type', 'imatype', 'chanmin', 'chanmax', 'e_min', 'e_max'), dtype=('S20', 'S20', 'u1', 'u1', 'S20', 'S20', 'S20', 'f4', 'f4', 'f4', 'f4'))
for image_idx in range(len(sky_images)):
chanmin = energy_ranges[image_idx][0]
chanmax = energy_ranges[image_idx][1]
e_min = chanmin
e_max = chanmax
grp_table.add_row(['IMAGE ', 'Intensity', '1', image_idx*5+2, '', '', 'intensity', chanmin, chanmax, e_min, e_max])
grp_table.add_row(['IMAGE ', 'Variance', '1', image_idx*5+3, '', '', 'variance', chanmin, chanmax, e_min, e_max])
grp_table.add_row(['IMAGE ', 'SNR', '1', image_idx*5+4, '', '', 'SNR', chanmin, chanmax, e_min, e_max])
grp_table.add_row(['IMAGE ', 'Exposure', '1', image_idx*5+5, '', '', 'Exposure', chanmin, chanmax, e_min, e_max])
grp_table.add_row(['IMAGE ', 'Model', '1', image_idx*5+6, '', '', 'Model', chanmin, chanmax, e_min, e_max])
hdu_count = fits.ImageHDU(sky_images[image_idx].cleaned_sky_count)
hdu_var = fits.ImageHDU(sky_images[image_idx].cleaned_sky_var)
hdu_snr = fits.ImageHDU(sky_images[image_idx].cleaned_sky_snr)
hdu_exp = fits.ImageHDU(sky_images[image_idx].exposure)
hdu_mod = fits.ImageHDU(sky_images[image_idx].model_image)
fits_tools.common_keyword(hdu_count, tstart, tstop, creator, 1.0, proc_id)
fits_tools.energy_keywords(hdu_count, chanmin, chanmax, e_min, e_max)
hdu_count.header.extend(sky_images[image_idx].wcs.to_header().cards)
fits_tools.common_keyword(hdu_var, tstart, tstop, creator, 1.0, proc_id)
fits_tools.energy_keywords(hdu_var, chanmin, chanmax, e_min, e_max)
hdu_var.header.extend(sky_images[image_idx].wcs.to_header().cards)
fits_tools.common_keyword(hdu_snr, tstart, tstop, creator, 1.0, proc_id)
fits_tools.energy_keywords(hdu_snr, chanmin, chanmax, e_min, e_max)
hdu_snr.header.extend(sky_images[image_idx].wcs.to_header().cards)
fits_tools.common_keyword(hdu_exp, tstart, tstop, creator, 1.0, proc_id)
fits_tools.energy_keywords(hdu_exp, chanmin, chanmax, e_min, e_max)
hdu_exp.header.extend(sky_images[image_idx].wcs.to_header().cards)
fits_tools.common_keyword(hdu_mod, tstart, tstop, creator, 1.0, proc_id)
fits_tools.energy_keywords(hdu_mod, chanmin, chanmax, e_min, e_max)
hdu_mod.header.extend(sky_images[image_idx].wcs.to_header().cards)
hdu_count, hdu_var, hdu_snr, hdu_exp, hdu_mod = update_images_headers(hdu_count, hdu_var, hdu_snr, hdu_exp, hdu_mod, sky_images[image_idx].time_exp_mn)
hdu_images.extend([hdu_count, hdu_var, hdu_snr, hdu_exp, hdu_mod])
hdu_grp = fits.table_to_hdu(grp_table)
hdu_grp.header['comment'] = 'ECLAIRs reconstructed and cleaned individual Sky Images'
fits_tools.common_keyword(hdu_grp, tstart, tstop, creator, 1.0, proc_id)
fits_tools.grouphdu_keyword(hdu_grp, 'ECL-SKY-IMA-IDX')
hdu_list.append(hdu_grp)
hdu_list.extend(hdu_images)
thdulist = fits.HDUList(hdu_list)
thdulist.writeto(file_path + '/ECL-SKY-IMA-' + proc_id + '.fits', overwrite=True, checksum=True)
save_src_models(sky_images, file_path, tstart, tstop, energy_ranges, creator, proc_id)
[docs]def save_src_models(sky_images, file_path, tstart, tstop, energy_ranges, creator, proc_id="01"):
"""save models independant shadowgrams in fits file ECL-DET-MOD
use common keywords
filename is 'ECL-DET-MOD-' + proc_id + '.fits'
file contains: for each source model, the shadowgram of the source
:param sky_images: list of sky images and models
:type sky_images: list(SkyImages)
:param file_path: PATH to the directory where to write the file
:type file_path: string
:param tstart: start time of the observation in s from mjdref
:type tstart: float
:param tstop: end time of the observation in s from mjdref
:type tstop: float
:param energy_ranges: energy ranges (in PI) of the images [[low_energy, high_energy],[]]
:type energy_ranges: [[int, int]]
:param creator: program that has generated the file.
:type creator: string
:param proc_id: id of the process. Default="01".
:type proc_id: string
"""
prihdr = fits.Header()
prihdu = fits.PrimaryHDU(header=prihdr)
hdu_list = [prihdu]
hdu_images = []
grp_table = astt.Table([[],[],[],[],[],[],[],[],[],[],[]],names=('member_xtension', 'member_name', 'member_version', 'member_position', 'member_location', 'member_uri_type', 'imatype', 'chanmin', 'chanmax', 'e_min', 'e_max'), dtype=('S20', 'S20', 'u1', 'u1', 'S20', 'S20', 'S20', 'f4', 'f4', 'f4', 'f4'))
model_fits_position = 2
for image_idx in range(len(sky_images)):
for [model_shadowgram, model_name] in sky_images[image_idx].models_shadowgrams:
chanmin = energy_ranges[image_idx][0]
chanmax = energy_ranges[image_idx][1]
e_min = chanmin
e_max = chanmax
grp_table.add_row(['IMAGE ', model_name, '1', model_fits_position, '', '', 'Intensity', chanmin, chanmax, e_min, e_max])
hdu_mod = fits.ImageHDU(yzegp_to_ijdet_array(model_shadowgram))
hdu_mod.name = model_name
fits_tools.common_keyword(hdu_mod, tstart, tstop, creator, 1.0, proc_id)
fits_tools.energy_keywords(hdu_mod, chanmin, chanmax, e_min, e_max)
hdu_mod.header.extend(sky_images[image_idx].wcs.to_header().cards)
hdu_mod.header['comment'] = model_name + ' source model shadowgram'
hdu_mod.header['BUNIT'] = 'ct.s^-1.cm^-2'
hdu_mod.header['IMATYPE'] = ('Intensity', "Type of image")
hdu_images.append(hdu_mod)
model_fits_position += 1
hdu_grp = fits.table_to_hdu(grp_table)
hdu_grp.header['comment'] = 'ECLAIRs detector model images of point sources'
fits_tools.common_keyword(hdu_grp, tstart, tstop, creator, 1.0, proc_id)
fits_tools.grouphdu_keyword(hdu_grp, 'ECL-DET-MOD-IDX')
hdu_list.append(hdu_grp)
hdu_list.extend(hdu_images)
thdulist = fits.HDUList(hdu_list)
thdulist.writeto(file_path + '/ECL-DET-MOD-' + proc_id + '.fits', overwrite=True, checksum=True)
[docs]def save_sky_images_debug(sky_images, file_path, tstart, tstop, energy_ranges, creator, proc_id="01"):
"""save auxiliary images in fits file ECL-SKY-IMA_DEBUG
use common keywords
filename is 'ECL-SKY-IMA-' + proc_id + '_DEBUG.fits'
file contains: for each source model, the shadowgram of the source
:param sky_images: list of sky images and models
:type sky_images: list(SkyImages)
:param file_path: PATH to the directory where to write the file
:type file_path: string
:param tstart: start time of the observation in s from mjdref
:type tstart: float
:param tstop: end time of the observation in s from mjdref
:type tstop: float
:param energy_ranges: energy ranges (in PI) of the images [[low_energy, high_energy],[]]
:type energy_ranges: [[int, int]]
:param creator: program that has generated the file.
:type creator: string
:param proc_id: id of the process. Default="01".
:type proc_id: string
"""
prihdr = fits.Header()
prihdu = fits.PrimaryHDU(header=prihdr)
hdu_list = [prihdu]
hdu_images = []
grp_table = astt.Table([[],[],[],[],[],[],[],[],[],[],[]],names=('member_xtension', 'member_name', 'member_version', 'member_position', 'member_location', 'member_uri_type', 'imatype', 'chanmin', 'chanmax', 'e_min', 'e_max'), dtype=('S20', 'S20', 'u1', 'u1', 'S20', 'S20', 'S20', 'f4', 'f4', 'f4', 'f4'))
for image_idx in range(len(sky_images)):
chanmin = energy_ranges[image_idx][0]
chanmax = energy_ranges[image_idx][1]
e_min = chanmin
e_max = chanmax
grp_table.add_row(['IMAGE ', 'Initial Sky', '1', image_idx*6+2, '', '', 'intensity', chanmin, chanmax, e_min, e_max])
grp_table.add_row(['IMAGE ', 'Initial Variance', '1', image_idx*6+3, '', '', 'variance', chanmin, chanmax, e_min, e_max])
grp_table.add_row(['IMAGE ', 'Initial SNR', '1', image_idx*6+4, '', '', 'SNR', chanmin, chanmax, e_min, e_max])
grp_table.add_row(['IMAGE ', 'Remaining Sky', '1', image_idx*6+5, '', '', 'Intensity', chanmin, chanmax, e_min, e_max])
grp_table.add_row(['IMAGE ', 'Remaining Variance', '1', image_idx*6+6, '', '', 'Variance', chanmin, chanmax, e_min, e_max])
grp_table.add_row(['IMAGE ', 'Remaining SNR', '1', image_idx*6+7, '', '', 'SNR', chanmin, chanmax, e_min, e_max])
hdu_init_sky = fits.ImageHDU(sky_images[image_idx].initial_sky_count)
hdu_init_var = fits.ImageHDU(sky_images[image_idx].initial_sky_var)
hdu_init_snr = fits.ImageHDU(sky_images[image_idx].initial_sky_snr)
hdu_remain_sky = fits.ImageHDU(sky_images[image_idx].remains_sky_count)
hdu_remain_var = fits.ImageHDU(sky_images[image_idx].remains_sky_var)
hdu_remain_snr = fits.ImageHDU(sky_images[image_idx].remains_sky_snr)
hdu_images_tmp = [hdu_init_sky, hdu_init_var, hdu_init_snr, hdu_remain_sky, hdu_remain_var, hdu_remain_snr]
for hdu in hdu_images_tmp:
fits_tools.common_keyword(hdu, tstart, tstop, creator, 1.0, proc_id)
fits_tools.energy_keywords(hdu, chanmin, chanmax, e_min, e_max)
hdu.header.extend(sky_images[image_idx].wcs.to_header().cards)
hdu_images_tmp = update_images_debug_headers(hdu_images_tmp, sky_images[image_idx].time_exp_mn)
hdu_images.extend(hdu_images_tmp)
hdu_grp = fits.table_to_hdu(grp_table)
fits_tools.common_keyword(hdu_grp, tstart, tstop, creator, 1.0, proc_id)
fits_tools.grouphdu_keyword(hdu_grp, 'ECL-SKY-IMA-IDX')
hdu_list.append(hdu_grp)
hdu_list.extend(hdu_images)
thdulist = fits.HDUList(hdu_list)
thdulist.writeto(file_path + '/ECL-SKY-IMA-' + proc_id + '_DEBUG.fits', overwrite=True, checksum=True)
[docs]def save_catalogs(catalogs_output, file_path, tstart, tstop, energy_ranges, creator, proc_id="01"):
"""save output sources catalogs in fits file ECL-SOP-IMA
use common keywords
filename is 'ECL-SOP-IMA-' + proc_id + '.fits'
file contains: for each energy bands, the catalog of identified sources
:param catalogs_output: list of sources catalogs
:type catalogs_output: list(CatalogIdentifiedSources)
:param file_path: PATH to the directory where to write the file
:type file_path: string
:param tstart: start time of the observation in s from mjdref
:type tstart: float
:param tstop: end time of the observation in s from mjdref
:type tstop: float
:param energy_ranges: energy ranges (in PI) of the catalogs [[low_energy, high_energy],[]]
:type energy_ranges: [[int, int]]
:param creator: program that has generated the file.
:type creator: string
:param proc_id: id of the process. Default="01".
:type proc_id: string
"""
prihdr = fits.Header()
prihdu = fits.PrimaryHDU(header=prihdr)
hdu_list = [prihdu]
hdu_catalogs = []
grp_table = astt.Table([[],[],[],[],[],[],[],[],[],[]],names=('member_xtension', 'member_name', 'member_version', 'member_position', 'member_location', 'member_uri_type', 'chanmin', 'chanmax', 'e_min', 'e_max'), dtype=('S20', 'S20', 'u1', 'u1', 'S20', 'S20', 'f4', 'f4', 'f4', 'f4'))
for catalog_idx in range(len(catalogs_output)):
chanmin = energy_ranges[catalog_idx][0]
chanmax = energy_ranges[catalog_idx][1]
e_min = chanmin
e_max = chanmax
grp_table.add_row(['BINTABLE ', "ECL-SKY-RES", '1', catalog_idx+2, '', '', chanmin, chanmax, e_min, e_max])
hdu = fits.table_to_hdu(catalogs_output[catalog_idx]._catalog)
hdu.name = "ECL-SKY-RES"
fits_tools.common_keyword(hdu, tstart, tstop, creator, 1.0, proc_id)
fits_tools.energy_keywords(hdu, chanmin, chanmax, e_min, e_max)
hdu.header['comment'] = 'source parameters from sky images'
hdu.header['BASETYPE'] = ('DAL_TABLE', 'Data Access Layer base type')
hdu_catalogs.append(hdu)
hdu_grp = fits.table_to_hdu(grp_table)
hdu_grp.header['comment'] = 'Source Parameters derived from single reconstructed sky image'
fits_tools.common_keyword(hdu_grp, tstart, tstop, creator, 1.0, proc_id)
fits_tools.grouphdu_keyword(hdu_grp, 'ECL-SOP-IMA-IDX')
hdu_list.append(hdu_grp)
hdu_list.extend(hdu_catalogs)
thdulist = fits.HDUList(hdu_list)
thdulist.writeto(file_path + '/ECL-SOP-IMA-' + proc_id + '.fits', overwrite=True, checksum=True)