7 std::vector<t_uint> ind;
8 for (t_uint i = 0; i < uv_data.
size(); i++) ind.push_back(i);
9 std::sort(ind.begin(), ind.end(),
10 [&](
const t_uint a,
const t_uint b) { return uv_data.w(a) < uv_data.w(b); });
11 for (t_uint i = 0; i < uv_data.
size(); i++) {
12 output.
u(i) = uv_data.
u(ind.at(i));
13 output.
v(i) = uv_data.
v(ind.at(i));
14 output.
w(i) = uv_data.
w(ind.at(i));
16 output.
vis(i) = uv_data.
vis(ind.at(i));
21 namespace wproj_utilities {
23 std::set<t_uint> w_rows_set;
24 for (t_int k = 0; k < w_degrider.outerSize(); ++k) {
29 w_rows_set.insert(it.col());
33 std::vector<t_uint>
w_rows(w_rows_set.begin(), w_rows_set.end());
37 std::tuple<t_real, t_real>
fov_cosines(t_real
const &cell_x, t_real
const &cell_y,
38 t_uint
const &x_size, t_uint
const &y_size) {
44 const t_real theta_FoV_L = cell_x * x_size;
45 const t_real theta_FoV_M = cell_y * y_size;
46 const t_real L = 2 * std::sin(
pi / 180. * theta_FoV_L / (60. * 60.) * 0.5);
47 const t_real M = 2 * std::sin(
pi / 180. * theta_FoV_M / (60. * 60.) * 0.5);
48 return std::make_tuple(L, M);
51 Matrix<t_complex>
generate_dde(
const std::function<t_complex(t_real, t_real)> &dde,
52 const t_real &cell_x,
const t_real &cell_y,
const t_uint &x_size,
53 const t_uint &y_size) {
58 auto const LM =
fov_cosines(cell_x, cell_y, x_size, y_size);
60 const t_real L = std::get<0>(LM);
61 const t_real M = std::get<1>(LM);
63 const t_real delt_x = L / x_size;
64 const t_real delt_y = M / y_size;
65 Image<t_complex> chirp(y_size, x_size);
67 for (t_int l = 0; l < x_size; ++l)
68 for (t_int m = 0; m < y_size; ++m) {
69 const t_real x = (l + 0.5 - x_size * 0.5) * delt_x;
70 const t_real y = (m + 0.5 - y_size * 0.5) * delt_y;
71 chirp(l, m) = dde(y, x);
76 Matrix<t_complex>
generate_chirp(
const std::function<t_complex(t_real, t_real)> &dde,
77 const t_real &w_rate,
const t_real &cell_x,
const t_real &cell_y,
78 const t_uint &x_size,
const t_uint &y_size) {
85 const t_real nz = y_size * x_size;
86 const t_complex
I(0, 1);
88 const auto chirp = [=](
const t_real &y,
const t_real &x) {
89 return dde(y, x) * (std::exp(-2 *
pi *
I * w_rate * (std::sqrt(1 - x * x - y * y) - 1))) / nz;
91 auto primary_beam = [=](
const t_real &x,
const t_real &y) {
92 return 1. / std::sqrt(1 - x * x - y * y);
94 const auto chirp_approx = [=](
const t_real &y,
const t_real &x) {
95 return dde(y, x) * (std::exp(2 *
pi *
I * w_rate * (x * x + y * y))) / nz;
97 return generate_dde(chirp, cell_x, cell_y, x_size, y_size);
99 Matrix<t_complex>
generate_chirp(
const t_real &w_rate,
const t_real &cell_x,
const t_real &cell_y,
100 const t_uint &x_size,
const t_uint &y_size) {
107 return generate_chirp([](
const t_real &,
const t_real &) {
return 1.; }, w_rate, cell_x, cell_y,
111 const t_uint &ftsizev,
const t_uint &ftsizeu,
112 const t_real &energy_fraction,
113 const sopt::OperatorFunction<Vector<t_complex>> &fftop) {
114 const Matrix<t_complex> chirp =
116 return create_chirp_row(Vector<t_complex>::Map(chirp.data(), chirp.size()), energy_fraction,
120 const t_real &energy_fraction,
121 const sopt::OperatorFunction<Vector<t_complex>> &fftop) {
122 Vector<t_complex> chirp;
123 #pragma omp critical(fft)
124 fftop(chirp, chirp_image);
125 chirp *= std::sqrt(chirp.size());
127 assert(chirp.norm() > 0);
128 const t_real row_max = chirp.cwiseAbs().maxCoeff();
133 const t_uint &y_size,
const Vector<t_real> &w_components,
134 const t_real &cell_x,
const t_real &cell_y,
135 const t_real &energy_fraction_chirp,
136 const t_real &energy_fraction_wproj,
138 const t_real &interpolation_error) {
139 const t_uint Npix = x_size * y_size;
140 const t_uint Nvis = w_components.size();
143 std::sqrt(std::pow(w_components.norm(), 2) / Nvis -
144 std::pow(w_components.array().mean(), 2)));
145 PURIFY_HIGH_LOG(
"Mean of w components {} ", w_components.array().mean());
146 PURIFY_HIGH_LOG(
"Hard-thresholding of the chirp kernels: energy [{}] ", energy_fraction_chirp);
147 PURIFY_HIGH_LOG(
"Hard-thresholding of the rows of G: energy [{}] ", energy_fraction_wproj);
150 const auto fftop_ = operators::init_FFT_2d<Vector<t_complex>>(y_size, x_size, 1., ft_plan);
154 t_uint total_non_zero = 0;
155 GW.reserve(G.nonZeros() * 1e3);
156 #pragma omp parallel for
157 for (t_int m = 0; m < G.rows(); m++) {
159 create_chirp_row(w_components(m), cell_x, cell_y, x_size, y_size, energy_fraction_chirp,
160 std::get<0>(fftop_));
164 kernel.prune([&](
const t_uint &i,
const t_uint &j,
const t_complex &value) {
165 return std::abs(value) > thres;
167 assert(
kernel.cols() > 0);
168 assert(
kernel.rows() == 1);
174 total_non_zero +=
kernel.nonZeros();
178 PURIFY_DEBUG(
"With {} entries non zero, which is {} entries per a row.", total_non_zero,
179 static_cast<t_real
>(total_non_zero) / counts);
182 assert(GW.nonZeros() > 0);
184 PURIFY_DEBUG(
"DONE - With {} entries non zero, which is {} entries per a row.", GW.nonZeros(),
185 static_cast<t_real
>(GW.nonZeros()) / GW.rows());
190 t_real
snr_metric(
const Image<t_real> &model,
const Image<t_real> &solution) {
194 t_real nm = model.matrix().norm();
195 t_real ndiff = (model - solution).matrix().norm();
196 t_real val = 20 * std::log10(nm / ndiff);
199 t_real
mr_metric(
const Image<t_real> &model,
const Image<t_real> &solution) {
203 t_int Npix = model.rows() * model.cols();
204 Image<t_real> model_ = model.array() + 1e-10;
205 Image<t_real> solution_ = solution.array() + 1e-10;
206 Image<t_real> model_sol = model_.matrix().cwiseQuotient(solution_.matrix());
207 Image<t_real> sol_model = solution_.matrix().cwiseQuotient(model_.matrix());
208 Image<t_real> min_ratio = sol_model.matrix().cwiseMin(model_sol.matrix());
209 t_real val = min_ratio.array().sum() / Npix;
214 const t_real &
mean) {
218 Matrix<t_complex> chirp = Image<t_complex>::Zero(y_size, x_size);
224 for (
int x = 0; x < W; ++x) {
225 for (
int y = 0; y < W; ++y) {
231 exp(-0.5 * (xx / (sigma * sigma) +
232 yy / (sigma * sigma)));
233 if (std::abs(val) > 1e-5)
240 chirp.resize(x_size * y_size, 1);
#define PURIFY_HIGH_LOG(...)
High priority message.
#define PURIFY_DEBUG(...)
\macro Output some debugging
const t_real pi
mathematical constant
K::Scalar mean(const K x)
Calculate mean of vector.
vis_params sort_by_w(const vis_params &uv_data)
Sort visibilities to be from w_max to w_min.
series
Type of series approximation.
std::vector< t_uint > w_rows(const Sparse< t_complex > &w_degrider)
t_real snr_metric(const Image< t_real > &model, const Image< t_real > &solution)
SNR calculation.
Matrix< t_complex > generate_chirp(const std::function< t_complex(t_real, t_real)> &dde, 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)
t_real sparsify_row_thres(const Eigen::SparseMatrixBase< T > &row, const t_real &energy)
Returns threshold to keep a fraction of energy in the sparse row.
std::tuple< t_real, t_real > fov_cosines(t_real const &cell_x, t_real const &cell_y, t_uint const &x_size, t_uint const &y_size)
Work out max L and M directional cosines from image parameters.
t_real sparsify_row_dense_thres(const Eigen::MatrixBase< T > &row, const t_real &energy)
Returns threshold to keep a fraction of energy in the dense row.
Sparse< t_complex > create_chirp_row(const t_real &w_rate, const t_real &cell_x, const t_real &cell_y, const t_uint &ftsizev, const t_uint &ftsizeu, const t_real &energy_fraction, const sopt::OperatorFunction< Vector< t_complex >> &fftop)
Generates row of chirp matrix from image of chirp.
Sparse< t_complex > convert_sparse(const Eigen::MatrixBase< T > &M, const t_real &threshold=0.)
Convert from dense to sparse.
Matrix< t_complex > generate_dde(const std::function< t_complex(t_real, t_real)> &dde, const t_real &cell_x, const t_real &cell_y, const t_uint &x_size, const t_uint &y_size)
Generate image of DDE for A or W projection.
Sparse< t_complex > generate_vect(const t_uint &x_size, const t_uint &y_size, const t_real &sigma, const t_real &mean)
Genereates an image of a Gaussian as a sparse matrice.
t_real mr_metric(const Image< t_real > &model, const Image< t_real > &solution)
MR calculation.
Sparse< t_complex > row_wise_sparse_convolution(const Sparse< t_complex > &Grid_, const Sparse< T > &chirp_, const t_uint &x_size, const t_uint &y_size)
Sparse< t_complex > wprojection_matrix(const Sparse< t_complex > &G, const t_uint &x_size, const t_uint &y_size, const Vector< t_real > &w_components, const t_real &cell_x, const t_real &cell_y, const t_real &energy_fraction_chirp, const t_real &energy_fraction_wproj, const expansions::series series, const t_uint order, const t_real &interpolation_error)
Produce Gridding matrix convovled with chirp matrix for wprojection.
Eigen::SparseMatrix< T, Eigen::RowMajor, I > Sparse
A matrix of a given type.
t_uint size() const
return number of measurements
Vector< t_complex > weights