To allow for flexibility and extendability, the instructions on how to expand
keyword comes from one or more configuration files, written using the yaml
standard.
Special keywords
These keywords are understood and used by the interpreter, but should not be
used as variables to expand
is_alias_of
If exists, its value is the real name of the executable. This allows to create
various commands using the same underlying executable. If e.g. the command is:
do_something $args -o $ofile $ifiles
and the configuration file contains
is_alias_of: an_executable
args: "-a -b"
ofile: outfile
ifiles: file[1-9].txt
primary: ifiles
then the interpreter will loop through all the files matching the ifiles
pattern in target_dir. For the first file, it will execute:
an_executable -a -b -o outfile file1.txt
mandatory
List of mandatory fields; field names defined under mandatory must exist
in the provided command; if not found, or empty, no check is done
mandatory: [ifiles]
# or equivalently
mandatory:
- field1
- field2
primary
Name of the keyword to use as primary. A primary keyword has a special status:
files are collected from the target_dir according to the type of the
underlying keyword, then they are looped over and for each step the command
string is created and executed. If the value of any other keywords needs to be
built at run time, it will use the primary files to do it. VDAT is
shipped with few primary types.
filter_selected
Tells the interpreter how to filter the list of primary files. If this option
is not found in the configuration or the selected keyword in
CommandInterpreter is None, no
filtering is performed. Otherwise, for each element in the primary list:
- uses the instructions from the value of filter_selected to extract a
string
- check if the string is in selected.
The value of filter_selected can be any of the keyword types described below.
With the following settings:
# Use the value of the header keyword ``IFUSLOT`` to decide whether to
# keep the primary field or not
filter_selected:
type: header
keyword: IFUSLOT
the content of the fits header keyword IFUSLOT is extracted and compared
with the list provided with the selected options in
CommandInterpreter
execute
For each iteration of the primary, tells the interpreter whether to run or
not the command. If the option is not found, no filtering will be performed.
VDAT is shipped with a few execute types.
The following configuration:
execute:
type: new_file
sub_type: format
value: masterbias_{ica}.fits
keys:
ica:
type: regex
match: .*\d*?T\d*?_(\d{3}[LR][LU])_.*\.fits
replace: \1
Create the value extracting the ica keyword from the primary file name
and returns false if the file already exists.
If the handling of the keyword raises and exception, it is logged and the
command is executed.
Build-in primary keyword types
plain
It looks for all the files matching the give pattern in the target directory. If
the value of a keyword is a string, it is interpreted as of plain type.
These three definitions are equivalent:
keyword: 20*.fits
---
keyword:
type: plain
value: 20*.fits
---
keyword: {type: plain, value: 20*.fits}
loop
collects the keys
cycles through all the possible combinations of the keys
for each combination replaces the corresponding entries in value using
the standard python format string syntax
look for all the files matching the resulting strings
- if any file is found, construct a string with space separated file names
and yields it.
The value of keys is a map between the names of the keys, e.g. ifu
and the values that they can have. Their value can be either a list or three
comma separated numbers: start, stop, step. The latter case is converted
into a list of numbers from start to stop excluded every step
The following configuration:
keyword:
type: loop
value: 's[0-9]*{ifu:03d}{channel}{amp}_*.fits'
keys: # dictionary of keys to expand in ``value``
ifu: 1, 100, 1 # start, stop, step values of a slice
channel: [L, R] # a list of possible values
amp: # alternative syntax for the list
- L
- U
cycles through all the possible combinations of the three lists: [1, 2, ..,
99], ['L', 'R'] and ['L', 'R']. For the first combination we get:
ifu: 1, channel: L, amp: L and value becomes
s[0-9]*001LL_*.fit. Then all the files matching this pattern are
collected.
groupby
collects all the files matching value and loop through them
- for each of the files replace match with all the values in replace
using the python regex syntax
The following configuration:
keyword:
type: groupby
value: 'p[0-9][LR]L_*.fits'
match: (.*p\d[LR])L(_.*\.fits)
replace:
- \1U\2
cycles through all the files matching value in the target_dir, e.g.
“p2LL_sci.fits”, and for each of them creates a new file name the last “L” with
“U”, e.g. “p2LU_sci.fits”. The two files are then returned.
To create multiple files out of the first one, it’s enough to provide other
entries to replace. E.g.:
replace: [\1U\2, \1A\2, \2_\1]
will create three new files: “p2LU_sci.fits”, “p2LA_sci.fits” and
“_sci.fits_p2L”
Build-in keyword types
plain
A static string. These three definitions are equivalent:
keyword: '-a -b --long option'
---
keyword:
type: plain
value: '-a -b --long option'
---
keyword: {type: plain, value: '-a -b --long option'}
regex
Returns a string obtained from primary replacing match with replace. It
uses re.sub() to do the substitution. If e.g. the primary is called
file_001_LL.fits, the following entry returns L001
keyword:
type: regex
match: .*_(\d{3})([LR]).*\.fits
replace: \2\1
Build-in execute types
new_file
For each of the primary entry, it constructs a string using the keyword
type defined by subtype. If that string corresponds to something
existing in the file system, returns False.
Besides type, subtype is the only mandatory keyword and its value must
be one of the available keyword types. All the relevant keywords for that type
must of course exist.