Update CFSimpleIndexer authored by Martin Pokorny's avatar Martin Pokorny
......@@ -72,13 +72,54 @@ Note that a `CFCellIndex` value only provides indexes within the range of each d
## Example
Let `store` be a `CFStore2` instance, with a single baseline type and ten elements on the "PA/Time" axis. Let each `CFBuffer` element have four frequencies, eight "W" values, and sixteen Mueller elements. Furthermore, assume that the CF support size varies with "W", and no other index values. To define a `CFSimpleIndexer` value for the *entire* `CFStore2 x CFBuffer`, the following is correct
Let `store` be a `CFStore2` instance, with a single baseline type and ten elements on the "PA/Time" axis. Let each `CFBuffer` element in `store` have four frequencies, eight "W" values, and sixteen Mueller elements. Furthermore, assume that the CF support size varies with "W", and no other index values. To define a `CFSimpleIndexer` value for the *full* `CFStore2 x CFBuffer`, the following is correct
```c++
CFSimpleIndexer
indexer(
full_indexer(
{1, false}, // 1 baseline type with no CF support variability
{10, false}, // 10 times with no CF support variability
{8, true}, // 8 W planes with CF support variability
{4, false}, // 4 frequencies with no CF support variability
16); // 16 Mueller elements
```
In many uses of gridding with `hpg::Gridder`, only a subset of the full CF definition is needed for gridding a particular set of visibilities to be passed to `hpg::Gridder::grid_visibilities()`. Such a strategy is useful because it limits the data that will be copied to a device (through a call to `hpg::Gridder::set_convolution_function()`) prior to the call to `grid_visibilities()`. Assume that we have partitioned the set of visibilities by W value, and we will grid them one W value at a time. For the remainder of this example, then, assume that the W index is fixed to `W_0`, where `0 <= W_0 < 8`. Finally, assume that only the diagonal Mueller matrix elements will be used for gridding visibilities, which are the visibilities at Mueller index 0, 5, 10, and 15 in every `CFBuffer` instance. The `CFSimpleIndexer` definition for this subset of CF values is the following
```c++
CFSimpleIndexer
subset_indexer(
{1, false}, // 1 baseline type with no CF support variability
{10, false}, // 10 times with no CF support variability
{1, false}, // 1 W planes with no CF support variability
{4, false}, // 4 frequencies with no CF support variability
4); // 4 Mueller elements
```
We next must define mappings from indexes in the space defined by `CFSimpleIndexer` to indexes in the full `CFStore2 x CFBuffer` space. For example, the W index in `subset_indexer` can only take the value zero, but this index corresponds to `W_0` in a `CFBuffer`. Such mappings remain outside the scope of `hpg`, and so must be accounted for in client code. Similarly, while the Mueller index in `subset_indexer` has values in the set {0, 1, 2, 3}, these indexes correspond to the Mueller index values {0, 5, 10, 15} in a `CFBuffer` value. These mappings may be defined in many ways, but or the present example, we define the maps from `subset_indexer` indexes to `store` indexes as follows
```c++
unsigned w_map[]{W_0};
unsigned mueller_map[]{0, 5, 10, 15};
```
Finally we define the CF values through a `CFArray` instance with the appropriate element indexing operator (taking some liberties with C++ and CASA syntax):
```c++
class MyCFArray : public hpg::CFArray {
unsigned m_w_value;
static const unsigned m_mueller_map[]{0, 5, 10, 15};
static const hpg::CFSimpleIndexer m_subset_indexer = subset_indexer;
casa::CFStore m_store;
MyCFArray(unsigned w_value, const casa::CFStore& store)
: m_w_value(w_value)
, m_store(store) {}
value_type
operator()(unsigned x, unsigned y, unsigned mueller, unsigned cube, unsigned group)
const override {
hpg::CellIndex ci = m_subset_indexer({mueller, cube, group});
assert(ci.m_w_plane == 0);
assert(ci.m_mueller < 4);
return m_store(ci.m_baseline_class, ci.m_time, m_w_value, ci.m_frequency, m_mueller_map[ci.m_mueller], x, y);
}
};
```
\ No newline at end of file