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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
#ifndef WSCLEAN_IMAGING_TABLE_H
#define WSCLEAN_IMAGING_TABLE_H
#include "imagingtableentry.h"
#include <functional>
#include <memory>
#include <vector>
#include <radler/work_table.h>
namespace wsclean {
/**
* The ImagingTable contains ImagingTableEntry's and supports creating subtables
* with entries that have the same attribute.
* It supports the following grouping types:
* - IndependentGroup : Entries have an equal joinedGroupIndex in each group.
* - FacetGroup : Entries have an equal facetGroupIndex in each group.
* Each group thus contains all entries that form a single image.
* - Facet : Entries have an equal facetIndex in each group.
* Each group thus contains all entries for a single facet.
* - SquaredGroup : Entries have an equal squaredDeconvolutionIndex in each
* group.
*/
class ImagingTable {
public:
using EntryPtr = std::shared_ptr<ImagingTableEntry>;
using Group = std::vector<EntryPtr>;
using Groups = std::vector<Group>;
/**
* Iterator class for looping over entries.
*
* Dereferencing this iterator yields a reference to the actual object instead
* of a reference to the shared pointer for the object.
*/
class EntryIterator {
using BaseIterator = Group::const_iterator;
public:
explicit EntryIterator(BaseIterator baseIt) : _baseIterator(baseIt) {}
ImagingTableEntry& operator*() { return **_baseIterator; }
const ImagingTableEntry& operator*() const { return **_baseIterator; }
ImagingTableEntry* operator->() { return _baseIterator->get(); }
const ImagingTableEntry* operator->() const { return _baseIterator->get(); }
void operator++() { ++_baseIterator; }
bool operator!=(const EntryIterator& other) const {
return _baseIterator != other._baseIterator;
}
bool operator==(const EntryIterator& other) const {
return _baseIterator == other._baseIterator;
}
private:
BaseIterator _baseIterator;
};
ImagingTable() = default;
ImagingTable(const ImagingTable& other,
std::function<bool(const ImagingTableEntry&)> isSelected);
explicit ImagingTable(const Group& entries);
size_t IndependentGroupCount() const { return _independentGroups.size(); }
ImagingTable GetIndependentGroup(size_t index) const {
return ImagingTable(_independentGroups[index]);
}
size_t SquaredGroupCount() const { return _squaredGroups.size(); }
ImagingTable GetSquaredGroup(size_t index) const {
return ImagingTable(_squaredGroups[index]);
}
const Groups& SquaredGroups() const { return _squaredGroups; }
// When an imagingtable is split into different tables, a facetGroupIndex may
// be greater-equal than FacetGroupCount(). Since facetGroupIndices are used
// for acquiring scheduler locks, always use (MaxFacetGroupIndex() + 1) for
// determining the number of scheduler locks.
size_t MaxFacetGroupIndex() const { return _entries.back()->facetGroupIndex; }
/**
* Groups the entries per facet group.
* Each group holds all entries for one image.
* @param is_selected Selection function. The default selection
* function omits direction dependent PSF entries from the result.
*/
Groups FacetGroups(std::function<bool(const ImagingTableEntry&)> is_selected =
[](const ImagingTableEntry& e) {
return !e.isDdPsf;
}) const {
return CreateGroups(
[](const ImagingTableEntry& e) { return e.facetGroupIndex; },
is_selected);
}
size_t FacetCount() const { return _facets.size(); }
ImagingTable GetFacet(size_t index) const {
return ImagingTable(_facets[index]);
}
const Groups& Facets() const { return _facets; }
size_t EntryCount() const { return _entries.size(); }
ImagingTableEntry& operator[](size_t index) { return *_entries[index]; }
const ImagingTableEntry& operator[](size_t index) const {
return *_entries[index];
}
const EntryIterator begin() const { return EntryIterator(_entries.begin()); }
EntryIterator begin() { return EntryIterator(_entries.begin()); }
const EntryIterator end() const { return EntryIterator(_entries.end()); }
EntryIterator end() { return EntryIterator(_entries.end()); }
void Clear() {
_entries.clear();
_independentGroups.clear();
_facets.clear();
_squaredGroups.clear();
}
void AddEntry(std::unique_ptr<ImagingTableEntry> entry) {
entry->index = _entries.size();
_entries.push_back(std::move(entry));
}
void Update() {
_independentGroups = CreateGroups(
[](const ImagingTableEntry& e) { return e.joinedGroupIndex; });
_facets =
CreateGroups([](const ImagingTableEntry& e) { return e.facetIndex; },
[](const ImagingTableEntry& e) { return !e.isDdPsf; });
_squaredGroups = CreateGroups(
[](const ImagingTableEntry& e) { return e.squaredDeconvolutionIndex; });
}
void Print() const;
ImagingTableEntry& Front() { return *_entries.front(); }
const ImagingTableEntry& Front() const { return *_entries.front(); }
/**
* Copies all fields that are set by the gridding results from one
* polarization to all other polarizations.
*/
void AssignGridDataFromPolarization(aocommon::PolarizationEnum polarization);
std::unique_ptr<radler::WorkTable> CreateDeconvolutionTable(
int n_deconvolution_channels, CachedImageSet& psf_images,
CachedImageSet& model_images, CachedImageSet& residual_images) const;
private:
static void PrintEntry(const ImagingTableEntry& entry);
Groups CreateGroups(
std::function<size_t(const ImagingTableEntry&)> getIndex,
std::function<bool(const ImagingTableEntry&)> isSelected =
[](const ImagingTableEntry&) { return true; }) const;
Group _entries;
Groups _independentGroups;
Groups _facets;
/**
* Item i will contain a Group for which each entry has a
* squaredDeconvolutionIndex equal to i.
*/
Groups _squaredGroups;
};
} // namespace wsclean
#endif
|