1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
Example script
==============
.. default-domain:: lua
This section demonstrates a simple example script.
Copying the script below into the ``rfigui`` Lua editor will allow you to
interactively change this script.
.. code-block:: lua
function execute(data)
data:clear_mask()
for _,polarization in ipairs(data:get_polarizations()) do
local pol_data = data:convert_to_polarization(polarization)
pol_data = pol_data:convert_to_complex("amplitude")
aoflagger.high_pass_filter(pol_data, 51, 51, 3, 3)
aoflagger.visualize(pol_data, "Low-pass filtered", 0)
aoflagger.sumthreshold(pol_data, 1, 1, true, true)
aoflagger.scale_invariant_rank_operator(pol_data, 0.2, 0.2)
pol_data = pol_data:convert_to_complex("complex")
data:set_polarization_data(polarization, pol_data)
end -- end of polarization iterations
end
We will discuss this script line by line.
When AOFlagger calls the ``execute()`` function, the script starts by calling
:meth:`Data.clear_mask`, which unsets all flags:
.. code-block:: lua
function execute(data)
data:clear_mask()
If the input data was already flagged, these flags are removed.
The next step is a ``for`` loop over the different polarizations in the set:
.. code-block:: lua
for _,polarization in ipairs(data:get_polarizations()) do
Almost any flagging script will need such a loop, because most
operations can only work on a single polarization. The input data could consist
of 1-4 linear polarizations (XX, XY, YX, YY), circular polarizations
(LL, LR, RL, RR) or Stokes polarizations (I, Q, U, V).
:meth:`Data.get_polarizations()` returns a table of strings, and ``ipairs``
converts this to an iterator. A loop over a table captures an
(index, value) pair. In this case we only need the value (``polarization``),
and ignore the index with the underscore.
To work on a single polarization only, :meth:`Data.convert_to_polarization` is
used to create a new data object that contains just that single polarization:
.. code-block:: lua
local pol_data = data:convert_to_polarization(polarization)
The new object is stored as ``local`` variable. In Lua, any variable that is
not declared as ``local``, is a global. This might cause the data to be stored
longer than necessary, causing more memory usage, so local variables should be
preferred. [1]_
Most input data sets are complex. Thresholding is more effective on the
amplitudes of the samples though. Function ``Data.convert_to_complex`` is used
to calculate the amplitudes:
.. code-block:: lua
pol_data = pol_data:convert_to_complex("amplitude")
Another new object is created, but the previous ``pol_data`` object is
overwritten.
The next step is high-pass filtering the data:
.. code-block:: lua
aoflagger.high_pass_filter(pol_data, 51, 51, 3, 3)
Function :meth:`aoflagger.high_pass_filter` filters the visibility data in
`pol_data`. A kernel of 51 x 51 samples is used (ntimes x nchannels), with a
Gaussian width of 3 samples in both directions.
The filtered data is "visualized" with function :meth:`aoflagger.visualize`:
.. code-block:: lua
aoflagger.visualize(pol_data, "Low-pass filtered", 0)
This statement makes it possible to display the result of filtering the
data in ``rfigui``. When the script is not running interactively from a
gui, the call is ignored. Note that ``visualize()`` will be called for
all polarizations. The gui will recombine visualizations from different
polarizations, as long as they have the same name and sorting index.
The :meth:`aoflagger.sumthreshold` searches the (filtered) data for consecutive high
values in time or frequency:
.. code-block:: lua
aoflagger.sumthreshold(pol_data, 1, 1, true, true)
The resulting ``pol_data`` object will now contain a flag mask. This flag mask
is morphologically extended in the time and frequency direction with the
:meth:`aoflagger.scale_invariant_rank_operator` function:
.. code-block:: lua
aoflagger.scale_invariant_rank_operator(pol_data, 0.2, 0.2)
Finally, the data are converted back to its original form, so that the
polarizations can be combined. The first step is to convert the data back
to complex values using :meth:`Data.convert_to_complex`:
.. code-block:: lua
pol_data = pol_data:convert_to_complex("complex")
This "conversion" can be seen as an update of the metadata. The phases
were lost while converting to amplitudes, so these are not restored, and
just assumed to be constant. The ``pol_data`` now holds a complex data and
our new flag mask. The last step is to update the input data with our
new data using :meth:`Data.set_polarization_data`:
.. code-block:: lua
data:set_polarization_data(polarization, pol_data)
By iterating over all polarizations in the input set, the
polarizations in the input data object are replaced one by one.
.. [1] Data objects are emptied by AOFlagger at the end of the ``execute()``
function, so the user should normally not worry about memory usage.
|