Introduction

To encourage interoperability between our various frameworks, and to enable people to write standard "plug-and-play" modules for such things as Jones matrices, it is important to define some standard interfaces and behaviours. I will refer to these by contracts, since Python encourages describing interfaces in terms of guaranteed object behaviour (i.e. contract), rather than specific object types. This page is an attempt to describe a few standard contracts.

I have implemented a class tentatively called MeqMaker which makes use of all the contracts here to put together arbitrary MEs. Since this provides examples of how these contracts are used, I will refer to MeqMaker a lot here.

"Jones" contract

This represents a single Jones matrix. A "Jones" contract is simply a node that computes a scalar or a 2x2 matrix.

"Station Jones" contract

J is a "Station Jones" if for a given station index p, J(p) implements the "Jones" contract.

The most common example is an unqualified node. E.g. ns.G is a "Station Jones" if ns.G(p) are valid nodes representing Jones matrices for each station (p).

The reason to define this interface as a contract and not as simply an unqualified node is because people may want to implement some kind of class to represent station Jones. As long as that class defines the function call operator (which returns a single "Jones"), the class follows the contract. We may need to use this when we implement image-plane effects on extended sources.

Note that Meow.SkyComponent.corrupt() expects a "Station Jones" argument.

"Sky Jones" contract

J is a "Sky Jones set" if it implements these two behaviours:

Note that we do not define what "x" are valid here. The range of "x" is specified by additional contracts, e.g. "Sky Jones for the following list of sources". See "Sky Jones Module" below for examples.

The most common example is an unqualified node. E.g. ns.E is a "Sky Jones" if ns.E(src,p) are valid nodes representing Jones matrices for each source and station.

"Station Pointings" contract

P is a "Station Pointings" if, for a given station index p, P(p) is a node returning a real-valued 2-vector. Note that this may be an absolute pointing, or a pointing offset.

"Module" contract

A "Module" is simply a self-contained unit implementing some functionality (Jones, sky models, etc.) This may be an actual Python module (e.g. oms_gain_models.py), or an object of some class (e.g. Meow.MeowLSM).

A "Module" will typically include a number of TdlOptions that show up in the GUI and in config files. Real Python modules may declare these as TDLCompileOptions/TDLRuntimeOptions; users of the module may trivially "suck" these into submenus, see TdlOptions for details.

The various specialized "Module" contracts below all follow the "Module" contract.

Optional "Module" behaviours

parameters apply to only a subset of sources.

For real Python modules, neither function is really necessary. The module can simply declare !TDLCompile/RuntimeOptions in its global scope in the usual way. The MeqMaker class will "suck in" these options automatically, and neatly arrange them inside sub-menus. There are two situations in which you may need to implement these functions:

Note that declaring global-scope options vs. returning them via compile_/runtime_options() is an either-or proposition. If, e.g., compile_options() is implemented, then MeqMaker will NOT look for global-scope options.

Node naming issues

Generally, we don't want modules making up their own node names in the global node scope, since this can lead to naming conflicts between different modules. For this reason, modules are typically passed a node or nodes argument, which should be used to create all internal nodes. This leaves naming under control of the caller. Any intermediate nodes used in calculations should be created within a subscope of nodes:

Some Common Module Behaviours

Most module contracts listed below define a compute_xxx() function that implements the bulk of the module's behaviour. This has the following features that are common to all contracts:

"Pointing Module" contract

A "Pointing Module" is a "Module" that implements a compute_pointings function with the following signature:

"Stations Jones Module" contract

A "Station Jones Module" is a "Module" that implements a compute_jones function with the following signature:

"Sky Jones Module" contract

A "Sky Jones Module" is a "Module" that implements a compute_jones function with the following signature:

The MeqMaker class can perform some important optimizations when dealing with a mix of solvable and non-solvable sky-Jones terms.

An example "Sky Jones Module" is oms_ionosphere.py (in WH/contrib/OMS/Siamese), which computes a Zeta-Jones. Note that this module illustrates the intended use of the inspectors argument. MeqMaker usually automatically creates inspectors for the Jones terms returned by every module. However, it is not really interesting to look at Zeta-Jones per se: far more informative are the TECs and the ionospheric phase delays that go into making it. The oms_ionosphere module therefore makes its own inspectors for these things, MeqMaker then skips the standard inspector.

"Sky Model" contract

A "Sky Model" is a "Module" that implements a source_list() function with the following signature:

Optional "Sky Model" behaviours

A "Sky Model" may optionally implement an estimate_image_size() function with the following signature:

There are currently two "Sky Model" examples:

Gridded_skies does implement estimate_image_size(), LSM currently doesn't

"Visibility Processing Module" contract

A VPM is a "Module" that implements a process_visibilities() function with the following signature:

VPMs may be used for any function that operates on visibilities. This can be, e.g., a flagger, or a module implementing interferometer-based errors.

Reversible VPMs

An "Reversible VPM" additionally implements a correct_visibilities() function with the following signature:

This function is meant to invert the processing applied by 'process_visibilities()`. For example, ifr-based errors are invertable, so MeqMaker can call this function when generating corrected visibilities. On the other hand, a flagger module would not implement this function at all.

All arguments are the same as for process_visibilities() above.

"Sky Visibility Processing Module" contract

A SVPM is a "Module" that implements a process_visibilities() function with the following signature:

SVPMs may be used for any function that operates on per-source visibilities. This can be, e.g., a module that applies smearing correction, etc.

Reversible SVPMs

An "Reversible SVPM" additionally implements one (or both) functions with the following signature:

These functions are meant to invert the processing applied by 'process_visibilities()`. For example, ifr-based errors are invertable, so MeqMaker can call this function when generating corrected visibilities.

All other arguments are the same as for process_visibilities() above.

FrameWorks/StandardContracts (last edited 2008-11-17 15:05:39 by OlegSmirnov)