Source code for sofia_redux.instruments.hawc.steps.stepfluxjump
# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""Flux jump correction pipeline step."""
import os
from astropy import log
import numpy as np
from sofia_redux.instruments.hawc.stepparent import StepParent
from sofia_redux.instruments.hawc.datafits import DataFits
__all__ = ['StepFluxjump']
[docs]
class StepFluxjump(StepParent):
"""
Correct for flux jumps in raw data.
This pipeline step corrects for a detector effect that introduces
discontinuous changes in flux values (flux jumps). Jumps are
detected in the data, then a jump map is used to shift all data
following the jump to correct values.
Input to this step is raw HAWC data files. This step should
be called before `sofia_redux.instruments.hawc.steps.StepPrepare`.
It uses the 'SQ1Feedback' and 'FluxJumps' columns in the data table.
Output from this step has the same format as the input; only flux
values in the SQ1FeedbackColumn are modified.
"""
[docs]
def setup(self):
"""
Set parameters and metadata for the pipeline step.
Output files have PRODTYPE = 'fluxjump', and are named with
the step abbreviation 'FJP'.
Parameters defined for this step are:
jumpmap : str or float
Path to a file name, specifying the jump gap map
in FITS format. Alternatively, a single value can be
specified to apply to all pixels. If all jump map
values are zero, no jump correction will be performed.
"""
# Name of the pipeline reduction step
self.name = 'fluxjump'
self.description = 'Fix Flux Jumps'
# Shortcut for pipeline reduction step and identifier for
# saved file names.
self.procname = 'fjp'
# Clear Parameter list
self.paramlist = []
# Append parameters
self.paramlist.append(['jumpmap', '4600.0',
'filepathname specifying the jump gap map, '
'alternatively a number for the gap '
'to be used for all pixels'])
[docs]
def run(self):
"""
Run the data reduction algorithm.
Because this step is single-in, single-out (SISO),
self.datain must be a DataFits object. The output
is also a DataFits object, stored in self.dataout.
The process is:
1. Read the jump map from the parameters.
2. Identify pixel samples with flux jumps
(FluxJump data at that pixel is < -32 or > 32).
3. Fix flux jump data for any pixels that wrap around
from 64 to -64, or from -64 to 64 (compared
to the previous sample).
4. Multiply flux jump data by the jump map.
5. Add the jump data * map to the raw data array.
6. Store the result in the SQ1Feedback column.
"""
# Preparation
# Get raw data size
detsize = self.datain.table['SQ1Feedback'].shape[1:]
# Load jump gap map
jumpmap = os.path.expandvars(str(self.getarg('jumpmap')))
if os.path.exists(jumpmap):
# Load pipedata object and get image
jumpdat = DataFits(jumpmap).image
else:
# make it an int
try:
jumpmap = int(float(jumpmap))
jumpdat = np.ones(detsize, dtype=np.int32) * jumpmap
except (ValueError, TypeError):
msg = 'Bad fluxjump value: {}'.format(jumpmap)
log.error(msg)
raise ValueError
log.debug('Got fluxjump data = %s' % jumpmap)
if np.allclose(jumpdat, 0):
log.info('No correction to apply.')
self.dataout = self.datain
return
# Get Data
fjdata = self.datain.table['FluxJumps']
rawdata = self.datain.table['SQ1Feedback']
# Correct fluxjumps wraparounds
# select only pixels which have fj values >32 and <-32
(rowinds, colinds) = np.where((np.amin(fjdata, axis=0) < -32)
& (np.amax(fjdata, axis=0) > 32))
log.debug('%d pixels need wraparound check' % len(rowinds))
# Loop through pixels which need check
for i in range(len(rowinds)):
ri, ci = rowinds[i], colinds[i]
# Fix wraparounds in fluxjump trace for that pixel
for j in range(1, fjdata.shape[0]):
if fjdata[j - 1, ri, ci] < -32 and fjdata[j, ri, ci] > 32:
fjdata[j, ri, ci] -= 128
if fjdata[j - 1, ri, ci] > 32 and fjdata[j, ri, ci] < -32:
fjdata[j, ri, ci] += 128
# Do flux jump correction
# Shift fluxjumps by one sample in time
# (to have one sample delayed response to FJ)
fjdata[1:, ...] = fjdata[:-1, ...]
# Multiply with jump map
fjdata *= jumpdat
# Correct raw data with flux jumps
rawdata += fjdata
# Put data back
self.dataout = self.datain
self.dataout.table['SQ1Feedback'] = rawdata