File: test_python_deconvolution.cc

package info (click to toggle)
wsclean 3.6-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,296 kB
  • sloc: cpp: 129,246; python: 22,066; sh: 360; ansic: 230; makefile: 185
file content (112 lines) | stat: -rw-r--r-- 3,255 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// SPDX-License-Identifier: LGPL-3.0-only

#include "radler.h"

#include <filesystem>
#include <fstream>
#include <string>

#include <boost/test/unit_test.hpp>

#include <aocommon/image.h>
#include <aocommon/logger.h>

#include "settings.h"

namespace radler {

namespace {
const std::string kPythonFilename = "tmp-error-reporting-test.py";
const std::size_t kWidth = 64;
const std::size_t kHeight = 64;
const double kPixelScale = 1.0 / 60.0 * (M_PI / 180.0);  // 1amin in rad

class PythonFileFixture {
 public:
  PythonFileFixture()
      : psf_image(kWidth, kHeight, 0.0),
        residual_image(kWidth, kHeight, 0.0),
        model_image(kWidth, kHeight, 0.0) {
    settings.trimmed_image_width = kWidth;
    settings.trimmed_image_height = kHeight;
    settings.pixel_scale.x = kPixelScale;
    settings.pixel_scale.y = kPixelScale;
    settings.minor_iteration_count = 1000;
    settings.absolute_threshold = 1.0e-8;
    settings.algorithm_type = AlgorithmType::kPython;
    settings.python.filename = kPythonFilename;
  }

  ~PythonFileFixture() { std::filesystem::remove(kPythonFilename); }

  void Write(const std::string& contents) const {
    std::ofstream python_file(kPythonFilename);
    python_file << contents;
  }

  Settings settings;
  aocommon::Image psf_image;
  aocommon::Image residual_image;
  aocommon::Image model_image;
};

}  // namespace

BOOST_AUTO_TEST_SUITE(python_deconvolution)

BOOST_FIXTURE_TEST_CASE(non_existent_file, PythonFileFixture) {
  BOOST_CHECK_THROW(
      Radler(settings, psf_image, residual_image, model_image, 0.0),
      std::runtime_error);
}

BOOST_FIXTURE_TEST_CASE(bad_file, PythonFileFixture) {
  // A syntax error or direct raise may throw an exception in the constructor of
  // Radler
  Write(R"(#! /usr/bin/python

raise RuntimeError("This should give an error during construction")
)");
  try {
    Radler(settings, psf_image, residual_image, model_image, 0.0);
    // Should have thrown
    BOOST_ASSERT(false);
  } catch (std::runtime_error& e) {
    const std::string what = e.what();
    BOOST_CHECK_NE(what.find("This should give an error"), std::string::npos);
  }
}

BOOST_FIXTURE_TEST_CASE(error_reporting, PythonFileFixture) {
  Write(R"(#! /usr/bin/python

def deconvolve(residual, model, psf, meta):
  raise RuntimeError("This is a test to see if WSClean handles a raise correctly")
)");

  aocommon::Logger::SetVerbosity(aocommon::LogVerbosityLevel::kQuiet);

  Radler radler(settings, psf_image, residual_image, model_image, 0.0);
  try {
    bool reached_threshold = false;
    const std::size_t iteration_number = 1;
    radler.Perform(reached_threshold, iteration_number);
    // Should have thrown
    BOOST_ASSERT(false);
  } catch (std::runtime_error& e) {
    const std::string what = e.what();
    BOOST_CHECK_NE(what.find("This is a test"), std::string::npos);
    if (what.find("This is a test") == std::string::npos) {
      // Give more info, as Python throw a different, unexpected error; for
      // debugging it's useful to know what this error is.
      throw std::runtime_error(
          "Exception what() string should have had the text 'This is a test' "
          "in it: " +
          what);
    }
  }
}

BOOST_AUTO_TEST_SUITE_END()

}  // namespace radler