11 const Vector<t_real> &w,
const Vector<t_complex> &weights,
12 const t_uint imsizey_,
const t_uint imsizex_,
13 const t_real oversample_ratio,
14 const std::function<t_real(t_real)> &ftkerneluv,
15 const std::function<t_real(t_real)> &kerneluv,
16 const t_uint Ju,
const t_uint Jw,
const t_real cellx,
17 const t_real celly,
const t_real abs_error,
18 const t_real rel_error,
const dde_type dde) {
19 const t_uint ftsizev_ = std::floor(imsizey_ * oversample_ratio);
20 const t_uint ftsizeu_ = std::floor(imsizex_ * oversample_ratio);
24 if (std::abs(du - dv) > 1e-6)
25 throw std::runtime_error(
26 "Field of view along l and m is not the same, this assumption is required for "
28 const t_uint rows =
u.size();
29 const t_uint cols = ftsizeu_ * ftsizev_;
30 if (
u.size() !=
v.size())
31 throw std::runtime_error(
32 "Size of u and v vectors are not the same for creating gridding matrix.");
33 if (
u.size() != w.size())
34 throw std::runtime_error(
35 "Size of u and w vectors are not the same for creating gridding matrix.");
36 if (
u.size() != weights.size())
37 throw std::runtime_error(
38 "Size of u and w vectors are not the same for creating gridding matrix.");
40 throw std::runtime_error(
41 "w kernel size must be at least the size of w=0 kernel, must have Ju <= Jw.");
43 Vector<t_int> total_coeffs = Vector<t_int>::Zero(w.size());
44 for (
int i = 0; i < w.size(); i++) {
47 total_coeffs(i) = Ju_max * Ju_max;
49 const t_real num_of_coeffs = total_coeffs.array().cast<t_real>().sum();
50 PURIFY_HIGH_LOG(
"Using {} rows (coefficients per a row {}), and memory of {} MegaBytes",
51 total_coeffs.size(), total_coeffs.array().cast<t_real>().mean(),
52 16. * num_of_coeffs / std::pow(10., 6));
55 interpolation_matrix.reserve(total_coeffs);
56 }
catch (std::bad_alloc e) {
57 throw std::runtime_error(
58 "Not enough memory for coefficients, choose upper limit on support size Jw.");
61 const t_complex
I(0., 1.);
63 const t_uint max_evaluations = 1e8;
64 const t_real relative_error = rel_error;
65 const t_real absolute_error = abs_error;
67 auto const ftkernel_radial = [&](
const t_real l) -> t_real {
return ftkerneluv(l); };
69 t_int coeffs_done = 0;
72 #pragma omp parallel for
73 for (t_int m = 0; m < rows; ++m) {
76 t_uint evaluations = 0;
77 const t_int kwu = std::floor(
u(m) - Ju_max * 0.5);
78 const t_int kwv = std::floor(
v(m) - Ju_max * 0.5);
79 const t_real w_val = w(m);
81 for (t_int ju = 1; ju < Ju_max + 1; ++ju) {
82 for (t_int jv = 1; jv < Ju_max + 1; ++jv) {
86 interpolation_matrix.insert(m, index) =
87 std::exp(-2 *
constant::pi *
I * ((kwu + ju) * 0.5 + (kwv + jv) * 0.5)) * weights(m) *
90 (
u(m) - (kwu + ju)), (
v(m) - (kwv + jv)), w_val, du, oversample_ratio,
91 ftkernel_radial, max_evaluations, absolute_error, relative_error,
94 (
u(m) - (kwu + ju)), (
v(m) - (kwv + jv)), w_val, du, dv, oversample_ratio,
95 ftkernel_radial, ftkernel_radial, max_evaluations, absolute_error,
97 #pragma omp critical(add_eval)
100 if (num_of_coeffs > 100) {
101 if ((coeffs_done % (
static_cast<t_int
>(num_of_coeffs / 100)) == 0)) {
103 "w = {}, support = {}x{}, coeffs: {} of {}, {}%", w_val, Ju_max, Ju_max,
104 coeffs_done, num_of_coeffs,
105 static_cast<t_real
>(coeffs_done) /
static_cast<t_real
>(num_of_coeffs) * 100.);
112 interpolation_matrix.makeCompressed();
113 return interpolation_matrix;
117 const t_uint imsizex_,
118 const std::function<t_real(t_real)> &ftkerneluv,
119 const t_real w_mean,
const t_real cellx,
120 const t_real celly) {
121 const t_uint ftsizeu_ = std::floor(imsizex_ * oversample_ratio);
122 const t_uint ftsizev_ = std::floor(imsizey_ * oversample_ratio);
123 const t_uint x_start = std::floor(ftsizeu_ * 0.5 - imsizex_ * 0.5);
124 const t_uint y_start = std::floor(ftsizev_ * 0.5 - imsizey_ * 0.5);
126 Image<t_complex> gridding_correction = Image<t_complex>::Zero(imsizey_, imsizex_);
127 for (
int i = 0; i < gridding_correction.rows(); i++)
128 for (
int j = 0; j < gridding_correction.cols(); j++)
129 gridding_correction(i, j) =
130 1. / ftkerneluv(std::sqrt(std::pow((y_start + i + 0.5) / ftsizev_ - 0.5, 2) +
131 std::pow((j + 0.5 + x_start) / ftsizeu_ - 0.5, 2)));
133 return gridding_correction.array() *
#define PURIFY_LOW_LOG(...)
Low priority message.
#define PURIFY_HIGH_LOG(...)
High priority message.
const std::vector< t_real > u
data for u coordinate
const std::vector< t_real > v
data for v coordinate
const t_real pi
mathematical constant
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)
Sparse< t_complex > init_gridding_matrix_2d(const Vector< t_real > &u, const Vector< t_real > &v, const Vector< t_complex > &weights, const t_uint &imsizey_, const t_uint &imsizex_, const t_real &oversample_ratio, const std::function< t_real(t_real)> kernelu, const std::function< t_real(t_real)> kernelv, const t_uint Ju, const t_uint Jv)
Construct gridding matrix.
t_complex exact_w_projection_integration_1d(const t_real u, const t_real v, const t_real w, const t_real du, const t_real oversample_ratio, const std::function< t_complex(t_real)> &ftkerneluv, const t_uint &max_evaluations, const t_real &absolute_error, const t_real &relative_error, const integration::method method, t_uint &evaluations)
t_complex exact_w_projection_integration(const t_real u, const t_real v, const t_real w, const t_real du, const t_real dv, const t_real oversample_ratio, const std::function< t_complex(t_real)> &ftkernelu, const std::function< t_complex(t_real)> &ftkernelv, const t_uint &max_evaluations, const t_real &absolute_error, const t_real &relative_error, const integration::method method, t_uint &evaluations)
numerical integration of chirp and kernel in image domain
t_int sub2ind(const t_int &row, const t_int &col, const t_int &rows, const t_int &cols)
Converts from subscript to index for matrix.
t_real mod(const t_real &x, const t_real &y)
Mod function modified to wrap circularly for negative numbers.
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 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 > 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.
dde_type
Types of DDEs in purify.
Eigen::SparseMatrix< T, Eigen::RowMajor, I > Sparse
A matrix of a given type.