Source code for sofia_redux.instruments.flitecam.backsub
# Licensed under a 3-clause BSD style license - see LICENSE.rst
from astropy import log
from astropy.io import fits
import numpy as np
from sofia_redux.toolkit.utilities.fits import hdinsert
__all__ = ['backsub']
[docs]
def backsub(hdul, bgfile=None, method='flatnorm'):
"""
Correct flux data for background level.
To correct pixels individually, a background image must be
provided with a FLUX extension and (optionally) an ERROR extension.
The error is propagated assuming that the input data is independent
of the sky data. Delete the extension or set the error plane to
zero-values to skip error propagation.
Otherwise, a single background level can be determined from the
median of each image, or from a header value derived from a
sky flat file, stored in the FLATNORM keyword in the primary header
of the input data. In this case, no error is propagated.
Parameters
----------
hdul : fits.HDUList
Input data. Should have FLUX, ERROR, FLAT, and FLAT_ERROR
extensions.
bgfile : fits.HDUList, optional
Background image. Should have FLUX and ERROR extensions.
method : {'flatnorm', 'median'}, optional
Method for background value determination, if background image
is not provided. If 'flatnorm', the header keyword FLATNORM
will be subtracted from the data. If 'median', the image median
will be subtracted from the data. Ignored if `bgfile` is not
None.
Returns
-------
fits.HDUList
Corrected data, with updated FLUX and ERROR extensions.
"""
# input data
header = hdul[0].header
flux = hdul['FLUX'].data
var = hdul['ERROR'].data ** 2
if bgfile is not None:
bgdata = bgfile['FLUX'].data
if 'ERROR' in bgfile:
bgvar = bgfile['ERROR'].data ** 2
else:
bgvar = 0.0
corrected_flux = flux - bgdata
corrected_var = var + bgvar
# record method and value
hdinsert(header, 'BGSOURCE',
bgfile[0].header.get('FILENAME', 'UNKNOWN'),
'Background value source')
hdinsert(header, 'BGVALUE', np.nanmedian(bgdata),
'Median background value')
else:
if method == 'flatnorm':
bgval = hdul[0].header.get('FLATNORM', None)
if bgval is None:
log.warning('FLATNORM keyword is missing; background '
'will not be corrected.')
bgval = 0
hdinsert(header, 'BGSOURCE', 'FLATNORM keyword',
'Background value source')
else:
bgval = np.nanmedian(flux)
hdinsert(header, 'BGSOURCE', 'Image median',
'Background value source')
corrected_flux = flux - bgval
corrected_var = var
hdinsert(header, 'BGVALUE', bgval, 'Median background value')
# make output hdul
corrected = fits.HDUList()
expected = ['FLUX', 'ERROR', 'BADMASK', 'EXPOSURE']
for hdu in hdul:
if hdu.name in expected:
corrected.append(hdu)
corrected['FLUX'].data = corrected_flux
corrected['ERROR'].data = np.sqrt(corrected_var)
return corrected