ARTS 2.5.0 (git: 9ee3ac6c)
zeemandata.cc
Go to the documentation of this file.
1/* Copyright (C) 2018 Richard Larsson
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2, or (at your option) any
6 later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 USA. */
17
29#include "zeemandata.h"
30#include "species_info.h"
31
33 const Numeric GS = get_lande_spin_constant(qid.Species());
35 const Numeric gu = SimpleG(qid.Upper(), GS, GL);
36 const Numeric gl = SimpleG(qid.Lower(), GS, GL);
37 return Model(gu, gl);
38}
39
41 Rational n,
42 Numeric GS,
43 Numeric GR,
44 Numeric GLE,
45 Numeric B,
46 Numeric D,
47 Numeric H,
48 Numeric gB,
49 Numeric gD,
50 Numeric gH,
51 Numeric lB,
52 Numeric lD,
53 Numeric lH) {
54 using Constant::pow2;
55 using Constant::pow3;
56 using std::atan2;
57 using std::cos;
58 using std::sin;
59 using std::sqrt;
60
61 if (j.isUndefined() or n.isUndefined())
62 return NAN;
63 if (j == 0)
64 return 0;
65
66 auto J = j.toNumeric();
67
68 auto nom = (lB + lD * (J * J + J + 1) + lH * pow2(J * J + J + 1)) * (2 * sqrt(J * J + J) / (2 * J + 1));
69
70 auto denom =
71 B * J * (J - 1) - D * pow2(J * (J - 1)) + H * pow3(J * (J - 1)) +
72 (gB + gD * J * (J - 1) + gH * pow2(J * (J - 1))) * (J - 1) +
73 (lB + lD * J * (J - 1) + lH * pow2(J * (J - 1))) *
74 (2. / 3. - 2 * J / (2 * J + 1)) -
75 (B * (J + 2) * (J + 1) - D * pow2((J + 2) * (J + 1)) +
76 H * pow3((J + 2) * (J + 1)) -
77 (gB + gD * (J + 2) * (J + 1) + gH * pow2((J + 2) * (J + 1))) * (J + 2) +
78 (lB + lD * (J + 2) * (J + 1) + lH * pow2((J + 2) * (J + 1))) *
79 (2. / 3. - 2 * (J + 1) / (2 * J + 1)));
80
81 auto phi = atan2(2 * nom, denom) / 2;
82
83 if (j == n)
84 return (GS + GR) / (J * (J + 1)) - GR;
85 if (j < n)
86 return (GS + GR) * (pow2(cos(phi)) / J - pow2(sin(phi)) / (J + 1)) +
87 2 * GLE * cos(2 * phi) / (2 * J + 1) - GR;
88 return (GS + GR) * (pow2(sin(phi)) / J - pow2(cos(phi)) / (J + 1)) -
89 2 * GLE * cos(2 * phi) / (2 * J + 1) - GR;
90}
91
93 Rational j,
94 Numeric gperp,
95 Numeric gpara)
96{
97 if (k.isUndefined() or j.isUndefined() or j == 0)
98 return 0;
99 return gperp + (gperp + gpara) * Numeric(k*k / (j*(j+1)));
100}
101
102
104 ARTS_ASSERT(qid.type == Quantum::IdentifierType::Transition,
105 "Not a transition"
106 )
107 if (qid.Isotopologue() == "O2-66") {
108 if (qid.Lower()[QuantumNumberType::v1] == 0 and qid.Upper()[QuantumNumberType::v1] == 0) {
109 Numeric GS = 2.002084;
110 Numeric GLE = 2.77e-3;
111 Numeric GR = -1.16e-4;
112 Numeric B = 43100.44276e6;
113 Numeric D = 145.1271e3;
114 Numeric H = 49e-3;
115 Numeric lB = 59501.3438e6;
116 Numeric lD = 58.3680e3;
117 Numeric lH = 290.8e-3;
118 Numeric gB = -252.58634e6;
119 Numeric gD = -243.42;
120 Numeric gH = -1.46e-3;
121
122 auto JU = qid.Upper()[QuantumNumberType::J];
123 auto NU = qid.Upper()[QuantumNumberType::N];
125 JU, NU, GS, GR, GLE, B, D, H, gB, gD, gH, lB, lD, lH);
126 auto JL = qid.Lower()[QuantumNumberType::J];
127 auto NL = qid.Lower()[QuantumNumberType::N];
129 JL, NL, GS, GR, GLE, B, D, H, gB, gD, gH, lB, lD, lH);
130 return Model(gu, gl);
131 }
132 } else if (qid.Isotopologue() == "O2-68") {
133 if (qid.Lower()[QuantumNumberType::v1] == 0 and qid.Upper()[QuantumNumberType::v1] == 0) {
134 Numeric GS = 2.002025;
135 Numeric GLE = 2.813e-3;
136 Numeric GR = -1.26e-4;
137 Numeric B = 40707.38657e6;
138 Numeric D = 129.4142e3;
139 Numeric H = 0;
140 Numeric lB = 59499.0375e6;
141 Numeric lD = 54.9777e3;
142 Numeric lH = 272.1e-3;
143 Numeric gB = -238.51530e6;
144 Numeric gD = -217.77;
145 Numeric gH = -1.305e-3;
146
147 auto JU = qid.Upper()[QuantumNumberType::J];
148 auto NU = qid.Upper()[QuantumNumberType::N];
150 JU, NU, GS, GR, GLE, B, D, H, gB, gD, gH, lB, lD, lH);
151 auto JL = qid.Lower()[QuantumNumberType::J];
152 auto NL = qid.Lower()[QuantumNumberType::N];
154 JL, NL, GS, GR, GLE, B, D, H, gB, gD, gH, lB, lD, lH);
155 return Model(gu, gl);
156 }
157 } else if (qid.Isotopologue() == "CO-26") {
158 Numeric gperp = -0.2689 / Constant::mass_ratio_electrons_per_proton; // Flygare and Benson 1971
159
160 return Model(gperp, gperp);
161 } else if (qid.Isotopologue() == "OCS-622") {
162 Numeric gperp = -.02889 / Constant::mass_ratio_electrons_per_proton; // Flygare and Benson 1971
163 Numeric gpara = 0 / Constant::mass_ratio_electrons_per_proton; // Flygare and Benson 1971
164
165 auto JU = qid.Upper()[QuantumNumberType::J];
166 auto KU = qid.Upper()[QuantumNumberType::Ka];
167 auto JL = qid.Lower()[QuantumNumberType::J];
168 auto KL = qid.Lower()[QuantumNumberType::Ka];
169
170 return Model(closed_shell_trilinear(KU, JU, gperp, gpara),
171 closed_shell_trilinear(KL, JL, gperp, gpara));
172 } else if (qid.Isotopologue() == "OCS-624") {
173 Numeric gperp = -.0285 / Constant::mass_ratio_electrons_per_proton; // Flygare and Benson 1971
174 Numeric gpara = -.061 / Constant::mass_ratio_electrons_per_proton; // Flygare and Benson 1971
175
176 auto JU = qid.Upper()[QuantumNumberType::J];
177 auto KU = qid.Upper()[QuantumNumberType::Ka];
178 auto JL = qid.Lower()[QuantumNumberType::J];
179 auto KL = qid.Lower()[QuantumNumberType::Ka];
180
181 return Model(closed_shell_trilinear(KU, JU, gperp, gpara),
182 closed_shell_trilinear(KL, JL, gperp, gpara));
183 } else if (qid.Isotopologue() == "CO2-626") {
184 Numeric gperp = -.05508 / Constant::mass_ratio_electrons_per_proton; // Flygare and Benson 1971
185 Numeric gpara = 0 / Constant::mass_ratio_electrons_per_proton; // Flygare and Benson 1971
186
187 auto JU = qid.Upper()[QuantumNumberType::J];
188 auto KU = qid.Upper()[QuantumNumberType::Ka];
189 auto JL = qid.Lower()[QuantumNumberType::J];
190 auto KL = qid.Lower()[QuantumNumberType::Ka];
191
192 return Model(closed_shell_trilinear(KU, JU, gperp, gpara),
193 closed_shell_trilinear(KL, JL, gperp, gpara));
194 }
195
196 // Take care of zeroes since they do not show up in replacement databases
197 const bool upperzero = qid.Upper()[QuantumNumberType::J] == 0 or qid.Upper()[QuantumNumberType::F] == 0;
198 const bool lowerzero = qid.Lower()[QuantumNumberType::J] == 0 or qid.Lower()[QuantumNumberType::F] == 0;
199 return Model(upperzero ? 0 : NAN, lowerzero ? 0 : NAN);
200}
201
203 Model m = GetAdvancedModel(qid);
204 if (m.empty()) m = GetSimpleModel(qid);
205 *this = m;
206}
207
209{
210 return Eigen::Vector3d(v, u, w).normalized();
211}
212
214{
215 using std::cos;
216 using std::sin;
217 return Eigen::Vector3d(cos(a)*sin(z), sin(a)*sin(z), cos(z));
218}
219
221{
222 using std::cos;
223 using std::sin;
224 return Eigen::Vector3d(cos(a)*cos(z), sin(a)*cos(z), -sin(z));
225}
226
228{
229 Derived output;
230
231 // If there is no magnetic field, bailout quickly
232 output.H = std::hypot(u, v, w);
233 if (output.H == 0) {
234 output = FromPreDerived(0, 0, 0);
235 } else {
236 // XYZ vectors normalized
237 const Eigen::Vector3d n = los_xyz_by_za_local(z, a);
238 const Eigen::Vector3d ev = ev_xyz_by_za_local(z, a);
239 const Eigen::Vector3d nH = los_xyz_by_uvw_local(u, v, w);
240
241 // Normalized vector (which are also the magnetic field derivatives)
242 output.dH_dv = nH[0];
243 output.dH_du = nH[1];
244 output.dH_dw = nH[2];
245
246 // Compute theta (and its derivatives if possible)
247 const Numeric cos_theta = n.dot(nH);
248 const Numeric sin_theta = std::sqrt(1 - Constant::pow2(cos_theta));
249 output.theta = std::acos(cos_theta);
250 if (sin_theta not_eq 0) {
251 const Eigen::Vector3d dtheta = (nH * cos_theta - n) / (output.H * sin_theta);
252 output.dtheta_dv = dtheta[0];
253 output.dtheta_du = dtheta[1];
254 output.dtheta_dw = dtheta[2];
255 } else {
256 output.dtheta_dv = 0;
257 output.dtheta_du = 0;
258 output.dtheta_dw = 0;
259 }
260
261 // Compute eta (and its derivatives if possible)
262 const Eigen::Vector3d inplane = nH - nH.dot(n) * n;
263 const Numeric y = ev.cross(inplane).dot(n);
264 const Numeric x = ev.dot(inplane);
265 output.eta = std::atan2(y, x);
266 if (x not_eq 0 or y not_eq 0) {
267 const Eigen::Vector3d deta = n.cross(nH) / (output.H * (Constant::pow2(x) + Constant::pow2(y)));
268 output.deta_dv = deta[0];
269 output.deta_du = deta[1];
270 output.deta_dw = deta[2];
271 } else {
272 output.deta_dv = 0;
273 output.deta_du = 0;
274 output.deta_dw = 0;
275 }
276 }
277
278 return output;
279}
280
281namespace Zeeman {
283 using Constant::pow2;
284
285 auto ml = Ml(Ju, Jl, type, n);
286 auto mu = Mu(Ju, Jl, type, n);
287 auto dm = Rational(dM(type));
288 return PolarizationFactor(type) * pow2(wigner3j(Jl, Rational(1), Ju, ml, -dm, -mu));
289}
290
291std::ostream& operator<<(std::ostream& os, const Model& m) {
292 os << m.mdata.gu << ' ' << m.mdata.gl;
293 return os;
294}
295
296std::istream& operator>>(std::istream& is, Model& m) {
297 is >> double_imanip() >> m.mdata.gu >> m.mdata.gl;
298 return is;
299}
300
301std::ostream& operator<<(bofstream& bof, const Model& m) {
302 bof << m.mdata.gu << m.mdata.gl;
303 return bof;
304}
305
306std::istream& operator>>(bifstream& bif, Model& m) {
307 bif >> m.mdata.gu >> m.mdata.gl;
308 return bif;
309}
310
312 Numeric eta) noexcept {
313 const Numeric ST = std::sin(theta), CT = std::cos(theta), ST2 = ST * ST,
314 CT2 = CT * CT, ST2C2E = ST2 * std::cos(2 * eta),
315 ST2S2E = ST2 * std::sin(2 * eta);
316
319 1 + CT2, ST2C2E, ST2S2E, 2 * CT, 4 * CT, 2 * ST2S2E, -2 * ST2C2E);
320 pv.pi =
321 PolarizationVector(ST2, -ST2C2E, -ST2S2E, 0, 0, -2 * ST2S2E, 2 * ST2C2E);
323 1 + CT2, ST2C2E, ST2S2E, -2 * CT, -4 * CT, 2 * ST2S2E, -2 * ST2C2E);
324 return pv;
325}
326
328 Numeric theta, const Numeric eta) noexcept {
329 const Numeric ST = std::sin(theta), CT = std::cos(theta),
330 C2E = std::cos(2 * eta), S2E = std::sin(2 * eta), dST = CT,
331 dST2 = 2 * ST * dST, dCT = -ST, dST2C2E = dST2 * C2E,
332 dST2S2E = dST2 * S2E, dCT2 = 2 * CT * dCT;
333
336 dCT2, dST2C2E, dST2S2E, 2 * dCT, 4 * dCT, 2 * dST2S2E, -2 * dST2C2E);
338 dST2, -dST2C2E, -dST2S2E, 0, 0, -2 * dST2S2E, 2 * dST2C2E);
340 dCT2, dST2C2E, dST2S2E, -2 * dCT, -4 * dCT, 2 * dST2S2E, -2 * dST2C2E);
341 return pv;
342}
343
345 Numeric eta) noexcept {
346 const Numeric ST = std::sin(theta), ST2 = ST * ST, C2E = std::cos(2 * eta),
347 S2E = std::sin(2 * eta), dST2C2E = -2 * ST2 * S2E,
348 dST2S2E = 2 * ST2 * C2E;
349
351 pv.sm =
352 PolarizationVector(0, dST2C2E, dST2S2E, 0, 0, 2 * dST2S2E, -2 * dST2C2E);
354 0, -dST2C2E, -dST2S2E, 0, 0, -2 * dST2S2E, 2 * dST2C2E);
355 pv.sp =
356 PolarizationVector(0, dST2C2E, dST2S2E, 0, 0, 2 * dST2S2E, -2 * dST2C2E);
357 return pv;
358}
359
360#pragma GCC diagnostic push
361#pragma GCC diagnostic ignored "-Wreturn-type"
363 const AllPolarizationVectors& data, Polarization type) noexcept {
364 switch (type) {
366 return data.sm;
367 case Polarization::Pi:
368 return data.pi;
370 return data.sp;
371 }
372}
373#pragma GCC diagnostic pop
374
375void sum(PropagationMatrix& pm, const ComplexVectorView& abs, const PolarizationVector& polvec, const bool do_phase) ARTS_NOEXCEPT {
376 ARTS_ASSERT(pm.NumberOfZenithAngles() == 1)
377 ARTS_ASSERT(pm.NumberOfAzimuthAngles() == 1)
378 ARTS_ASSERT(pm.NumberOfFrequencies() == abs.nelem())
379 ARTS_ASSERT(do_phase ? pm.NumberOfNeededVectors() == 7 : pm.NumberOfNeededVectors() == 4)
380
381 const auto& pol_real = polvec.attenuation();
382 const auto& pol_imag = polvec.dispersion();
383
384 MatrixView out = pm.Data()(0, 0, joker, joker);
385 MapToEigen(out).leftCols<4>().noalias() += MapToEigen(abs.real()) * pol_real;
386 if (do_phase) MapToEigen(out).rightCols<3>().noalias() += MapToEigen(abs.imag()) * pol_imag;
387}
388
390 const ComplexVectorView& abs,
391 const ComplexVectorView& dabs,
392 const PolarizationVector& polvec,
393 const PolarizationVector& dpolvec_dtheta,
394 const PolarizationVector& dpolvec_deta,
395 const Numeric dH,
396 const Numeric dt,
397 const Numeric de, const bool do_phase) ARTS_NOEXCEPT {
398 ARTS_ASSERT(pm.NumberOfZenithAngles() == 1)
399 ARTS_ASSERT(pm.NumberOfAzimuthAngles() == 1)
400 ARTS_ASSERT(pm.NumberOfFrequencies() == abs.nelem())
401 ARTS_ASSERT(do_phase ? pm.NumberOfNeededVectors() == 7 : pm.NumberOfNeededVectors() == 4)
402
403 const auto& pol_real = polvec.attenuation();
404 const auto& pol_imag = polvec.dispersion();
405 auto da_r = (dt * dpolvec_dtheta.attenuation() + de * dpolvec_deta.attenuation());
406 auto da_i = (dt * dpolvec_dtheta.dispersion() + de * dpolvec_deta.dispersion());
407
408 MatrixView out = pm.Data()(0, 0, joker, joker);
409 MapToEigen(out).leftCols<4>().noalias() += dH * MapToEigen(dabs.real()) * pol_real + MapToEigen(abs.real()) * da_r;
410 if (do_phase) MapToEigen(out).rightCols<3>().noalias() += dH * MapToEigen(dabs.imag()) * pol_imag + MapToEigen(abs.imag()) * da_i;
411}
412} // namespace Zeeman
void * data
The ComplexVectorView class.
The MatrixView class.
Definition: matpackI.h:1125
Implements rational numbers to work with other ARTS types.
Definition: rational.h:52
constexpr bool isUndefined() const noexcept
Is the object not defined.
Definition: rational.h:108
constexpr Numeric toNumeric() const noexcept
Converts this to a Numeric.
Definition: rational.h:142
Main Zeeman Model.
Definition: zeemandata.h:357
SplittingData mdata
Definition: zeemandata.h:359
Numeric Strength(Rational Ju, Rational Jl, Polarization type, Index n) const
Gives the strength of one subline of a given polarization.
Definition: zeemandata.cc:282
bool empty() const noexcept
Returns true if the Model represents no Zeeman effect.
Definition: zeemandata.h:381
constexpr Model(SplittingData gs={NAN, NAN}) noexcept
Default copy/init of Model from its only private variable.
Definition: zeemandata.h:363
Polarization vector for Zeeman Propagation Matrix.
Definition: zeemandata.h:492
Binary output file stream class.
Definition: bifstream.h:42
Binary output file stream class.
Definition: bofstream.h:42
Input manipulator class for doubles to enable nan and inf parsing.
Definition: double_imanip.h:64
#define ARTS_NOEXCEPT
Definition: debug.h:80
#define ARTS_ASSERT(condition,...)
Definition: debug.h:83
#define abs(x)
#define dabs(x)
MatrixViewMap MapToEigen(Tensor3View &A, const Index &i)
Definition: lin_alg.cc:745
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
const Joker joker
constexpr auto pow3(T x) -> decltype(pow2(x) *x)
power of three
Definition: constants.h:71
constexpr auto pow2(T x) -> decltype(x *x)
power of two
Definition: constants.h:65
char Type type
Implements Zeeman modeling.
Definition: zeemandata.cc:281
std::ostream & operator<<(std::ostream &os, const Model &m)
Definition: zeemandata.cc:291
constexpr Index dM(Polarization type) noexcept
Gives the change of M given a polarization type.
Definition: zeemandata.h:52
const PolarizationVector & SelectPolarization(const AllPolarizationVectors &data, Polarization type) noexcept
Selects the polarization vector depending on polarization type.
Definition: zeemandata.cc:362
constexpr Derived FromPreDerived(Numeric H, Numeric theta, Numeric eta) noexcept
Sets Derived from predefined Derived parameters.
Definition: zeemandata.h:676
constexpr Numeric PolarizationFactor(Polarization type) noexcept
The renormalization factor of a polarization type.
Definition: zeemandata.h:192
Derived FromGrids(Numeric u, Numeric v, Numeric w, Numeric z, Numeric a) noexcept
Computes the derived plane from ARTS grids.
Definition: zeemandata.cc:227
AllPolarizationVectors AllPolarization_deta(Numeric theta, Numeric eta) noexcept
The derivative of AllPolarization wrt eta.
Definition: zeemandata.cc:344
AllPolarizationVectors AllPolarization_dtheta(Numeric theta, const Numeric eta) noexcept
The derivative of AllPolarization wrt theta.
Definition: zeemandata.cc:327
Polarization
Zeeman polarization selection.
Definition: zeemandata.h:44
Model GetAdvancedModel(const QuantumIdentifier &qid) ARTS_NOEXCEPT
Returns an advanced Zeeman model.
Definition: zeemandata.cc:103
void dsum(PropagationMatrix &pm, const ComplexVectorView &abs, const ComplexVectorView &dabs, const PolarizationVector &polvec, const PolarizationVector &dpolvec_dtheta, const PolarizationVector &dpolvec_deta, const Numeric dH, const Numeric dt, const Numeric de, const bool do_phase) ARTS_NOEXCEPT
Sums the Zeeman components derivatives into a propagation matrix.
Definition: zeemandata.cc:389
constexpr Numeric SimpleG(const QuantumNumbers &qns, const Numeric &GS, const Numeric &GL) noexcept
Computes the Zeeman splitting coefficient.
Definition: zeemandata.h:314
void sum(PropagationMatrix &pm, const ComplexVectorView &abs, const PolarizationVector &polvec, const bool do_phase) ARTS_NOEXCEPT
Sums the Zeeman components into a propagation matrix.
Definition: zeemandata.cc:375
std::istream & operator>>(std::istream &is, Model &m)
Definition: zeemandata.cc:296
Model GetSimpleModel(const QuantumIdentifier &qid) ARTS_NOEXCEPT
Returns a simple Zeeman model.
Definition: zeemandata.cc:32
constexpr Rational Ml(Rational Ju, Rational Jl, Polarization type, Index n) noexcept
Gives the lower state M value at an index.
Definition: zeemandata.h:174
AllPolarizationVectors AllPolarization(Numeric theta, Numeric eta) noexcept
Computes the polarization of each polarization type.
Definition: zeemandata.cc:311
constexpr Rational Mu(Rational Ju, Rational Jl, Polarization type, Index n) noexcept
Gives the upper state M value at an index.
Definition: zeemandata.h:153
#define u
#define v
#define w
#define a
Quantum::Identifier QuantumIdentifier
Definition: quantum.h:471
Numeric sqrt(const Rational r)
Square root.
Definition: rational.h:739
#define N
Definition: rng.cc:164
Numeric get_lande_spin_constant(const Species::Species species) noexcept
Get the Lande spin constant.
Definition: species_info.cc:30
Numeric get_lande_lambda_constant() noexcept
Get the Lande Lambda constant.
Definition: species_info.cc:44
Some molecular constants.
PolarizationVector for each Polarization.
Definition: zeemandata.h:550
Contains derived values useful for Zeeman calculations.
Definition: zeemandata.h:630
Numeric deta_dv
Definition: zeemandata.h:632
Numeric dtheta_du
Definition: zeemandata.h:631
Numeric dtheta_dw
Definition: zeemandata.h:631
Numeric dtheta_dv
Definition: zeemandata.h:631
Numeric deta_du
Definition: zeemandata.h:632
Numeric deta_dw
Definition: zeemandata.h:632
Numeric wigner3j(const Rational j1, const Rational j2, const Rational j3, const Rational m1, const Rational m2, const Rational m3)
Wigner 3J symbol.
Eigen::Vector3d los_xyz_by_za_local(Numeric z, Numeric a)
Definition: zeemandata.cc:213
Numeric case_b_g_coefficient_o2(Rational j, Rational n, Numeric GS, Numeric GR, Numeric GLE, Numeric B, Numeric D, Numeric H, Numeric gB, Numeric gD, Numeric gH, Numeric lB, Numeric lD, Numeric lH)
Definition: zeemandata.cc:40
constexpr Numeric closed_shell_trilinear(Rational k, Rational j, Numeric gperp, Numeric gpara)
Definition: zeemandata.cc:92
Eigen::Vector3d ev_xyz_by_za_local(Numeric z, Numeric a)
Definition: zeemandata.cc:220
Eigen::Vector3d los_xyz_by_uvw_local(Numeric u, Numeric v, Numeric w)
Definition: zeemandata.cc:208
Headers and class definition of Zeeman modeling.