DP3
Simulator.h
Go to the documentation of this file.
1 // Simulator.h: Compute visibilities for different model components types
2 // (implementation of ModelComponentVisitor).
3 //
4 // Copyright (C) 2023 ASTRON (Netherlands Institute for Radio Astronomy)
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 
7 #ifndef DP3_BASE_SIMULATOR_H_
8 #define DP3_BASE_SIMULATOR_H_
9 
10 #include <vector>
11 
12 #include <casacore/casa/Arrays/Cube.h>
13 
14 #include <xtensor/containers/xtensor.hpp>
15 
16 #include "Baseline.h"
17 #include "ModelComponent.h"
18 #include "ModelComponentVisitor.h"
19 #include "Direction.h"
20 
21 namespace dp3 {
22 namespace base {
23 
34 inline void radec2lmn(const Direction& reference, const Direction& direction,
35  double* lmn) {
43  const double delta_ra = direction.ra - reference.ra;
44  const double sin_delta_ra = std::sin(delta_ra);
45  const double cos_delta_ra = std::cos(delta_ra);
46  const double sin_dec = std::sin(direction.dec);
47  const double cos_dec = std::cos(direction.dec);
48  const double sin_dec0 = std::sin(reference.dec);
49  const double cos_dec0 = std::cos(reference.dec);
50 
51  lmn[0] = cos_dec * sin_delta_ra;
52  lmn[1] = sin_dec * cos_dec0 - cos_dec * sin_dec0 * cos_delta_ra;
53  // Normally, n is calculated using n = std::sqrt(1.0 - l * l - m * m).
54  // However the sign of n is lost that way, so a calculation is used that
55  // avoids losing the sign. This formula can be found in Perley (1989).
56  // Be aware that we asserted that the sign is wrong in Perley (1989),
57  // so this is corrected.
58  lmn[2] = sin_dec * sin_dec0 + cos_dec * cos_dec0 * cos_delta_ra;
59 }
60 
62 
63 typedef std::complex<double> dcomplex;
64 
100 class Simulator : public ModelComponentVisitor {
101  public:
116  Simulator(const Direction& reference, size_t nStation,
117  const std::vector<Baseline>& baselines,
118  const std::vector<double>& freq,
119  const std::vector<double>& chanWidths,
120  const xt::xtensor<double, 2>& stationUVW,
121  casacore::Cube<dcomplex>& buffer, bool correctFreqSmearing,
122  bool stokesIOnly);
123 
141  Simulator(const Direction& reference, size_t nStation,
142  const std::vector<Baseline>& baselines,
143  const std::vector<double>& freq,
144  const std::vector<double>& chanWidths,
145  const std::vector<double>& scaled_ncp_uvw,
146  const xt::xtensor<double, 2>& stationUVW,
147  casacore::Cube<dcomplex>& buffer, bool correctTimeSmearing,
148  bool correctFreqSmearing, bool stokesIOnly);
149 
150  // Note DuoMatrix is actually two T matrices
151  // T: floating point type, ideally float, double, or long double.
152  template <typename T>
153  class DuoMatrix {
154  public:
155  DuoMatrix() = default;
156 
157  DuoMatrix(size_t nrows, size_t ncols) { resize(nrows, ncols); }
158 
159  void resize(size_t nrows, size_t ncols) {
160  itsNRows = nrows;
161  itsData_real.resize(nrows * ncols);
162  itsData_imag.resize(nrows * ncols);
163  }
164 
165  size_t nRows() { return itsNRows; }
166  size_t nCols() { return itsData_real.size() / itsNRows; }
167 
168  T& real(size_t row, size_t col) {
169  return itsData_real[col * itsNRows + row];
170  }
171  T& imag(size_t row, size_t col) {
172  return itsData_imag[col * itsNRows + row];
173  }
174  T* realdata() { return &itsData_real[0]; }
175  T* imagdata() { return &itsData_imag[0]; }
176 
177  private:
178  // Use separate storage for real/imag parts
179  std::vector<T> itsData_real;
180  std::vector<T> itsData_imag;
181  size_t itsNRows{0};
182  };
183 
184  void simulate(const std::shared_ptr<const ModelComponent>& component);
185 
186  private:
187  void visit(const PointSource& component) override;
188  void visit(const GaussianSource& component) override;
189 
190  private:
191  Direction itsReference;
192  size_t itsNStation, itsNBaseline, itsNChannel;
193  bool itsCorrectTimeSmearing;
194  bool itsCorrectFreqSmearing;
195  bool itsStokesIOnly;
196  std::vector<Baseline> itsBaselines;
197  std::vector<double> itsFreq;
198  std::vector<double> itsChanWidths;
199  std::vector<double> itsScaledNcpUvw;
203  const xt::xtensor<double, 2>* itsStationUVW;
204  casacore::Cube<dcomplex> itsBuffer;
205  std::vector<double> itsStationPhases;
206  std::vector<double> itsStationEarthRotation;
207  DuoMatrix<double> itsShiftBuffer;
208  DuoMatrix<double> itsSpectrumBuffer;
209 };
210 
212 
213 } // namespace base
214 } // namespace dp3
215 
216 #endif
Pair of stations that together form a baseline (interferometer).
Gaussian source model component.
Definition: GaussianSource.h:18
Base class for visitors that visit model component hierarchies.
Definition: ModelComponentVisitor.h:20
Point source model component with optional spectral index and rotation measure.
Definition: PointSource.h:26
void simulate(const Direction &reference, const std::shared_ptr< const model::Patch > &patch, size_t nStation, size_t nBaseline, size_t nChannel, const_cursor< Baseline > baselines, const_cursor< double > freq, const_cursor< double > uvw, cursor< std::complex< double >> buffer)
void radec2lmn(const Direction &reference, const Direction &direction, double *lmn)
Definition: Simulator.h:34
std::complex< double > dcomplex
Definition: Simulator.h:63
This file has generic helper routines for testing steps.
Definition: AntennaConfig.h:53
A direction on the celestial sphere.
Definition: Direction.h:15
double ra
Right ascension in radians.
Definition: Direction.h:26
double dec
Declination in radians.
Definition: Direction.h:27