1 #ifndef PURIFY_WPROJ_OPERATORS_H
2 #define PURIFY_WPROJ_OPERATORS_H
4 #include "purify/config.h"
15 const t_uint imsizex_,
16 const std::function<t_real(t_real)> &ftkerneluv,
17 const t_real w_mean,
const t_real cellx,
26 const std::function<t_real(t_real)> &ftkerneluv,
const t_uint imsizey,
const t_uint imsizex,
27 const t_real oversample_ratio,
const fftw_plan ft_plan,
const t_real w_mean,
const t_real cellx,
29 sopt::OperatorFunction<T> directZ, indirectZ;
30 sopt::OperatorFunction<T> directFFT, indirectFFT;
31 const Image<t_complex> S =
33 w_mean, cellx, celly) *
34 std::sqrt(imsizex * imsizey) * oversample_ratio;
37 "Constructing Zero Padding "
38 "and Correction Operator: "
42 std::tie(directZ, indirectZ) = purify::operators::init_zero_padding_2d<T>(S, oversample_ratio);
52 std::tie(directFFT, indirectFFT) =
53 purify::operators::init_FFT_2d<T>(imsizey, imsizex, oversample_ratio, ft_plan);
54 auto direct = sopt::chained_operators<T>(directFFT, directZ);
55 auto indirect = sopt::chained_operators<T>(indirectZ, indirectFFT);
56 return std::make_tuple(direct, indirect);
61 const Vector<t_real> &
u,
const Vector<t_real> &
v,
const Vector<t_real> &w,
62 const Vector<t_complex> &weights,
const t_uint &imsizey,
const t_uint &imsizex,
65 const t_real absolute_error,
const t_real relative_error,
const dde_type dde) {
66 sopt::OperatorFunction<T> directFZ, indirectFZ;
67 sopt::OperatorFunction<T> directG, indirectG;
68 t_real
const w_mean =
w_stacking ? w.array().mean() : 0;
72 std::tie(directFZ, indirectFZ) = base_padding_and_FFT_2d<T>(
73 std::get<0>(kerneluvs), imsizey, imsizex, oversample_ratio, ft_plan, w_mean, cellx, celly);
74 PURIFY_MEDIUM_LOG(
"FoV (width, height): {} deg x {} deg", imsizex * cellx / (60. * 60.),
75 imsizey * celly / (60. * 60.));
76 PURIFY_LOW_LOG(
"Constructing Weighting and Gridding Operators: WG");
78 PURIFY_MEDIUM_LOG(
"Mean, w: {}, +/- {}", w.array().mean(), (w.maxCoeff() - w.minCoeff()) * 0.5);
79 std::tie(directG, indirectG) = purify::operators::init_gridding_matrix_2d<T>(
80 u,
v, w.array() - w_mean, weights, imsizey, imsizex, oversample_ratio,
81 std::get<0>(kerneluvs), std::get<1>(kerneluvs), Ju, Jw, cellx, celly, absolute_error,
86 std::function<t_real(t_real)> kernelu, kernelv, ftkernelu, ftkernelv;
87 std::tie(kernelu, kernelv, ftkernelu, ftkernelv) =
89 std::tie(directFZ, indirectFZ) = base_padding_and_FFT_2d<T>(
90 ftkernelu, ftkernelv, imsizey, imsizex, oversample_ratio, ft_plan, w_mean, cellx, celly);
91 PURIFY_MEDIUM_LOG(
"FoV (width, height): {} deg x {} deg", imsizex * cellx / (60. * 60.),
92 imsizey * celly / (60. * 60.));
93 PURIFY_LOW_LOG(
"Constructing Weighting and Gridding Operators: WG");
95 PURIFY_MEDIUM_LOG(
"Mean, w: {}, +/- {}", w.array().mean(), (w.maxCoeff() - w.minCoeff()) * 0.5);
97 std::tie(directG, indirectG) = purify::operators::init_gridding_matrix_2d<T>(
98 u,
v, w.array() - w_mean, weights, imsizey, imsizex, oversample_ratio,
99 std::get<0>(kerneluvs), std::get<1>(kerneluvs), Ju, Jw, cellx, celly, absolute_error,
100 relative_error, dde);
104 throw std::runtime_error(
"DDE is not recognised.");
106 auto direct = sopt::chained_operators<T>(directG, directFZ);
107 auto indirect = sopt::chained_operators<T>(indirectFZ, indirectG);
109 return std::make_tuple(direct, indirect);
114 std::tuple<sopt::OperatorFunction<T>, sopt::OperatorFunction<T>>
115 base_mpi_all_to_all_degrid_operator_2d(
116 const sopt::mpi::Communicator &comm,
const std::vector<t_int> &image_index,
117 const std::vector<t_real> &w_stacks,
const Vector<t_real> &
u,
const Vector<t_real> &
v,
118 const Vector<t_real> &w,
const Vector<t_complex> &weights,
const t_uint &imsizey,
121 const t_real cellx,
const t_real celly,
const t_real absolute_error,
122 const t_real relative_error,
const dde_type dde) {
123 const t_uint number_of_images = comm.size();
124 if (std::any_of(image_index.begin(), image_index.end(), [&number_of_images](
int index) {
125 return index < 0 or index > (number_of_images - 1);
127 throw std::runtime_error(
"Image index is out of bounds");
128 const t_int local_grid_size =
129 std::floor(imsizex * oversample_ratio) * std::floor(imsizex * oversample_ratio);
130 sopt::OperatorFunction<T> directFZ, indirectFZ;
131 sopt::OperatorFunction<T> directG, indirectG;
132 t_real
const w_mean =
w_stacking ? w_stacks.at(comm.rank()) : 0.;
136 std::tie(directFZ, indirectFZ) = base_padding_and_FFT_2d<T>(
137 std::get<0>(kerneluvs), imsizey, imsizex, oversample_ratio, ft_plan, w_mean, cellx, celly);
138 PURIFY_MEDIUM_LOG(
"FoV (width, height): {} deg x {} deg", imsizex * cellx / (60. * 60.),
139 imsizey * celly / (60. * 60.));
140 PURIFY_LOW_LOG(
"Constructing Weighting and Gridding Operators: WG");
142 std::tie(directG, indirectG) =
143 purify::operators::init_gridding_matrix_2d_all_to_all<T, std::int64_t>(
144 comm,
static_cast<std::int64_t
>(local_grid_size),
145 static_cast<std::int64_t
>(comm.rank()) *
static_cast<std::int64_t
>(local_grid_size),
146 number_of_images, image_index,
147 (
w_stacking) ? w_stacks : std::vector<t_real>(comm.size(), 0.),
u,
v, w, weights,
148 imsizey, imsizex, oversample_ratio, std::get<0>(kerneluvs), std::get<1>(kerneluvs), Ju,
149 Jw, cellx, celly, absolute_error, relative_error, dde);
153 std::function<t_real(t_real)> kernelu, kernelv, ftkernelu, ftkernelv;
154 std::tie(kernelu, kernelv, ftkernelu, ftkernelv) =
156 std::tie(directFZ, indirectFZ) = base_padding_and_FFT_2d<T>(
157 ftkernelu, ftkernelv, imsizey, imsizex, oversample_ratio, ft_plan, w_mean, cellx, celly);
158 PURIFY_MEDIUM_LOG(
"FoV (width, height): {} deg x {} deg", imsizex * cellx / (60. * 60.),
159 imsizey * celly / (60. * 60.));
160 PURIFY_LOW_LOG(
"Constructing Weighting and Gridding Operators: WG");
163 std::tie(directG, indirectG) =
164 purify::operators::init_gridding_matrix_2d_all_to_all<T, std::int64_t>(
165 comm,
static_cast<std::int64_t
>(local_grid_size),
166 static_cast<std::int64_t
>(comm.rank()) *
static_cast<std::int64_t
>(local_grid_size),
167 number_of_images, image_index,
168 (
w_stacking) ? w_stacks : std::vector<t_real>(comm.size(), 0.),
u,
v, w, weights,
169 imsizey, imsizex, oversample_ratio, std::get<0>(kerneluvs), std::get<1>(kerneluvs), Ju,
170 Jw, cellx, celly, absolute_error, relative_error, dde);
174 throw std::runtime_error(
"DDE is not recognised.");
176 auto direct = sopt::chained_operators<T>(directG, directFZ);
177 auto indirect = sopt::chained_operators<T>(indirectFZ, indirectG);
179 return std::make_tuple(direct, indirect);
185 namespace measurementoperator {
190 const Vector<t_real> &
u,
const Vector<t_real> &
v,
const Vector<t_real> &w,
191 const Vector<t_complex> &weights,
const t_uint imsizey,
const t_uint imsizex,
193 const bool w_stacking,
const t_real cellx,
const t_real celly,
const t_real absolute_error,
194 const t_real relative_error,
const dde_type dde) {
196 std::array<t_int, 3> N = {0, 1,
static_cast<t_int
>(imsizey * imsizex)};
197 std::array<t_int, 3> M = {0, 1,
static_cast<t_int
>(
u.size())};
198 sopt::OperatorFunction<T> directDegrid, indirectDegrid;
199 std::tie(directDegrid, indirectDegrid) = purify::operators::base_degrid_operator_2d<T>(
200 u,
v, w, weights, imsizey, imsizex, oversample_ratio,
kernel, Ju, Jw, ft_plan,
w_stacking,
201 cellx, celly, absolute_error, relative_error, dde);
202 auto direct = directDegrid;
203 auto indirect = indirectDegrid;
204 return std::make_shared<sopt::LinearTransform<T>>(direct, M, indirect, N);
209 const t_real cell_x,
const t_real cell_y,
const t_real oversample_ratio,
211 const t_real absolute_error,
const t_real relative_error,
const dde_type dde) {
214 return init_degrid_operator_2d<T>(uv_vis.u, uv_vis.v, uv_vis.w, uv_vis.weights, imsizey, imsizex,
216 absolute_error, relative_error, dde);
222 const sopt::mpi::Communicator &comm,
const Vector<t_real> &
u,
const Vector<t_real> &
v,
223 const Vector<t_real> &w,
const Vector<t_complex> &weights,
const t_uint imsizey,
225 const t_uint Ju,
const t_uint Jw,
const bool w_stacking,
const t_real cellx,
const t_real celly,
226 const t_real absolute_error,
const t_real relative_error,
const dde_type dde) {
228 std::array<t_int, 3> N = {0, 1,
static_cast<t_int
>(imsizey * imsizex)};
229 std::array<t_int, 3> M = {0, 1,
static_cast<t_int
>(
u.size())};
230 sopt::OperatorFunction<T> directDegrid, indirectDegrid;
231 std::tie(directDegrid, indirectDegrid) = purify::operators::base_degrid_operator_2d<T>(
232 u,
v, w, weights, imsizey, imsizex, oversample_ratio,
kernel, Ju, Jw, ft_plan,
w_stacking,
233 cellx, celly, absolute_error, relative_error, dde);
234 const auto allsumall = purify::operators::init_all_sum_all<T>(comm);
235 auto direct = directDegrid;
236 auto indirect = sopt::chained_operators<T>(allsumall, indirectDegrid);
237 return std::make_shared<sopt::LinearTransform<T>>(direct, M, indirect, N);
242 const sopt::mpi::Communicator &comm,
const utilities::vis_params &uv_vis_input,
243 const t_uint imsizey,
const t_uint imsizex,
const t_real cell_x,
const t_real cell_y,
245 const bool w_stacking,
const t_real absolute_error,
const t_real relative_error,
249 return init_degrid_operator_2d<T>(comm, uv_vis.u, uv_vis.v, uv_vis.w, uv_vis.weights, imsizey,
251 cell_y, absolute_error, relative_error, dde);
255 std::shared_ptr<sopt::LinearTransform<T>> init_degrid_operator_2d_mpi(
256 const sopt::mpi::Communicator &comm,
const Vector<t_real> &
u,
const Vector<t_real> &
v,
257 const Vector<t_real> &w,
const Vector<t_complex> &weights,
const t_uint imsizey,
259 const t_uint Ju,
const t_uint Jw,
const bool w_stacking,
const t_real cellx,
const t_real celly,
260 const t_real absolute_error,
const t_real relative_error,
const dde_type dde) {
261 throw std::runtime_error(
"Under construction!");
263 std::array<t_int, 3> N = {0, 1,
static_cast<t_int
>(imsizey * imsizex)};
264 std::array<t_int, 3> M = {0, 1,
static_cast<t_int
>(
u.size())};
265 sopt::OperatorFunction<T> directDegrid, indirectDegrid;
266 std::tie(directDegrid, indirectDegrid) = purify::operators::base_degrid_operator_2d<T>(
267 u,
v, w, weights, imsizey, imsizex, oversample_ratio,
kernel, Ju, Jw, ft_plan,
w_stacking,
268 cellx, celly, absolute_error, relative_error, dde);
269 const auto allsumall = purify::operators::init_all_sum_all<T>(comm);
270 auto direct = directDegrid;
271 auto indirect = sopt::chained_operators<T>(allsumall, indirectDegrid);
272 return std::make_shared<sopt::LinearTransform<T>>(direct, M, indirect, N);
276 std::shared_ptr<sopt::LinearTransform<T>> init_degrid_operator_2d_mpi(
277 const sopt::mpi::Communicator &comm,
const utilities::vis_params &uv_vis_input,
278 const t_uint imsizey,
const t_uint imsizex,
const t_real cell_x,
const t_real cell_y,
280 const bool w_stacking,
const t_real absolute_error,
const t_real relative_error,
284 return init_degrid_operator_2d<T>(comm, uv_vis.u, uv_vis.v, uv_vis.w, uv_vis.weights, imsizey,
286 cell_y, absolute_error, relative_error, dde);
291 std::shared_ptr<sopt::LinearTransform<T>> init_degrid_operator_2d_all_to_all(
292 const sopt::mpi::Communicator &comm,
const std::vector<t_int> &image_index,
293 const std::vector<t_real> &w_stacks,
const Vector<t_real> &
u,
const Vector<t_real> &
v,
294 const Vector<t_real> &w,
const Vector<t_complex> &weights,
const t_uint imsizey,
296 const t_uint Ju,
const t_uint Jw,
const bool w_stacking,
const t_real cellx,
const t_real celly,
297 const t_real absolute_error,
const t_real relative_error,
const dde_type dde) {
299 std::array<t_int, 3> N = {0, 1,
static_cast<t_int
>(imsizey * imsizex)};
300 std::array<t_int, 3> M = {0, 1,
static_cast<t_int
>(
u.size())};
301 sopt::OperatorFunction<T> directDegrid, indirectDegrid;
302 std::tie(directDegrid, indirectDegrid) =
303 purify::operators::base_mpi_all_to_all_degrid_operator_2d<T>(
304 comm, image_index, w_stacks,
u,
v, w, weights, imsizey, imsizex, oversample_ratio,
kernel,
305 Ju, Jw, ft_plan,
w_stacking, cellx, celly, absolute_error, relative_error, dde);
306 const auto allsumall = purify::operators::init_all_sum_all<T>(comm);
307 auto direct = directDegrid;
308 auto indirect = sopt::chained_operators<T>(allsumall, indirectDegrid);
309 return std::make_shared<sopt::LinearTransform<T>>(direct, M, indirect, N);
314 std::shared_ptr<sopt::LinearTransform<T>> init_degrid_operator_2d_all_to_all(
315 const sopt::mpi::Communicator &comm,
const std::vector<t_int> &image_index,
316 const std::vector<t_real> &w_stacks,
const utilities::vis_params &uv_vis_input,
317 const t_uint imsizey,
const t_uint imsizex,
const t_real cell_x,
const t_real cell_y,
319 const bool w_stacking,
const t_real absolute_error,
const t_real relative_error,
323 return init_degrid_operator_2d_all_to_all<T>(comm, image_index, w_stacks, uv_vis.u, uv_vis.v,
324 uv_vis.w, uv_vis.weights, imsizey, imsizex,
326 cell_y, absolute_error, relative_error, dde);
#define PURIFY_LOW_LOG(...)
Low priority message.
#define PURIFY_MEDIUM_LOG(...)
Medium priority message.
const std::vector< t_real > u
data for u coordinate
const std::vector< t_real > v
data for v coordinate
Image< t_complex > init_correction_radial_2d(const t_real oversample_ratio, const t_uint imsizey_, const t_uint imsizex_, const std::function< t_real(t_real)> &ftkerneluv, const t_real w_mean, const t_real cellx, const t_real celly)
std::shared_ptr< sopt::LinearTransform< T > > init_degrid_operator_2d(const Vector< t_real > &u, const Vector< t_real > &v, const Vector< t_real > &w, const Vector< t_complex > &weights, const t_uint &imsizey, const t_uint &imsizex, const t_real &oversample_ratio=2, const kernels::kernel kernel=kernels::kernel::kb, const t_uint Ju=4, const t_uint Jv=4, const bool w_stacking=false, const t_real &cellx=1, const t_real &celly=1)
Returns linear transform that is the standard degridding operator.
fftw_plan
enum for fftw plans
std::tuple< sopt::OperatorFunction< T >, sopt::OperatorFunction< T > > base_padding_and_FFT_2d(const std::function< t_real(t_real)> &ftkernelu, const std::function< t_real(t_real)> &ftkernelv, const t_uint &imsizey, const t_uint &imsizex, const t_real &oversample_ratio=2, const fftw_plan &ft_plan=fftw_plan::measure, const t_real &w_mean=0, const t_real &cellx=1, const t_real &celly=1)
std::tuple< sopt::OperatorFunction< T >, sopt::OperatorFunction< T > > base_degrid_operator_2d(const Vector< t_real > &u, const Vector< t_real > &v, const Vector< t_real > &w, const Vector< t_complex > &weights, const t_uint &imsizey, const t_uint &imsizex, const t_real &oversample_ratio=2, const kernels::kernel kernel=kernels::kernel::kb, const t_uint Ju=4, const t_uint Jv=4, const fftw_plan &ft_plan=fftw_plan::measure, const bool w_stacking=false, const t_real &cellx=1, const t_real &celly=1, const bool on_the_fly=true)
utilities::vis_params w_stacking(utilities::vis_params const ¶ms, sopt::mpi::Communicator const &comm, const t_int iters, const std::function< t_real(t_real)> &cost, const t_real k_means_rel_diff)
utilities::vis_params convert_to_pixels(const utilities::vis_params &uv_vis, const t_real cell_x, const t_real cell_y, const t_real imsizex, const t_real imsizey, const t_real oversample_ratio)
Converts u and v coordaintes to units of pixels.
std::tuple< std::function< t_real(t_real)>, std::function< t_real(t_real)> > create_radial_ftkernel(const kernels::kernel kernel_name_, const t_uint Ju_, const t_real oversample_ratio)
std::tuple< std::function< t_real(t_real)>, std::function< t_real(t_real)>, std::function< t_real(t_real)>, std::function< t_real(t_real)> > create_kernels(const kernels::kernel kernel_name_, const t_uint Ju_, const t_uint Jv_, const t_real imsizey_, const t_real imsizex_, const t_real oversample_ratio)
dde_type
Types of DDEs in purify.