.. Copyright 2009-2012 Peter Williams This file is part of miriad-python. Miriad-python is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Miriad-python is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miriad-python. If not, see . .. _pytaskskeys: .. sectionauthor:: Peter Williams MIRIAD-Style Argument Handling: :mod:`mirtask.keys` =================================================== .. module:: mirtask.keys :synopsis: Process task arguments in the MIRIAD style. .. moduleauthor:: Peter Williams Like other UNIX programs, MIRIAD tasks accept input parameters from the user via command-line arguments. The way in which MIRIAD tasks do this, however, is different than the usual UNIX way. Each task defines a number of "keywords". The MIRIAD keyword-handling subsystem can be used to obtain zero or more values of each keyword from the command-line arguments. The values of a given keyword do not necessarily all have to be of the same type. The user specifies the values of these keywords on the command-line with an assignment syntax:: invert vis=3c286.uv map=3c286.mp imsize=824,724 slop=0.5 select='ant(1,3),pol(xx)' Here, the *vis* keyword has a single string value (interpretable specifically as a filename), the *imsize* keyword has two integer values, and the *select* keyword has two string values. (Note that the keyword-handling routines process parentheses in string-valued keywords and do *not* consider the keyword to have the values "ant(1", "3)", and "pol(xx)".) Boolean-valued keywords are called "options" and are implemented by an *options* pseudo-keyword:: invert options=mfs,double Here the options *mfs* and *double* have :const:`True` values while all other options are :const:`False`. Handling keywords in miriad-python ---------------------------------- Tasks in MIRIAD obtain the values of keywords in a procedural way. In miriad-python, keywords are generally specified declaratively and their values are obtained automatically, although there is support for the more general procedural approach. To parse arguments in a miriad-python task: #. Instantiate a :class:`KeySpec` object. #. Specify the keywords your task accepts. #. Use the :meth:`KeySpec.process` method to obtain a data structure populated with the settings for all keywords based on your specification. Here's a simple example:: from mirtask import keys ks = keys.KeySpec () ks.keyword ('param', 'd', 0.25) ks.keyword ('mode', 'a', 'deconvolve') ks.option ('verbose', 'noop') opts = ks.process () if opts.param < 0: die ('"param" must be positive, not %f' % opts.param) if opts.mode not in ('deconvolve', 'stirfry'): die ('Unknown operation mode "%s"' % opts.mode) if opts.verbose: print "Being verbose starting now!" The methods on :class:`KeySpec` to define keywords are: * :meth:`~KeySpec.keyword` defines a keyword that takes a single, typed value, with a default if the keyword is left unspecified. * :meth:`~KeySpec.mkeyword` defines a keyword that takes multiple values of the same type. * :meth:`~KeySpec.keymatch` defines a keyword that takes on one or more enumerated values with minimum-match string expansion. * :meth:`~KeySpec.option` defines one or more options. * :meth:`~KeySpec.custom` defines a keyword that is handled in a custom way by the caller. The object returned by :meth:`~KeySpec.process` has an attribute for each keyword defined using the above functions. * For keywords defined with :meth:`~KeySpec.keyword`, the attribute is equal to the user's provided value or the default. * For keywords defined with :meth:`~KeySpec.mkeyword`, the attribute is a list of the values provided by the user, with the list being empty if the user provided none. * For keywords defined with :meth:`~KeySpec.keymatch`, the attribute is a list of the values provided by the user expanded out to their full values if the user abbreviated any. As above, the list may be empty. * For options defined with :meth:`~KeySpec.option`, the attribute is either :const:`True` or :const:`False`. * For keywords defined with :meth:`~KeySpec.custom`, the attribute is whatever value was returned by a user-specified routine. If the user-specified values do not match the expectations defined by the specification (e.g., a keyword that should be integer-typed is passed the value "abcd") then a :class:`~miriad.MiriadError` is raised in :meth:`~KeySpec.process`. .. _keywordtypes: Keyword Types ------------- Keyword types in MIRIAD and miriad-python are identified by single letters. The following types are available: =========== ============== Character Description =========== ============== *i* (The character is the lower-case letter i.) An integer value. *d* A floating-point ("double") value. *a* A character string value. *f* A filename value. These are essentially treated like character strings, but there are special hooks in the MIRIAD processing code to expand out shell glob patterns into multiple values. *t* A time or angle value. These are parsed according to one of several formats, described below. The output is always a floating-point number but its meaning depends on the parse format. =========== ============== .. _keywordformats: Keyword Formats --------------- Keywords describing a time or angle can be parsed according to one of several formats. You must specify one of these formats when declaring the keyword. ======= ============ Name Description ======= ============ *dms* The argument is an angle measured in degrees, written as "dd:mm:ss.s" or "dd.ddd". The output is the angle in radians. *hms* The argument is an angle/time measured in hours, written as "hh:mm:ss.s" or "hh.hhh". The output is the angle/time in radians. *dtime* The argument is a day fraction, i.e. the portion of a day that has elapsed at that local time. The user can provide it in the format "hh:mm:ss.s" or "hh.hhhh". The output is the day fraction, a number in the range [0, 1]. *atime* The argument is an absolute time, specified as either "yyMMMdd.ddd" or "yyMMMdd:hh:mm:ss.s", or as an epoch, "bYYYY" or "jYYYY". The output is in Julian days. *time* Either an absolute time or a day fraction. The output is either a Julian day value or a day fraction. ======= ============ .. _keysuvdat: Integration with the UVDAT Subsystem ------------------------------------ The keyword subsystem can integrate with MIRIAD's UVDAT subsystem. This integration is necessary because the UVDAT subsystem uses the MIRIAD keyword-handling routines to obtain settings for UV data selection, whether calibration should be applied, and so on. If your task does not use the UVDAT subsystem, you need take no action. If your task does use the UVDAT subsystem, you must call :meth:`KeySpec.uvdat` while defining your keywords. When doing so, you specify processing options that will be passed to the UVDAT subsystem. See the documentation of :meth:`~KeySpec.uvdat` for more information. .. _mirtaskkeysapiref: :mod:`mirtask.keys` API Reference --------------------------------- This section presents a detailed API reference for the :mod:`mirtask.keys` module. .. autoclass:: KeySpec :members: .. autoclass:: KeyHolder :members: