PURIFY
Next-generation radio interferometric imaging
wide_field_utilities.cc
Go to the documentation of this file.
1 #include "purify/config.h"
2 #include <iostream>
3 #include "catch2/catch_all.hpp"
4 #include "purify/logging.h"
5 
6 #include "purify/types.h"
7 
8 #include "purify/convolution.h"
9 #include "purify/directories.h"
10 #include "purify/kernels.h"
11 #include "purify/uvw_utilities.h"
13 
14 using namespace purify;
15 using Catch::Approx;
16 
17 TEST_CASE("uvw units") {
18  const t_uint imsizex = 128;
19  const t_uint imsizey = 128;
20  const t_real oversample_ratio = 2;
21 
22  SECTION("1arcsec") {
23  const utilities::vis_params uv_lambda(Vector<t_real>::Ones(5), Vector<t_real>::Ones(5),
24  Vector<t_real>::Ones(5), Vector<t_complex>::Ones(5),
25  Vector<t_complex>::Ones(5));
26  auto const uv_radians = utilities::set_cell_size(uv_lambda, 1., 1.);
27  auto const uv_pixels = utilities::uv_scale(uv_radians, std::floor(oversample_ratio * imsizex),
28  std::floor(oversample_ratio * imsizey));
29  CHECK(uv_radians.units == utilities::vis_units::radians);
31  CHECK(uv_pixels.units == utilities::vis_units::pixels);
32  // const t_real scale = 60. * 60. * 180. / std::floor(oversample_ratio * imsizex) /
33  // constant::pi;
34  const t_real scale = widefield::pixel_to_lambda(1., imsizex, oversample_ratio);
35  CAPTURE(1. / scale);
36  CAPTURE(uv_pixels.u.transpose());
37  CHECK(uv_lambda.u.isApprox(uv_pixels.u * scale, 1e-6));
38  CHECK(
39  1. ==
40  Approx(widefield::equivalent_miriad_cell_size(1., imsizex, oversample_ratio)).margin(1e-4));
41  }
42  SECTION("arcsec") {
43  const t_real cell = 3;
44  const utilities::vis_params uv_lambda(Vector<t_real>::Ones(5), Vector<t_real>::Ones(5),
45  Vector<t_real>::Ones(5), Vector<t_complex>::Ones(5),
46  Vector<t_complex>::Ones(5));
47  auto const uv_radians = utilities::set_cell_size(uv_lambda, cell, cell);
48  auto const uv_pixels = utilities::uv_scale(uv_radians, std::floor(oversample_ratio * imsizex),
49  std::floor(oversample_ratio * imsizey));
50  CHECK(uv_radians.units == utilities::vis_units::radians);
52  CHECK(uv_pixels.units == utilities::vis_units::pixels);
53  // const t_real scale
54  // = 60. * 60. * 180. / cell / std::floor(oversample_ratio * imsizex) / constant::pi;
55  const t_real scale = widefield::pixel_to_lambda(cell, imsizex, oversample_ratio);
56  CAPTURE(1. / scale);
57  CAPTURE(uv_pixels.u.transpose());
58  CHECK(uv_lambda.u.isApprox(uv_pixels.u * scale, 1e-6));
59  CHECK(3. == Approx(widefield::equivalent_miriad_cell_size(cell, imsizex, oversample_ratio))
60  .margin(1e-4));
61  }
62 }
63 
64 TEST_CASE("test cell size conversion") {
65  const t_real oversample_ratio = 2;
66  const t_int imsize = 8192;
67  for (t_real FoV : {0.1, 0.2, 0.3, 0.4, 0.5, 1., 5., 10., 15., 20., 25., 30., 40., 50., 60., 70.,
68  80., 90., 120.}) {
69  const t_real cell = FoV / imsize * 60 * 60;
70  const t_real miriad_cell =
71  widefield::equivalent_miriad_cell_size(cell, imsize, oversample_ratio);
72  CAPTURE(cell);
73  CAPTURE(miriad_cell);
74  CAPTURE(FoV);
75  CAPTURE(miriad_cell * imsize / 60. / 60.);
76  CAPTURE((1 - miriad_cell * imsize / 60. / 60. / FoV) * FoV);
77  if (FoV < 0.5)
78  CHECK(cell == Approx(miriad_cell).margin(1e-12));
79  else
80  CHECK(cell > miriad_cell);
81  }
82 }
83 
84 TEST_CASE("Calcuate DDE Image") {
85  const t_int imsizex = 128;
86  const t_int imsizey = 128;
87  SECTION("w is zero") {
88  const t_real w_rate = 0;
89  const Image<t_complex> chirp_image =
90  widefield::generate_dde([](t_real, t_real) { return 1.; }, 1, 1, imsizex, imsizey, 0);
91  REQUIRE(chirp_image.cols() == imsizex);
92  REQUIRE(chirp_image.rows() == imsizey);
93  REQUIRE(chirp_image.isApprox(Image<t_complex>::Constant(imsizey, imsizex, 1)));
94  }
95 }
96 
97 TEST_CASE("estimate_sample_density") {
98  const t_int imsizex = 1024;
99  const t_int imsizey = 1024;
100  const t_real cellx = 10;
101  const t_real celly = 10;
102  const t_real oversample_ratio = 2;
103  const t_int M = 6;
104  const Vector<t_real> u = Vector<t_real>::Random(M) * 1000;
105  const Vector<t_real> v = Vector<t_real>::Random(M) * 1000;
106 
107  const Vector<t_complex> weights =
108  widefield::sample_density_weights(u, v, cellx, celly, imsizex, imsizey, oversample_ratio, 1);
109  REQUIRE(weights.size() == M);
110  CHECK(weights.isApprox(Vector<t_complex>::Ones(weights.size())));
111 }
#define CHECK(CONDITION, ERROR)
Definition: casa.cc:6
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
utilities::vis_params uv_scale(const utilities::vis_params &uv_vis, const t_int &sizex, const t_int &sizey)
scales the visibilities to units of pixels
utilities::vis_params set_cell_size(const sopt::mpi::Communicator &comm, utilities::vis_params const &uv_vis, const t_real &cell_x, const t_real &cell_y)
Matrix< t_complex > generate_dde(const DDE &dde, const t_real cell_x, const t_real cell_y, const t_uint x_size, const t_uint y_size, const t_real stop_gap)
Generate image of DDE for aw-stacking.
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
TEST_CASE("uvw units")