File: averagebeam.cpp

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 (129 lines) | stat: -rw-r--r-- 4,592 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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "averagebeam.h"

#include "../io/cachedimageset.h"

#include <aocommon/io/serialistream.h>
#include <aocommon/io/serialostream.h>
#include <aocommon/logger.h>

#include <cassert>

namespace wsclean {

namespace {
constexpr size_t kNPolarizations = 4;
}  // namespace

void AverageBeam::SetMatrixInverseBeam(
    const std::shared_ptr<std::vector<std::complex<float>>>&
        matrix_inverse_beam,
    size_t width, size_t height) {
  assert(matrix_inverse_beam->size() ==
         width * height * kNPolarizations * kNPolarizations);
  matrix_inverse_beam_ = matrix_inverse_beam;
  matrix_width_ = width;
  matrix_height_ = height;
}

void AverageBeam::SetScalarBeam(
    const std::shared_ptr<std::vector<float>>& scalar_beam, size_t width,
    size_t height) {
  assert(scalar_beam->size() == width * height);
  scalar_beam_ = scalar_beam;
  scalar_width_ = width;
  scalar_height_ = height;
}

void AverageBeam::Serialize(aocommon::SerialOStream& stream) const {
  stream.Bool(static_cast<bool>(scalar_beam_));
  if (scalar_beam_) {
    stream.Vector(*scalar_beam_).UInt64(scalar_width_).UInt64(scalar_height_);
  }

  stream.Bool(static_cast<bool>(matrix_inverse_beam_));
  if (matrix_inverse_beam_) {
    stream.Vector(*matrix_inverse_beam_)
        .UInt64(matrix_width_)
        .UInt64(matrix_height_);
  }
}

void AverageBeam::Unserialize(aocommon::SerialIStream& stream) {
  const bool has_scalar = stream.Bool();
  if (has_scalar) {
    scalar_beam_.reset(new std::vector<float>());
    stream.Vector(*scalar_beam_).UInt64(scalar_width_).UInt64(scalar_height_);
  } else
    scalar_beam_.reset();

  const bool has_matrix_inverse = stream.Bool();
  if (has_matrix_inverse) {
    matrix_inverse_beam_.reset(new std::vector<std::complex<float>>());
    stream.Vector(*matrix_inverse_beam_)
        .UInt64(matrix_width_)
        .UInt64(matrix_height_);
  } else
    matrix_inverse_beam_.reset();
}

std::unique_ptr<AverageBeam> AverageBeam::Load(
    const CachedImageSet& scalar_cache, const CachedImageSet& matrix_cache,
    size_t frequency_index) {
  std::unique_ptr<AverageBeam> result;
  if (!scalar_cache.Empty()) {
    aocommon::Logger::Debug << "Loading average beam from cache.\n";
    result = std::make_unique<AverageBeam>();

    // Scalar beam
    result->scalar_width_ = scalar_cache.Writer().Width();
    result->scalar_height_ = scalar_cache.Writer().Height();
    const size_t n_scalar_pixels =
        result->scalar_width_ * result->scalar_height_;
    result->scalar_beam_ =
        std::make_shared<std::vector<float>>(n_scalar_pixels);
    scalar_cache.Load(result->scalar_beam_->data(),
                      aocommon::PolarizationEnum::StokesI, frequency_index,
                      false);

    // Inverse matrix beam
    // It is stored as one real and one imaginary fits image. The 16 elements
    // are consecutively stored along the X axis, so its width is 16x its
    // height. This makes these images not easy to interpret, but it avoids
    // having to reshuffle the data, and they are only for temporary storage,
    // not for interpretation.
    assert(!matrix_cache.Empty());
    result->matrix_width_ =
        matrix_cache.Writer().Width() / (kNPolarizations * kNPolarizations * 2);
    result->matrix_height_ = matrix_cache.Writer().Height();
    const size_t n_matrix_pixels = result->matrix_width_ *
                                   result->matrix_height_ * kNPolarizations *
                                   kNPolarizations;
    result->matrix_inverse_beam_ =
        std::make_shared<std::vector<std::complex<float>>>(n_matrix_pixels);
    matrix_cache.Load(
        reinterpret_cast<float*>(result->matrix_inverse_beam_->data()),
        aocommon::PolarizationEnum::StokesI, frequency_index, false);
  }
  return result;
}

void AverageBeam::Store(CachedImageSet& scalar_cache,
                        CachedImageSet& matrix_cache,
                        size_t frequency_index) const {
  if (!Empty()) {
    // Scalar beam
    scalar_cache.Writer().SetImageDimensions(scalar_width_, scalar_height_);
    scalar_cache.Store(scalar_beam_->data(),
                       aocommon::PolarizationEnum::StokesI, frequency_index,
                       false);

    // Matrix beam
    matrix_cache.Writer().SetImageDimensions(
        matrix_width_ * kNPolarizations * kNPolarizations * 2, matrix_height_);
    matrix_cache.Store(reinterpret_cast<float*>(matrix_inverse_beam_->data()),
                       aocommon::PolarizationEnum::StokesI, frequency_index,
                       false);
  }
}

}  // namespace wsclean