ARTS 2.5.11 (git: 6827797f)
mc_antenna.cc
Go to the documentation of this file.
1
9/*===========================================================================
10 === External declarations
11 ===========================================================================*/
12
13#include "mc_antenna.h"
14#include <cfloat>
15#include <random>
16#include <sstream>
17#include "arts_constants.h"
18#include "arts_conversions.h"
19#include "matpack_math.h"
20#include "rng.h"
21
22inline constexpr Numeric PI=Constant::pi;
23inline constexpr Numeric DEG2RAD=Conversion::deg2rad(1);
24inline constexpr Numeric RAD2DEG=Conversion::rad2deg(1);
25
26void rotmat_enu(MatrixView R_ant2enu, ConstVectorView prop_los)
27
28{
29 Numeric cza, sza, caa, saa;
30
31 cza = cos(prop_los[0] * DEG2RAD);
32 sza = sin(prop_los[0] * DEG2RAD);
33 caa = cos(prop_los[1] * DEG2RAD);
34 saa = sin(prop_los[1] * DEG2RAD);
35
36 R_ant2enu(0, 0) = -cza * saa;
37 R_ant2enu(0, 1) = caa;
38 R_ant2enu(0, 2) = sza * saa;
39
40 R_ant2enu(1, 0) = -cza * caa;
41 R_ant2enu(1, 1) = -saa;
42 R_ant2enu(1, 2) = sza * caa;
43
44 R_ant2enu(2, 0) = sza;
45 R_ant2enu(2, 1) = 0.0;
46 R_ant2enu(2, 2) = cza;
47}
48
49void rotmat_stokes(MatrixView R_pra,
50 const Index& stokes_dim,
51 const Numeric& f1_dir,
52 const Numeric& f2_dir,
53 ConstMatrixView R_f1,
54 ConstMatrixView R_f2)
55
56{
57 const Numeric flip = f1_dir * f2_dir;
58 Numeric cos_pra1, sin_pra1, cos_pra2, sin_pra2;
59
60 cos_pra1 = R_f1(joker, 0) * R_f2(joker, 0);
61 sin_pra1 = f2_dir * (R_f1(joker, 0) * R_f2(joker, 1));
62 sin_pra2 = f1_dir * (R_f1(joker, 1) * R_f2(joker, 0));
63 cos_pra2 = f1_dir * f2_dir * (R_f1(joker, 1) * R_f2(joker, 1));
64
65 R_pra = 0.0;
66 R_pra(0, 0) = 1.0;
67 if (stokes_dim > 1) {
68 R_pra(1, 1) = 2 * cos_pra1 * cos_pra1 - 1.0;
69 if (stokes_dim > 2) {
70 R_pra(1, 2) = flip * 2 * cos_pra1 * sin_pra1;
71 R_pra(2, 1) = 2 * cos_pra2 * sin_pra2;
72 R_pra(2, 2) = flip * (2 * cos_pra2 * cos_pra2 - 1.0);
73 if (stokes_dim > 3) {
74 R_pra(3, 3) = flip * 1.0;
75 }
76 }
77 }
78}
79
81
82void MCAntenna::set_gaussian(const Numeric& za_sigma, const Numeric& aa_sigma) {
84 sigma_za = za_sigma;
85 sigma_aa = aa_sigma;
86}
87
88void MCAntenna::set_gaussian_fwhm(const Numeric& za_fwhm,
89 const Numeric& aa_fwhm) {
91 sigma_za = za_fwhm / 2.3548;
92 sigma_aa = aa_fwhm / 2.3548;
93}
94
95void MCAntenna::set_lookup(ConstVectorView za_grid_,
96 ConstVectorView aa_grid_,
97 ConstMatrixView G_lookup_) {
99 za_grid = za_grid_;
100 aa_grid = aa_grid_;
101 G_lookup = G_lookup_;
102}
103
104void MCAntenna::return_los(Numeric& wgt,
105 ConstMatrixView R_return,
106 ConstMatrixView R_enu2ant) const {
107 Numeric z, term_el, term_az;
108 Numeric ant_el, ant_az;
109 Vector k_vhk(3);
110
111 switch (atype) {
113 wgt = 1.0;
114 break;
115
117
118 mult(k_vhk, R_enu2ant, R_return(joker, 2));
119
120 // Assume Gaussian is narrow enough that response is 0 beyond 90 degrees
121 // Same assumption is made for drawing samples (draw_los)
122 if (k_vhk[2] > 0) {
123 ant_el = atan(k_vhk[0] / k_vhk[2]) * RAD2DEG;
124 ant_az = atan(k_vhk[1] / k_vhk[2]) * RAD2DEG;
125 term_el = ant_el / sigma_za;
126 term_az = ant_az / sigma_aa;
127 z = term_el * term_el + term_az * term_az;
128 wgt = exp(-0.5 * z);
129 } else {
130 wgt = 0.0;
131 }
132 break;
133
134 default:
135 ARTS_USER_ERROR ("invalid Antenna type.")
136 }
137}
138
139void MCAntenna::draw_los(VectorView sampled_rte_los,
140 MatrixView R_los,
142 ConstMatrixView R_ant2enu,
143 ConstVectorView bore_sight_los) const {
144 Numeric ant_el, ant_az, ant_r;
145 Numeric tel, taz;
146 Vector k_vhk(3);
147
148 switch (atype) {
150 sampled_rte_los = bore_sight_los;
151 R_los = R_ant2enu;
152 break;
153
155
156 ant_el = 91;
157 ant_az = 91;
158
159 // Assume Gaussian is narrow enough that response is 0 beyond 90 degrees
160 // Same assumption is made for radar return samples (return_los)
161 {
162 auto za_sample = rng.get<std::normal_distribution>(0.0, sigma_za);
163 while (ant_el >= 90) {
164 ant_el = za_sample();
165 }
166 auto aa_sample = rng.get<std::normal_distribution>(0.0, sigma_aa);
167 while (ant_az >= 90) {
168 ant_az = aa_sample();
169 }
170 }
171
172 // Propagation direction
173 tel = tan(DEG2RAD * ant_el);
174 taz = tan(DEG2RAD * ant_az);
175 ant_r = sqrt(1 + tel * tel + taz * taz);
176 k_vhk[0] = tel / ant_r;
177 k_vhk[1] = taz / ant_r;
178 k_vhk[2] = (Numeric)1.0 / ant_r;
179 mult(R_los(joker, 2), R_ant2enu, k_vhk);
180
181 sampled_rte_los[0] = acos(R_los(2, 2)) * RAD2DEG;
182
183 // Horizontal polarization basis
184 // If drawn los is at zenith or nadir, assume same azimuth as boresight
185 if (((Numeric)1.0 - abs(R_los(2, 2))) < DBL_EPSILON) {
186 // H is aligned with H of bs, use row not column because tranpose
187 R_los(joker, 1) = R_ant2enu(1, joker);
188 sampled_rte_los[1] = bore_sight_los[1];
189 } else {
190 const Vector uhat{0.0, 0.0, 1.0};
191 Numeric magh;
192 sampled_rte_los[1] = atan2(R_los(0, 2), R_los(1, 2)) * RAD2DEG;
193 cross3(R_los(joker, 1), R_los(joker, 2), uhat);
194 magh = sqrt(R_los(joker, 1) * R_los(joker, 1));
195 R_los(joker, 1) /= magh;
196 }
197
198 // Vertical polarization basis
199 cross3(R_los(joker, 0), R_los(joker, 1), R_los(joker, 2));
200
201 break;
202
203 default:
204 ARTS_USER_ERROR ("invalid Antenna type.")
205 }
206}
207
208ostream& operator<<(ostream& os, const MCAntenna&) {
209 os << "MCAntenna: Output operator not implemented";
210 return os;
211}
Constants of physical expressions as constexpr.
Common ARTS conversions.
A C++ standards dependent random number generator class.
Definition: rng.h:22
auto get(Ts &&...x) const
Returns a random number generator of some random distribution.
Definition: rng.h:103
void mult(MatrixView C, ConstMatrixView A, const Block &B)
#define ARTS_USER_ERROR(...)
Definition: debug.h:151
constexpr Numeric DEG2RAD
Definition: disort.cc:47
constexpr Numeric RAD2DEG
Definition: doit.cc:42
constexpr Numeric DEG2RAD
Definition: mc_antenna.cc:23
constexpr Numeric RAD2DEG
Definition: mc_antenna.cc:24
void rotmat_stokes(MatrixView R_pra, const Index &stokes_dim, const Numeric &f1_dir, const Numeric &f2_dir, ConstMatrixView R_f1, ConstMatrixView R_f2)
rotmat_stokes.
Definition: mc_antenna.cc:49
ostream & operator<<(ostream &os, const MCAntenna &)
Definition: mc_antenna.cc:208
constexpr Numeric PI
Definition: mc_antenna.cc:22
void rotmat_enu(MatrixView R_ant2enu, ConstVectorView prop_los)
rotmat_enu.
Definition: mc_antenna.cc:26
Workspace functions for the solution of cloud-box radiative transfer by Monte Carlo methods....
@ ANTENNA_TYPE_PENCIL_BEAM
Definition: mc_antenna.h:24
@ ANTENNA_TYPE_GAUSSIAN
Definition: mc_antenna.h:25
@ ANTENNA_TYPE_LOOKUP
Definition: mc_antenna.h:26
constexpr Numeric pi
The following mathematical constants are generated in python Decimal package by the code:
constexpr auto deg2rad(auto x) noexcept
Converts degrees to radians.
constexpr auto rad2deg(auto x) noexcept
Converts radians to degrees.
An Antenna object used by MCGeneral.
Definition: mc_antenna.h:33
Matrix G_lookup
Definition: mc_antenna.h:37
Numeric sigma_aa
Definition: mc_antenna.h:35
Numeric sigma_za
Definition: mc_antenna.h:35
AntennaType atype
Definition: mc_antenna.h:34
void return_los(Numeric &wgt, ConstMatrixView R_return, ConstMatrixView R_enu2ant) const
return_los
Definition: mc_antenna.cc:104
void set_lookup(ConstVectorView za_grid, ConstVectorView aa_grid, ConstMatrixView G_lookup)
set_lookup.
Definition: mc_antenna.cc:95
void draw_los(VectorView sampled_rte_los, MatrixView R_los, RandomNumberGenerator<> &rng, ConstMatrixView R_ant2enu, ConstVectorView bore_sight_los) const
draw_los.
Definition: mc_antenna.cc:139
void set_gaussian(const Numeric &za_sigma, const Numeric &aa_sigma)
set_gaussian.
Definition: mc_antenna.cc:82
Vector aa_grid
Definition: mc_antenna.h:36
Vector za_grid
Definition: mc_antenna.h:36
void set_gaussian_fwhm(const Numeric &za_fwhm, const Numeric &aa_fwhm)
set_gaussian_fwhm.
Definition: mc_antenna.cc:88
void set_pencil_beam()
set_pencil_beam
Definition: mc_antenna.cc:80