Source code for sofia_redux.instruments.hawc.steps.stepdmdcut
# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""Chop filtering pipeline step."""
from astropy import log
import numpy as np
from sofia_redux.instruments.hawc.stepparent import StepParent
__all__ = ['StepDmdCut']
[docs]
class StepDmdCut(StepParent):
"""
Filter bad chops from demodulated data.
This step removes chop cycles from the demodulated data arrays,
according to flags set by the demodulation algorithm.
The expected input is a demodulated file with a 'Chop Mask'
column in the data table. Input is generated by the
`sofia_redux.instruments.hawc.steps.StepDemodulate` pipeline step.
The output is a table with the same columns as the input, but some rows
removed.
The flag bits for the Chop Mask column are:
- bit 0: incomplete chop
- bit 1: check on azelstate
- bit 2: HWP moving
- bit 3: check on nodstate
- bit 4: spare
- bit 5: spare
- bit 6: LOS rewind
- bit 7: tracking errors too high
- bit 8: CentroidExpMsec below threshhold
- bit 9: extra samples before and after tracking tolerance violation
"""
[docs]
def setup(self):
"""
Set parameters and metadata for the pipeline step.
Output files have PRODTYPE = 'dmdcut', and are named with
the step abbreviation 'DMC'.
Parameters defined for this step are:
mask_bits : int
Bits on which to filter the data. Set to 0b1111111111
(1023) to filter on all flags. Set to 0b001000000 (64)
to filter on LOS rewind only. Set to 0 to skip all flags.
min_samples : int
Chops containing fewer than min_samples in the Samples
column will be removed from the output.
"""
# Name of the pipeline reduction step
self.name = 'dmdcut'
self.description = 'Filter Bad Chops'
# Shortcut for pipeline reduction step and identifier for
# saved file names.
self.procname = 'dmc'
# Clear Parameter list
self.paramlist = []
# Append parameters
self.paramlist.append(['mask_bits', 0b1111111111,
'Bits on which to filter'])
self.paramlist.append(['min_samples', 1,
'Minimum samples value'])
[docs]
def run(self):
"""
Run the data reduction algorithm.
This step is run as a single-in single-out (SISO) step:
self.datain should be a DataFits object, and output will also
be a single DataFits, stored in self.dataout.
The process is:
1. Read the desired filter flags from the input parameters
and compare with the Chop Mask column in the input.
2. Remove flagged samples.
"""
# Get variables
mask_bits = self.getarg('mask_bits')
min_samples = self.getarg('min_samples')
# Copy datain to dataout
self.dataout = self.datain.copy()
# Apply mask
if 'Chop Mask' in self.datain.table.names:
chopmask = self.datain.table['Chop Mask']
else:
log.info('Chop mask column not found, using zeros')
chopmask = np.zeros(len(self.datain.table), dtype=np.int32)
nsamples = self.datain.table['Samples']
keep_index = np.where(((chopmask & mask_bits) == 0)
& (nsamples >= min_samples))
self.dataout.table = self.dataout.table[keep_index]
log.info('Retained %d out of %d chops' %
(len(self.dataout.table), len(self.datain.table)))