PURIFY
Next-generation radio interferometric imaging
wide_field_utilities.cc
Go to the documentation of this file.
2 #include "purify/utilities.h"
3 
4 namespace purify {
5 namespace widefield {
6 
7 t_int w_support(const t_real w, const t_real du, const t_int min, const t_int max) {
8  return std::min<int>(std::max<int>(static_cast<int>(2 * std::floor(std::abs(w / du))), min), max);
9 }
10 
11 t_real pixel_to_lambda(const t_real cell, const t_uint imsize, const t_real oversample_ratio) {
12  return 1. / (oversample_ratio * fov_cosine(cell, imsize));
13 }
14 
15 t_real estimate_cell_size(const t_real max_u, const t_uint imsize, const t_real oversample_ratio) {
16  return (2. / static_cast<t_real>(imsize)) *
17  std::asin(static_cast<t_real>(imsize) / (4 * oversample_ratio * max_u)) * 60. * 60. *
18  180. / constant::pi;
19 }
20 
21 t_real fov_cosine(t_real const cell, t_uint const imsize) {
22  const t_real theta_FoV_L = imsize * cell;
23  const t_real extra_theta = (theta_FoV_L > 180. * 60. * 60.) ? theta_FoV_L - 180. * 60. * 60. : 0.;
24  return 2 * std::sin(constant::pi / 180. * (theta_FoV_L - extra_theta) / (60. * 60.) * 0.5) +
25  2 * std::sin(constant::pi / 180. * extra_theta / (60. * 60.) * 0.5);
26 }
27 
28 t_real equivalent_miriad_cell_size(const t_real cell, const t_uint imsize,
29  const t_real oversample_ratio) {
30  const t_real du = pixel_to_lambda(cell, imsize, oversample_ratio);
31  return 60. * 60. * 180. / (static_cast<t_real>(imsize) * oversample_ratio * du * constant::pi);
32 }
33 
34 Matrix<t_complex> generate_chirp(const t_real w_rate, const t_real cell_x, const t_real cell_y,
35  const t_uint x_size, const t_uint y_size) {
36  return generate_chirp([](t_real, t_real) { return 1.; }, w_rate, cell_x, cell_y, x_size, y_size);
37 }
38 
39 Matrix<t_complex> estimate_sample_density(const Vector<t_real> &u, const Vector<t_real> &v,
40  const t_real cellx, const t_real celly,
41  const t_uint imsizex, const t_uint imsizey,
42  const t_real oversample_ratio, const t_real scale) {
43  const t_int ftsizeu = std::floor(oversample_ratio * imsizex);
44  const t_int ftsizev = std::floor(oversample_ratio * imsizex);
45  Matrix<t_complex> sample_density = Matrix<t_complex>::Zero(ftsizev, ftsizeu);
46  const t_real du = pixel_to_lambda(cellx, imsizex, oversample_ratio) * scale;
47  const t_real dv = pixel_to_lambda(celly, imsizey, oversample_ratio) * scale;
48  for (t_int i = 0; i < u.size(); ++i) {
49  const t_int q = utilities::mod(floor(u(i) * du), ftsizeu);
50  const t_int p = utilities::mod(floor(v(i) * dv), ftsizev);
51  sample_density(p, q) += 1.;
52  }
53  return sample_density;
54 }
55 
56 Vector<t_complex> sample_density_weights(const Vector<t_real> &u, const Vector<t_real> &v,
57  const t_real cellx, const t_real celly,
58  const t_uint imsizex, const t_uint imsizey,
59  const t_real oversample_ratio, const t_real scale) {
60  Vector<t_complex> weights = Vector<t_complex>::Zero(u.size());
61  const t_int ftsizeu = std::floor(oversample_ratio * imsizex);
62  const t_int ftsizev = std::floor(oversample_ratio * imsizex);
63  const Matrix<t_complex> sample_density =
64  estimate_sample_density(u, v, cellx, celly, imsizex, imsizey, oversample_ratio, scale);
65  const t_real du = pixel_to_lambda(cellx, imsizex, oversample_ratio) * scale;
66  const t_real dv = pixel_to_lambda(celly, imsizey, oversample_ratio) * scale;
67  for (t_int i = 0; i < u.size(); ++i) {
68  const t_int q = utilities::mod(floor(u(i) * du), ftsizeu);
69  const t_int p = utilities::mod(floor(v(i) * dv), ftsizev);
70  weights(i) = 1. / sample_density(p, q);
71  }
72  const t_real max_weight = weights.array().cwiseAbs().maxCoeff();
73  weights /= max_weight;
74  return weights;
75 }
76 #ifdef PURIFY_MPI
77 Vector<t_complex> sample_density_weights(const Vector<t_real> &u, const Vector<t_real> &v,
78  const t_real cellx, const t_real celly,
79  const t_uint imsizex, const t_uint imsizey,
80  const t_real oversample_ratio, const t_real scale,
81  const sopt::mpi::Communicator &comm) {
82  Vector<t_complex> weights = Vector<t_complex>::Zero(u.size());
83  const t_int ftsizeu = std::floor(oversample_ratio * imsizex);
84  const t_int ftsizev = std::floor(oversample_ratio * imsizex);
85  const Matrix<t_complex> sample_density = comm.all_sum_all(
86  estimate_sample_density(u, v, cellx, celly, imsizex, imsizey, oversample_ratio, scale));
87  const t_real du = pixel_to_lambda(cellx, imsizex, oversample_ratio) * scale;
88  const t_real dv = pixel_to_lambda(celly, imsizey, oversample_ratio) * scale;
89  for (t_int i = 0; i < u.size(); ++i) {
90  const t_int q = utilities::mod(floor(u(i) * du), ftsizeu);
91  const t_int p = utilities::mod(floor(v(i) * dv), ftsizev);
92  weights(i) = 1. / sample_density(p, q);
93  }
94  const t_real max_weight = comm.all_reduce<t_real>(weights.array().cwiseAbs().maxCoeff(), MPI_MAX);
95  weights /= max_weight;
96  return weights;
97 }
98 #endif
99 } // namespace widefield
100 } // namespace purify
const std::vector< t_real > u
data for u coordinate
Definition: operators.cc:18
const std::vector< t_real > v
data for v coordinate
Definition: operators.cc:20
const t_real pi
mathematical constant
Definition: types.h:70
t_real mod(const t_real &x, const t_real &y)
Mod function modified to wrap circularly for negative numbers.
Definition: utilities.cc:41
t_real fov_cosine(t_real const cell, t_uint const imsize)
Work out max L and M directional cosines from image parameters.
t_int w_support(const t_real w, const t_real du, const t_int min, const t_int max)
estimate support size of w given u resolution du
t_real equivalent_miriad_cell_size(const t_real cell, const t_uint imsize, const t_real oversample_ratio)
for a given purify cell size in arcsec provide the equivalent miriad cell size in arcsec
Vector< t_complex > sample_density_weights(const Vector< t_real > &u, const Vector< t_real > &v, const t_real cellx, const t_real celly, const t_uint imsizex, const t_uint imsizey, const t_real oversample_ratio, const t_real scale)
create sample density weights for a given field of view, uniform weighting
t_real pixel_to_lambda(const t_real cell, const t_uint imsize, const t_real oversample_ratio)
return factors to convert between arcsecond pixel size image space and lambda for uv space
Matrix< t_complex > estimate_sample_density(const Vector< t_real > &u, const Vector< t_real > &v, const t_real cellx, const t_real celly, const t_uint imsizex, const t_uint imsizey, const t_real oversample_ratio, const t_real scale)
estimate sample desity grid for a given field of view
Matrix< t_complex > generate_chirp(const t_real w_rate, const t_real cell_x, const t_real cell_y, const t_uint x_size, const t_uint y_size)
Generates image of chirp.
t_real estimate_cell_size(const t_real max_u, const t_uint imsize, const t_real oversample_ratio)
return cell size from the bandwidth