#
# 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