Source code for recipe_system.utils.reduceActions

#
#                                                                  gemini_python
#
#                                                        recipe_system.reduction
#                                                               reduceActions.py
# ------------------------------------------------------------------------------
"""
This module provides a number "action" classes, subclassed from the
argparse.Action class. These classes only override the __call__() method. This 
actions class library supplies ad hoc functionality to DPDG requirements on the
reduce command line interface.

Action classes provided:

    PosArgAction          - positional argument
    BooleanAction         - optional switches
    UnitaryArgumentAction - single value options
    ParameterAction       - user parameters (-p, --param)
    CalibrationAction     - user calibration services (--user_cal)

Becuase of requirements on the reduce interface, any new reduce options should
specify one of these actions in the add_argument() call. But only one (1)
PosArgAction should occur in a given parser.

These actions may be used in the add_argument() method call, such as,

    parser.add_argument('-f', '--foo', action=BooleanAction,
                         help="Switch on foo.")

"""
from argparse import Action


[docs]class PosArgAction(Action): def __call__(self, parser, namespace, values, option_string=None): if values: setattr(namespace, self.dest, values) return
[docs]class BooleanAction(Action): def __call__(self, parser, namespace, values, option_string=None): # 'values' is a list, which may have accumulated pos args _pos_args = [] _switch_state = bool(getattr(namespace, self.dest)) _pos_args.extend([f for f in values if ".fits" in f]) # Configure namespace w new files if _pos_args: setattr(namespace, 'files', _pos_args) # Toggle switch. setattr(namespace, self.dest, not _switch_state) return
[docs]class UnitaryArgumentAction(Action): def __call__(self, parser, namespace, values, option_string=None): # 'values' is a list, which may have accumulated pos args _pos_args = [] _par_args = [] _extant_pos_args = getattr(namespace, 'files') _extant_par_args = getattr(namespace, self.dest) for value in values: if ".fits" in value: _pos_args.extend([value]) else: _par_args.extend([value]) # set new pos args if _pos_args: setattr(namespace, 'files', _pos_args) # Received (new) unitary argument types # override any previous namespace self.dest setattr(namespace, self.dest, _par_args) return
[docs]class ParameterAction(Action): def __call__(self, parser, namespace, values, option_string=None): # 'values' is a list, which may have accumulated pos args _pos_args = [] _par_args = [] _extant_pos_args = getattr(namespace, 'files') _extant_par_args = getattr(namespace, self.dest) for value in values: if "=" not in value: _pos_args.extend([value]) else: _par_args.extend([value]) # set new pos args if _pos_args: setattr(namespace, 'files', _pos_args) # Handle parameter args already in namespace. # Override only those specific parameters. if _par_args and not _extant_par_args: setattr(namespace, self.dest, _par_args) if _extant_par_args: reemed = [_extant_par_args.remove(z) for z in [x for x in _extant_par_args if x.split('=')[0] in [y.split('=')[0] for y in _par_args]] ] print("Overriding", len(reemed), "parameter(s).\n") _extant_par_args.extend(_par_args) setattr(namespace, self.dest, _extant_par_args) return
[docs]class CalibrationAction(Action): def __call__(self, parser, namespace, values, option_string=None): # 'values' is a list, which may have accumulated pos args _pos_args = [] _cal_args = [] _extant_pos_args = getattr(namespace, 'files') _extant_cal_args = getattr(namespace, self.dest) for value in values: if ":" not in value: _pos_args.extend([value]) else: _cal_args.extend([value]) # set new pos args if _pos_args: setattr(namespace, 'files', _pos_args) # Handle cal args already in namespace. # Override specific parameters. if _cal_args and not _extant_cal_args: setattr(namespace, self.dest, _cal_args) if _extant_cal_args: reemed = [_extant_cal_args.remove(z) for z in [x for x in _extant_cal_args if x.split(':')[0] in [y.split(':')[0] for y in _cal_args]] ] print("Overriding", len(reemed), "calibration source(s).\n") _extant_cal_args.extend(_cal_args) setattr(namespace, self.dest, _extant_cal_args) return