4 #include <boost/math/special_functions/erf.hpp>
5 #include "purify/directories.h"
9 #include <sopt/credible_region.h>
10 #include <sopt/imaging_padmm.h>
11 #include <sopt/power_method.h>
12 #include <sopt/relative_variation.h>
13 #include <sopt/utilities.h>
14 #include <sopt/wavelets.h>
15 #include <sopt/wavelets/sara.h>
25 void padmm(
const std::string &name,
const Image<t_complex> &M31,
const std::string &
kernel,
27 const std::tuple<bool, t_real> &w_term) {
34 t_real
const over_sample = 2;
35 t_uint
const imsizey = M31.rows();
36 t_uint
const imsizex = M31.cols();
39 auto const measurements_transform =
40 std::get<2>(sopt::algorithm::normalise_operator<Vector<t_complex>>(
42 uv_data, imsizey, imsizex, std::get<1>(w_term), std::get<1>(w_term), over_sample,
45 1000, 1e-4, Vector<t_complex>::Random(imsizex * imsizey)));
48 auto const measurements_transform =
49 std::get<2>(sopt::algorithm::normalise_operator<Vector<t_complex>>(
51 uv_data, imsizey, imsizex, std::get<1>(w_term), std::get<1>(w_term), over_sample,
53 1000, 1e-4, Vector<t_complex>::Random(imsizex * imsizey)));
55 sopt::wavelets::SARA
const sara{
56 std::make_tuple(
"Dirac", 3u), std::make_tuple(
"DB1", 3u), std::make_tuple(
"DB2", 3u),
57 std::make_tuple(
"DB3", 3u), std::make_tuple(
"DB4", 3u), std::make_tuple(
"DB5", 3u),
58 std::make_tuple(
"DB6", 3u), std::make_tuple(
"DB7", 3u), std::make_tuple(
"DB8", 3u)};
60 auto const Psi = sopt::linear_transform<t_complex>(sara, imsizey, imsizex);
61 Vector<> dimage = (measurements_transform->adjoint() * uv_data.
vis).real();
62 assert(dimage.size() == M31.size());
63 Vector<t_complex> initial_estimate = Vector<t_complex>::Zero(dimage.size());
64 sopt::utilities::write_tiff(Image<t_real>::Map(dimage.data(), imsizey, imsizex), dirty_image);
65 pfitsio::write2d(Image<t_real>::Map(dimage.data(), imsizey, imsizex), dirty_image_fits);
71 std::make_shared<CDisplay>(cimg::make_display(Vector<t_real>::Zero(1024 * 512), 1024, 512));
73 auto const show_image = [&, measurements_transform](
const Vector<t_complex> &x) ->
bool {
74 if (!canvas->is_closed()) {
75 const Vector<t_complex> res =
76 (measurements_transform->adjoint() * (uv_data.
vis - (*measurements_transform * x)));
77 const auto img1 = cimg::make_image(x.real().eval(), imsizey, imsizex)
79 .get_resize(512, 512);
80 const auto img2 = cimg::make_image(res.real().eval(), imsizey, imsizex)
82 .get_resize(512, 512);
83 const auto results = CImageList<t_real>(img1, img2);
84 canvas->display(results);
91 sopt::algorithm::ImagingProximalADMM<t_complex>(uv_data.
vis)
93 .regulariser_strength(
94 (Psi.adjoint() * (measurements_transform->adjoint() * uv_data.
vis).eval())
98 .relative_variation(1e-3)
99 .l2ball_proximal_epsilon(epsilon)
101 .l1_proximal_tolerance(1e-2)
103 .l1_proximal_itermax(50)
104 .l1_proximal_positivity_constraint(
true)
105 .l1_proximal_real_constraint(
true)
106 .residual_convergence(epsilon)
107 .lagrange_update_scale(0.9)
109 .is_converged(show_image)
112 .Phi(*measurements_transform);
114 auto const diagnostic =
padmm();
115 assert(diagnostic.x.size() == M31.size());
116 Image<t_complex> image = Image<t_complex>::Map(diagnostic.x.data(), imsizey, imsizex);
118 Vector<t_complex> residuals = measurements_transform->adjoint() *
119 (uv_data.
vis - ((*measurements_transform) * diagnostic.x));
120 Image<t_complex> residual_image = Image<t_complex>::Map(residuals.data(), imsizey, imsizex);
123 const auto results = CImageList<t_real>(
124 cimg::make_image(diagnostic.x.real().eval(), imsizey, imsizex).get_resize(512, 512),
125 cimg::make_image(residuals.real().eval(), imsizey, imsizex).get_resize(512, 512));
126 canvas->display(results);
127 cimg::make_image(residuals.real().eval(), imsizey, imsizex)
129 .display_graph(
"Residual Histogram", 2);
130 while (!canvas->is_closed()) canvas->wait();
137 const std::string &name =
"M31";
138 const t_real FoV = 15;
139 const t_real max_w = 15.;
140 const t_real snr = 30;
141 const bool w_term =
false;
142 const std::string
kernel =
"kb";
145 const t_real cellsize = FoV / M31.cols() * 60. * 60.;
146 std::string
const inputfile =
output_filename(name +
"_" +
"input.fits");
148 t_real
const max = M31.array().abs().maxCoeff();
149 M31 = M31 * 1. / max;
152 t_int
const number_of_pxiels = M31.size();
153 t_int
const number_of_vis = std::floor(number_of_pxiels * 2);
159 uv_data.u.size() * 1. / number_of_pxiels);
162 auto const sky_measurements = std::get<2>(sopt::algorithm::normalise_operator<Vector<t_complex>>(
164 uv_data, M31.rows(), M31.cols(), cellsize, cellsize, 2,
166 1000, 0.0001, Vector<t_complex>::Random(M31.size())));
168 auto const sky_measurements = std::get<2>(sopt::algorithm::normalise_operator<Vector<t_complex>>(
170 uv_data, M31.rows(), M31.cols(), cellsize, cellsize, 2,
172 1000, 0.0001, Vector<t_complex>::Random(M31.size())));
175 uv_data.vis = (*sky_measurements) * Image<t_complex>::Map(M31.data(), M31.size(), 1);
176 Vector<t_complex>
const y0 = uv_data.vis;
180 std::cout << std::setprecision(13) << sigma << std::endl;
183 padmm(name +
"30", M31,
kernel, 4, uv_data, sigma, std::make_tuple(w_term, cellsize));
#define PURIFY_HIGH_LOG(...)
High priority message.
#define PURIFY_MEDIUM_LOG(...)
Medium priority message.
const t_real pi
mathematical constant
const std::map< std::string, kernel > kernel_from_string
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.
void write2d(const Image< t_real > &eigen_image, const pfitsio::header_params &header, const bool &overwrite)
Write image to fits file.
Image< t_complex > read2d(const std::string &fits_name)
Read image from fits file.
void write_visibility(const utilities::vis_params &uv_vis, const std::string &file_name, const bool w_term)
Writes visibilities to txt.
t_real SNR_to_standard_deviation(const Vector< t_complex > &y0, const t_real &SNR)
Converts SNR to RMS noise.
Vector< t_complex > add_noise(const Vector< t_complex > &y0, const t_complex &mean, const t_real &standard_deviation)
Add guassian noise to vector.
utilities::vis_params random_sample_density(const t_int vis_num, const t_real mean, const t_real standard_deviation, const t_real rms_w)
Generates a random visibility coverage.
t_real calculate_l2_radius(const t_uint y_size, const t_real &sigma, const t_real &n_sigma, const std::string distirbution)
A function that calculates the l2 ball radius for sopt.
std::string output_filename(std::string const &filename)
Test output file.
std::string image_filename(std::string const &filename)
Image filename.
void padmm(const std::string &name, const Image< t_complex > &M31, const std::string &kernel, const t_int J, const utilities::vis_params &uv_data, const t_real sigma, const std::tuple< bool, t_real > &w_term)