mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
aoPSDs.hpp
Go to the documentation of this file.
1/** \file aoPSDs.hpp
2 * \author Jared R. Males (jaredmales@gmail.com)
3 * \brief Spatial power spectra used in adaptive optics.
4 * \ingroup mxAO_files
5 *
6 */
7
8//***********************************************************************//
9// Copyright 2016-2018 Jared R. Males (jaredmales@gmail.com)
10//
11// This file is part of mxlib.
12//
13// mxlib is free software: you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation, either version 3 of the License, or
16// (at your option) any later version.
17//
18// mxlib is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU General Public License for more details.
22//
23// You should have received a copy of the GNU General Public License
24// along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25//***********************************************************************//
26
27#ifndef aoPSDs_hpp
28#define aoPSDs_hpp
29
30#include <string>
31
32#include "../../mxlib.hpp"
33#include "../../math/constants.hpp"
35
36#include "aoConstants.hpp"
37
38#include "aoAtmosphere.hpp"
39
40namespace mx
41{
42namespace AO
43{
44namespace analysis
45{
46
47namespace PSDComponent
48{
49/// Enum to specify which component of the PSD to calcualte
50enum
51{
52 phase, ///< The phase or OPD
53 amplitude, ///< The amplitude
54 dispPhase, ///< The phase component of dispersive anisoplanatism
55 dispAmplitude ///< The amplitude component of dispersive anisoplanatism
56};
57
58std::string compName( int cc );
59
60int compNum( const std::string &name );
61} // namespace PSDComponent
62
63/// Manage calculations using the von Karman spatial power spectrum.
64/** This very general PSD has the form
65 *
66 * \f[
67 \mathcal{P}(k) = \frac{\beta}{ ( k^2 + k_0^2) ^{\alpha/2}}
68 \f]
69 *
70 * Where \f$ k \f$ is spatial frequency, \f$ \beta \f$ is a normalization constant, and outer scale \f$ L_0 \f$ is
71 included via \f$ k_0 = 1/L_0 \f$.
72 * For \f$ L_0 \rightarrow \infty \f$ this becomes a simple power law with index \f$ \alpha \f$.
73 *
74 * For atmospheric turbulence \f$ \alpha = 11/3 \f$ and the normalization is
75 \f[
76 \beta = \frac{\mathcal{A}_p}{r_0^{5/3}}
77 \f]
78 * where \f$ A_p = 0.0218...\f$ (see \ref mx::AO::constants::a_PSD ).
79 *
80 * \ingroup mxAOAnalytic
81 */
82template <typename realT>
84{
85 typedef verbose::d verboseT;
86
87 protected:
88 bool m_subPiston{ true }; ///< flag controlling whether piston is subtracted from the PSD. Default is true.
90 false }; ///< flag controlling whether tip and tilt are subtracted from the PSD. Default is false.
91
92 bool m_scintillation{ false }; ///< flag controlling whether or not scintillation is included
93 int m_component{ PSDComponent::phase }; ///< If m_scintillation is true, this controls whether phase (0), amplitude
94 ///< (1), or dispersive contrast (2) is returned.
95
96 realT m_D{ 1.0 }; ///< Diameter used for piston and tip/tilt subtraction, in m. Default is 1 m.
97
98 const char *m_id = "von Karman";
99
100 // realT m_alpha {eleven_thirds<realT>()}; ///< The power-law index, 11/3 for Kolmogorov
101
102 public:
103 /// Default Constructor
105
106 /// Constructor specifying the parameters
107 /**
108 */
109 vonKarmanSpectrum( bool subP, ///< [in] is the value of m_subPiston.
110 bool subT, ///< [in] is the value of m_subTipTilt.
111 realT D ///< [in] is the value of m_D.
112 );
113
114 /// Get the value of m_subPiston
115 /**
116 * \returns m_subPiston
117 */
118 bool subPiston();
119
120 /// Set the value of m_subPiston
121 /**
122 */
123 void subPiston( bool sp /**< [in] is the new value of m_subPiston */ );
124
125 /// Get the value of m_subTipTilt
126 /**
127 * \returns the value of m_subTipTilt.
128 */
129 bool subTipTilt();
130
131 /// Set the value of the m_subTipTilt flag.
132 /**
133 */
134 void subTipTilt( bool st /**< [in] the new value of m_subTipTilt.*/ );
135
136 /// Get the value of m_scintillation
137 /**
138 * \returns m_scintillation
139 */
140 bool scintillation();
141
142 /// Set the value of m_scintillation
143 /**
144 */
145 void scintillation( bool sc /**< [in] the new value of m_scintillation*/ );
146
147 /// Get the value of m_component
148 /**
149 * \returns m_component
150 */
151 int component();
152
153 /// Set the value of m_component
154 /**
155 */
156 int component( int cc /**< [in] the new value of m_component */ );
157
158 /// Get the value of the diameter m_D.
159 /**
160 * \returns the current value of m_D, the diameter in m.
161 */
162 realT D();
163
164 /// Set the aperture diameter
165 /**
166 */
167 void D( realT nd /**< [in] the new diameter in m */ );
168
169 /// Get the value of the PSD at spatial frequency k and a zenith distance.
170 /**
171 * \returns the von Karman PSD at the specified spatial frequency.
172 * \returns -1 if an error occurs.
173 *
174 */
175 template <class psdParamsT>
176 realT operator()( psdParamsT &par, ///< [in] gives the PSD parameters.
177 size_t layer_i,
178 realT k, ///< [in] is the spatial frequency in m^-1.
179 realT sec_zeta ///< [in] is the secant of the zenith distance.
180 );
181
182 /// Get the value of the PSD at spatial frequency k and wavelength lambda, and a zenith distance, with a WFS at a
183 /// different wavelength
184 /**
185 *
186 * \returns the von Karman PSD at the specified spatial frequency for the specified wavelength.
187 * \returns -1 if an error occurs.
188 */
189 template <class psdParamsT>
190 realT operator()( psdParamsT &par, ///< [in] gives the PSD parameters.
191 size_t layer_i,
192 realT k, ///< [in] is the spatial frequency in m^-1.
193 realT lambda, ///< [in] is the observation wavelength in m
194 realT lambda_wfs, ///< [in] is the wavefront measurement wavelength in m
195 realT secZeta ///< [in] is the secant of the zenith distance
196 );
197
198 /// Get the fitting error for an actuator spacing d.
199 /**
200 * \todo generatlize for different alpha and beta
201 *
202 * \param atm gives the atmosphere parameters r_0 and L_0
203 * \param d is the actuator spacing in m
204 */
205 // realT fittingError(aoAtmosphere<realT> &atm, realT d);
206
207 template <typename iosT>
208 iosT &dumpPSD( iosT &ios );
209
210 /// Setup the configurator to configure this class
211 void setupConfig( app::appConfigurator &config /**< [in] the app::configurator object*/ );
212
213 /// Load the configuration of this class from a configurator
214 void loadConfig( app::appConfigurator &config /**< [in] the app::configurator object*/ );
215};
216
217template <typename realT>
221
222template <typename realT>
223vonKarmanSpectrum<realT>::vonKarmanSpectrum( bool subP, // [in] is the value of m_subPiston.
224 bool subT, // [in] is the value of m_subTipTilt.
225 realT D // [in] is the diameter
226)
227{
228 m_subPiston = subP;
229 m_subTipTilt = subT;
230 m_D = D;
231}
232
233template <typename realT>
238
239template <typename realT>
240void vonKarmanSpectrum<realT>::subPiston( bool sp /* [in] is the new value of m_subPiston */ )
241{
242 m_subPiston = sp;
243}
244
245template <typename realT>
250
251template <typename realT>
252void vonKarmanSpectrum<realT>::subTipTilt( bool st /* [in] the new value of m_subTipTilt */ )
253{
254 m_subTipTilt = st;
255}
256
257template <typename realT>
262
263template <typename realT>
264void vonKarmanSpectrum<realT>::scintillation( bool sc /* [in] the new value of m_scintillation */ )
265{
266 m_scintillation = sc;
267}
268
269template <typename realT>
274
275template <typename realT>
276int vonKarmanSpectrum<realT>::component( int cc /* [in] the new value of m_component */ )
277{
280 {
282 // mxError( "vonKarmanSpectrum::component", MXE_INVALIDARG, "Unknown component" );
283 return -1;
284 }
285
286 m_component = cc;
287 return 0;
288}
289
290template <typename realT>
292{
293 return m_D;
294}
295
296template <typename realT>
297void vonKarmanSpectrum<realT>::D( realT nd /**< [in] the new diameter in m */ )
298{
299 m_D = nd;
300}
301
302template <typename realT>
303template <class psdParamsT>
304realT vonKarmanSpectrum<realT>::operator()( psdParamsT &par, //< [in] gives the PSD parameters.
305 size_t layer_i,
306 realT k, // [in] is the spatial frequency in m^-1.
307 realT sec_zeta // [in] is the secant of the zenith distance.
308)
309{
310 realT k02;
311
312 ///\todo this needs to handle layers with different L_0
313 if( par.L_0( layer_i ) > 0 )
314 {
315 k02 = ( 1 ) / ( par.L_0( layer_i ) * par.L_0( layer_i ) );
316 }
317 else
318 k02 = 0;
319
320 if( k02 == 0 && k == 0 )
321 {
322 return 0;
323 }
324
325 realT Ppiston, Ptiptilt;
326
327 if( ( m_subPiston || m_subTipTilt ) )
328 {
329 if( m_D == 0 )
330 {
332 "Diameter D not set for Piston and/or TT subtraction." );
333
334 // mxError( "aoAtmosphere", MXE_PARAMNOTSET, "Diameter D not set for Piston and/or TT subtraction." );
335 return -1;
336 }
337 if( m_subPiston )
338 {
339 Ppiston = pow( 2 * math::func::jinc( math::pi<realT>() * k * m_D ), 2 );
340 }
341 else
342 Ppiston = 0;
343
344 if( m_subTipTilt )
345 {
346 Ptiptilt = pow( 4 * math::func::jincN( 2, math::pi<realT>() * k * m_D ), 2 );
347 }
348 else
349 Ptiptilt = 0;
350 }
351 else
352 {
353 Ppiston = 0;
354 Ptiptilt = 0;
355 }
356
357 return ( par.beta( layer_i ) * pow( k * k + k02, -1 * par.alpha( layer_i ) / 2 ) + par.beta_0( layer_i ) ) *
358 ( 1.0 - Ppiston - Ptiptilt ) * sec_zeta;
359}
360
361template <typename realT>
362template <class psdParamsT>
364 psdParamsT &par, // [in] gives the PSD parameters.
365 size_t layer_i,
366 realT k, // [in] is the spatial frequency in m^-1.
367 realT lambda, // [in] is the observation wavelength in m. Not used if par.nonKolmogorov==true
368 realT lambda_wfs, // [in] is the wavefront measurement wavelength in m. Only used if m_scintillation==true.
369 realT secZeta // [in] is the secant of the zenith distance.
370)
371{
372 realT psd = operator()( par, layer_i, k, secZeta );
373
374 if( par.nonKolmogorov() == false )
375 {
376 psd *= pow( par.lam_0() / lambda, 2 );
377 }
378
379 if( psd < 0 )
380 return -1;
381
382 if( m_scintillation )
383 {
385 {
386 psd *= ( par.X( k, lambda, secZeta ) );
387 }
389 {
390 psd *= ( par.Y( k, lambda, secZeta ) );
391 }
393 {
394 psd *= ( par.X_Z( k, lambda, lambda_wfs, secZeta ) );
395 }
397 {
398 internal::mxlib_error_report<verboseT>( error_t::notimpl, "Dispersive-aniso amplitude not implemented" );
399 // mxError( "vonKarmanSpectrum::operator()", MXE_NOTIMPL, "Dispersive-aniso amplitude not implemented" );
400 return 0;
401 }
402 else
403 {
404 internal::mxlib_error_report<verboseT>( error_t::invalidarg, "Invalid component specified" );
405 // mxError( "vonKarmanSpectrum::operator()", MXE_INVALIDARG, "Invalid component specified" );
406 return 0;
407 }
408 }
409
410 return psd;
411}
412
413/*template< typename realT>
414realT vonKarmanSpectrum<realT>::fittingError(aoAtmosphere<realT> &atm, realT d)
415{
416 realT k0;
417 if(atm.L_0(0) > 0)
418 {
419 k0 = 1/ (atm.L_0(0)*atm.L_0(0));
420 }
421 else k0 = 0;
422
423 return (math::pi<realT>() * math::six_fifths<realT>())* constants::a_PSD<realT>()/ pow(atm.r_0(),
424math::five_thirds<realT>()) * (1./pow( pow(0.5/d,2) + k0, math::five_sixths<realT>()));
425}*/
426
427template <typename realT>
428template <typename iosT>
430{
431 ios << "# PSD Parameters:" << '\n';
432 ios << "# ID = " << m_id << '\n';
433 ios << "# D = " << m_D << '\n';
434 ios << "# subPiston = " << std::boolalpha << m_subPiston << '\n';
435 ios << "# subTipTilt = " << std::boolalpha << m_subTipTilt << '\n';
436 ios << "# Scintillation = " << std::boolalpha << m_scintillation << '\n';
437 ios << "# Component = " << PSDComponent::compName( m_component ) << '\n';
438 return ios;
439}
440
441template <typename realT>
443{
444 using namespace mx::app;
445
446 config.add( "psd.D",
447 "",
448 "psd.D",
449 argType::Required,
450 "psd",
451 "D",
452 false,
453 "real",
454 "Aperture diameter. Used for piston and tip/tilt subtraction." );
455 config.add( "psd.subPiston", "", "psd.subPiston", argType::Required, "psd", "subPiston", false, "real", "" );
456 config.add( "psd.subTipTilt", "", "psd.subTipTilt", argType::Required, "psd", "subTipTilt", false, "real", "" );
457 config.add( "psd.scintillation",
458 "",
459 "psd.scintillation",
460 argType::Required,
461 "psd",
462 "scintillation",
463 false,
464 "real",
465 "" );
466 config.add( "psd.component", "", "psd.component", argType::Required, "psd", "component", false, "real", "" );
467}
468
469template <typename realT>
471{
472 // Here "has side effecs" means that the set function does more than simply copy the value.
473
474 config( m_D, "psd.D" );
475 config( m_subPiston, "psd.subPiston" );
476 config( m_subTipTilt, "psd.subTipTilt" );
477 config( m_scintillation, "psd.scintillation" );
478
479 std::string cn = PSDComponent::compName( m_component );
480 config( cn, "psd.component" );
481 component( PSDComponent::compNum( cn ) );
482}
483
484extern template struct vonKarmanSpectrum<float>;
485
486extern template struct vonKarmanSpectrum<double>;
487
488extern template struct vonKarmanSpectrum<long double>;
489
490#ifdef HASQUAD
491extern template struct vonKarmanSpectrum<__float128>;
492#endif
493
494} // namespace analysis
495} // namespace AO
496} // namespace mx
497
498#endif // aoPSDs_hpp
Provides a class to specify atmosphere parameters.
Calculate and provide constants related to adaptive optics.
@ dispAmplitude
The amplitude component of dispersive anisoplanatism.
Definition aoPSDs.hpp:55
@ phase
The phase or OPD.
Definition aoPSDs.hpp:52
@ dispPhase
The phase component of dispersive anisoplanatism.
Definition aoPSDs.hpp:54
@ amplitude
The amplitude.
Definition aoPSDs.hpp:53
@ notimpl
A component or technique is not implemented.
Definition error_t.hpp:31
@ paramnotset
A parameter was not set.
Definition error_t.hpp:32
@ invalidarg
An argument was invalid.
Definition error_t.hpp:29
error_t mxlib_error_report(const error_t &code, const std::string &expl, const std::source_location &loc=std::source_location::current())
Print a report to stderr given an mxlib error_t code and explanation and return the code.
Definition error.hpp:331
T2 jincN(const T1 &v, const T2 &x)
The JincN function.
Definition jinc.hpp:112
T jinc(const T &x)
The Jinc function.
Definition jinc.hpp:61
constexpr T pi()
Get the value of pi.
Definition constants.hpp:62
Declares and defines the Jinc and Jinc2 functions.
Declarations of some libarary wide utilities.
MXLIB_DEFAULT_VERBOSITY d
The default verbosity.
Definition error.hpp:202
The mxlib c++ namespace.
Definition mxlib.hpp:37
Manage calculations using the von Karman spatial power spectrum.
Definition aoPSDs.hpp:84
bool subTipTilt()
Get the value of m_subTipTilt.
Definition aoPSDs.hpp:246
realT D()
Get the value of the diameter m_D.
Definition aoPSDs.hpp:291
realT operator()(psdParamsT &par, size_t layer_i, realT k, realT sec_zeta)
Get the value of the PSD at spatial frequency k and a zenith distance.
Definition aoPSDs.hpp:304
iosT & dumpPSD(iosT &ios)
Get the fitting error for an actuator spacing d.
Definition aoPSDs.hpp:429
void setupConfig(app::appConfigurator &config)
Setup the configurator to configure this class.
Definition aoPSDs.hpp:442
bool subPiston()
Get the value of m_subPiston.
Definition aoPSDs.hpp:234
realT m_D
Diameter used for piston and tip/tilt subtraction, in m. Default is 1 m.
Definition aoPSDs.hpp:96
vonKarmanSpectrum()
Default Constructor.
Definition aoPSDs.hpp:218
bool scintillation()
Get the value of m_scintillation.
Definition aoPSDs.hpp:258
void loadConfig(app::appConfigurator &config)
Load the configuration of this class from a configurator.
Definition aoPSDs.hpp:470
int component()
Get the value of m_component.
Definition aoPSDs.hpp:270
bool m_subTipTilt
flag controlling whether tip and tilt are subtracted from the PSD. Default is false.
Definition aoPSDs.hpp:89
bool m_scintillation
flag controlling whether or not scintillation is included
Definition aoPSDs.hpp:92
bool m_subPiston
flag controlling whether piston is subtracted from the PSD. Default is true.
Definition aoPSDs.hpp:88
Class to manage a set of configurable values, and read their values from config/ini files and the com...
void add(const configTarget &tgt)
Add a configTarget.