mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
fourierCovariance.hpp
Go to the documentation of this file.
1/** \file fourierCovariance.hpp
2 * \author Jared R. Males (jaredmales@gmail.com)
3 * \brief Calculation of the modal covariance in the Fourier basis.
4 * \ingroup mxAO_files
5 *
6 */
7
8#ifndef fourierCovariance_hpp
9#define fourierCovariance_hpp
10
11#include <gsl/gsl_integration.h>
12#include <gsl/gsl_errno.h>
13
14#include "../../math/constants.hpp"
20#include "../../mxlib.hpp"
24
26
27#include "aoAtmosphere.hpp"
28#include "aoPSDs.hpp"
29#include "aoSystem.hpp"
30#include "varmapToImage.hpp"
31
32namespace mx
33{
34namespace AO
35{
36namespace analysis
37{
38
39#ifndef WSZ
40
41/** \def WSZ
42 * \brief The size of the gsl_integration workspaces.
43 */
44#define WSZ 100000
45
46#endif
47
48// Forward Declaration
49template <typename realT, typename aosysT>
50struct fourierCovariance;
51
52/// Worker for the azimuthal integral (in phi) for the basic Fourier mode covariance.
53/**
54 * \param phi the angle at which to evaluate the integrand
55 * \param params a pointer to a object of type fourierCovariance<realT, aosyT>
56 *
57 * \tparam realT a floating point type used for all calculations
58 * \tparam aosysT the type of the AO system structure
59 *
60 * \ingroup mxAOAnalytic
61 */
62template <typename realT, typename aosysT>
63realT phiInt_basic( realT phi, void *params )
64{
65
67
68 realT D = Pp->aosys->D();
69
70 int p = Pp->p;
71 realT m = Pp->m;
72 realT n = Pp->n;
73
74 int pp = Pp->pp;
75 realT mp = Pp->mp;
76 realT np = Pp->np;
77
78 realT k = Pp->k;
79
80 realT cosp = cos( phi );
81 realT sinp = sin( phi );
82
83 /*** no prime ***/
84 realT kmn_p, kmn_m;
85 realT Ji_mn_p, Ji_mn_m;
86 realT Q_mn; //, Qs_mn;
87
88 kmn_p = sqrt( pow( k * cosp + m / D, 2 ) + pow( k * sinp + n / D, 2 ) );
89 kmn_m = sqrt( pow( k * cosp - m / D, 2 ) + pow( k * sinp - n / D, 2 ) );
90
91 Ji_mn_p = math::func::jinc( math::pi<realT>() * D * kmn_p );
92 Ji_mn_m = math::func::jinc( math::pi<realT>() * D * kmn_m );
93
94 realT N = 1. / sqrt( 0.5 + p * math::func::jinc( math::two_pi<realT>() * sqrt( m * m + n * n ) ) );
95
96 Q_mn = N * ( Ji_mn_p + p * Ji_mn_m );
97
98 /*** primed ***/
99 realT kmpnp_p, kmpnp_m;
100 realT Ji_mpnp_p, Ji_mpnp_m;
101 realT Q_mpnp; //, Qs_mpnp;
102
103 kmpnp_p = sqrt( pow( k * cosp + mp / D, 2 ) + pow( k * sinp + np / D, 2 ) );
104 kmpnp_m = sqrt( pow( k * cosp - mp / D, 2 ) + pow( k * sinp - np / D, 2 ) );
105
106 Ji_mpnp_p = math::func::jinc( math::pi<realT>() * D * kmpnp_p );
107 Ji_mpnp_m = math::func::jinc( math::pi<realT>() * D * kmpnp_m );
108
109 realT Np = 1. / sqrt( 0.5 + pp * math::func::jinc( math::two_pi<realT>() * sqrt( mp * mp + np * np ) ) );
110
111 Q_mpnp = Np * ( Ji_mpnp_p + pp * Ji_mpnp_m );
112
113 realT P = Pp->aosys->psd( Pp->aosys->atm, 0, k, 1.0 ); // vonKarmanPSD(k, D, L0, Pp->subPiston, Pp->subTipTilt);
114
115 return P * k * ( Q_mn * Q_mpnp );
116}
117
118/// Worker for the azimuthal integral (in phi) for the modified Fourier mode covariance.
119/**
120 * \param phi the angle at which to evaluate the integrand
121 * \param params a pointer to a object of type fourierCovariance<realT, aosyT>
122 *
123 * \tparam realT a floating point type used for all calculations
124 * \tparam aosysT the type of the AO system structure
125 */
126template <typename realT, typename aosysT>
127realT phiInt_mod( realT phi, void *params )
128{
129
131
132 // realT L0 = Pp->aosys->atm.L_0();
133 realT D = Pp->aosys->D();
134
135 int p = Pp->p;
136 realT m = Pp->m;
137 realT n = Pp->n;
138
139 int pp = Pp->pp;
140 realT mp = Pp->mp;
141 realT np = Pp->np;
142
143 realT k = Pp->k;
144
145 realT mnCon = Pp->mnCon;
146
147 realT cosp = cos( phi );
148 realT sinp = sin( phi );
149
150 /*** no prime ***/
151 realT kmn_p, kmn_m;
152 realT Ji_mn_p, Ji_mn_m;
153
154 kmn_p = sqrt( pow( k * cosp + m / D, 2 ) + pow( k * sinp + n / D, 2 ) );
155 kmn_m = sqrt( pow( k * cosp - m / D, 2 ) + pow( k * sinp - n / D, 2 ) );
156
157 Ji_mn_p = math::func::jinc( math::pi<realT>() * D * kmn_p );
158 Ji_mn_m = math::func::jinc( math::pi<realT>() * D * kmn_m );
159
160 /*** primed ***/
161 realT kmpnp_p, kmpnp_m;
162 realT Ji_mpnp_p, Ji_mpnp_m;
163
164 kmpnp_p = sqrt( pow( k * cosp + mp / D, 2 ) + pow( k * sinp + np / D, 2 ) );
165 kmpnp_m = sqrt( pow( k * cosp - mp / D, 2 ) + pow( k * sinp - np / D, 2 ) );
166
167 Ji_mpnp_p = math::func::jinc( math::pi<realT>() * D * kmpnp_p );
168 Ji_mpnp_m = math::func::jinc( math::pi<realT>() * D * kmpnp_m );
169
170 realT QQ;
171
172 if( p == pp )
173 {
174 QQ = 2.0 * ( Ji_mn_p * Ji_mpnp_p + Ji_mn_m * Ji_mpnp_m );
175 }
176 else
177 {
178 QQ = 2.0 * ( Ji_mn_p * Ji_mpnp_m + Ji_mn_m * Ji_mpnp_p );
179 }
180
181 realT P = Pp->aosys->psd(
182 Pp->aosys->atm, 0, k, 1.0 ); // psd(Pp->aosys->atm, k, Pp->aosys->lam_sci(), Pp->aosys->lam_wfs(), 1.0);
183
184 /*if(mnCon > 0 )
185 {
186 if( k*D <= mnCon )
187 {
188 P *= pow(math::two_pi<realT>()*Pp->aosys->atm.v_wind()* k *
189 (Pp->aosys->minTauWFS(0)+Pp->aosys->deltaTau()),2);
190 }
191 }*/
192
193 return P * k * QQ;
194}
195
196/// Worker function for the radial integral in the covariance calculation
197/**
198 * \param k the spatial frequency at which to evaluate the integrand
199 * \param params a pointer to a object of type fourierCovariance<realT, aosyT>
200 *
201 * \tparam realT a floating point type used for all calculations. As of Nov 2016 must be double due to gsl_integration.
202 * \tparam aosysT the type of the AO system structure
203 */
204template <typename realT, typename aosysT>
205realT kInt( realT k, void *params )
206{
208
209 realT result, error;
210
211 gsl_function func;
212
213 // Here choose between basic and modified Fourier modes.
214 if( Pp->useBasic )
215 {
216 func.function = &phiInt_basic<realT, aosysT>;
217 }
218 else
219 {
220 func.function = &phiInt_mod<realT, aosysT>;
221 }
222 func.params = Pp;
223
224 Pp->k = k;
225
226 // Tolerances of 1e-4 seem to be all we can ask for
227 gsl_integration_qag(
228 &func, 0., math::two_pi<double>(), 1e-10, 1e-4, WSZ, GSL_INTEG_GAUSS21, Pp->phi_w, &result, &error );
229
230 return result;
231}
232
233/// Structure to manage the Fourier mode covariance calculation, passed to integration functions
234/**
235 * \tparam realT a floating point type used for all calculations. As of Nov 2016 must be double due to gsl_integration.
236 * \tparam aosysT the type of the AO system structure
237 */
238template <typename realT, typename aosysT>
240{
241 /// Pointer to an AO system, which contains the relevant spatial PSD of turbulence.
242 aosysT *aosys{ nullptr };
243
244 /// Flag controlling use of basic or modified Fourier modes. If true, the basic sin/cos modes are used. If false
245 /// (default), the modified modes are u sed.
246 bool useBasic{ false };
247
248 /// p-index of the unprimed mode. +/-1 for modified modes. If basic, then +1==>cosine, -1==>sine.
249 int p;
250
251 /// The m-index of the unprimed mode, corresponding to the \f$ k_u = m/D \f$ component of spatial frequency.
252 realT m;
253
254 /// The n-indexof the unprimed mode, corresponding to the \f$ k_v = n/D \f$ component of spatial frequency.
255 realT n;
256
257 /// p-index of the primed mode. +/-1 for modified modes. If basic, then +1==>cosine, -1==>sine.
258 int pp;
259
260 /// The m-index of the primed mode, corresponding to the \f$ k_u = m/D \f$ component of spatial frequency.
261 realT mp;
262
263 /// The n-indexof the primed mode, corresponding to the \f$ k_v = n/D \f$ component of spatial frequency.
264 realT np;
265
266 /// Spatial frequency being calculated, passed for use in the integrand worker functions.
267 realT k;
268
269 /// The maximum controlled value of spatial frequency (k*D). If < 0 then not controlled.
270 realT mnCon{ 0 };
271
272 /// Absolute tolerance for the radial integral. Default is 1e-7.
273 realT absTol{ 1e-7 };
274
275 /// Relative tolerance for the radial integral. Default is 1e-7.
276 realT relTol{ 1e-7 };
277
278 /// Working memory for the azimuthal integral.
279 gsl_integration_workspace *phi_w;
280
281 /// Working memory for the radial integral.
282 gsl_integration_workspace *k_w;
283
284 /// Constructor
286 {
287 phi_w = gsl_integration_workspace_alloc( WSZ );
288 k_w = gsl_integration_workspace_alloc( WSZ );
289 }
290
291 /// Destructor
293 {
294 gsl_integration_workspace_free( phi_w );
295 gsl_integration_workspace_free( k_w );
296 }
297
298 /// Calculate the covariance between the two modes.
299 /** \todo document me
300 * \todo handle gsl errors
301 */
302 realT getVariance( realT &error )
303 {
304 realT result;
305
306 gsl_function func;
307 func.function = &kInt<realT, aosysT>;
308 func.params = this;
309
310 gsl_set_error_handler_off();
311
312 int ec = gsl_integration_qagiu( &func, 0, absTol, relTol, WSZ, k_w, &result, &error );
313
314 // Finally, convert to square sampling.
315 return result;
316 }
317};
318
319/// Calculate a vector of Fourier mode variances.
320template <typename realT, typename aosysT>
321int fourierVarVec( const std::string &fname, int N, aosysT &aosys, realT absTol, realT relTol, bool modifed = true )
322{
323
324 std::vector<realT> var( N, 0 );
325
326 ipc::ompLoopWatcher<> watcher( N, std::cerr );
327
328 realT mnCon = 0;
329 if( aosys.d_min( 0 ) > 0 )
330 {
331 mnCon = floor( aosys.D() / aosys.d_min( 0 ) / 2.0 );
332 }
333
334#pragma omp parallel
335 {
337 Pp.absTol = absTol;
338 Pp.relTol = relTol;
339 Pp.aosys = &aosys;
340
341 Pp.mnCon = mnCon;
342
343 realT result, error;
344
345#pragma omp for schedule( dynamic, 5 )
346 for( int i = 0; i < N; ++i )
347 {
348 Pp.p = +1;
349 Pp.m = i + 1;
350 Pp.n = 0;
351
352 Pp.pp = +1;
353 Pp.mp = i + 1;
354 Pp.np = 0;
355
356 result = Pp.getVariance( error );
357
358 var[i] = result;
359
360 watcher.incrementAndOutputStatus();
361 }
362 }
363
364 std::ofstream fout;
365 fout.open( fname );
366
367 realT D = aosys.D();
368 realT r_0 = aosys.atm.r_0();
369 realT tot = 1.0299 * pow( D / r_0, 5. / 3. );
370
371 realT sum = 0;
372
373 std::cout << 0 << " " << 0 << " " << 0 << " " << tot << "\n";
374 for( int i = 0; i < N; ++i )
375 {
376 realT k = ( i + 1 ) / D;
377
378 realT P = aosys.psd( aosys.atm, 0, k, 1.0 ); // aosys.lam_sci(), 0, aosys.lam_wfs(), 1.0);
379
380 if( mnCon > 0 )
381 {
382 if( k * D < mnCon )
383 {
384 P *= pow( math::two_pi<realT>() * aosys.atm.v_wind() * k * ( aosys.minTauWFS( 0 ) + aosys.deltaTau() ),
385 2 );
386 }
387 }
388
389 sum += var[i];
390 fout << i + 1 << " " << var[i] << " " << P / pow( D, 2 ) << " " << tot - sum << "\n";
391 }
392
393 fout.close();
394
395 return 0;
396}
397
398/// Calculate a map of Fourier variances by convolution with the PSD
399/** Uses the Airy pattern for the circularly unobstructed aperture.
400 *
401 * \returns 0 on success
402 * \returns -1 on error
403 */
404template <typename realT, typename aosysT>
405int fourierPSDMap( improc::eigenImage<realT> &var, ///< [out] The variance estimated by convolution with the PSD
406 improc::eigenImage<realT> &psd, ///< [out] the PSD map
407 int N, ///< [in] the number of components to analyze
408 int overSample,
409 aosysT &aosys ///< [in[ the AO system defining the PSD characteristics.
410)
411{
412 N *= overSample;
413 psd.resize( 2 * N + 1, 2 * N + 1 );
414
415 realT mnCon = 0;
416 if( aosys.d_min() > 0 )
417 {
418 mnCon = floor( aosys.D() / aosys.d_min() / 2.0 );
419 }
420
421 for( int i = 0; i <= N; ++i )
422 {
423 for( int j = -N; j <= N; ++j )
424 {
425
426 realT D = aosys.D();
427 realT k = sqrt( pow( i, 2 ) + pow( j, 2 ) ) / D / overSample;
428
429 realT P = aosys.psd( aosys.atm, k, aosys.lam_sci(), 0, aosys.lam_wfs(), 1.0 );
430
431 if( mnCon > 0 )
432 {
433 if( k * D < mnCon )
434 {
435 P *= pow( math::two_pi<realT>() * aosys.atm.v_wind() * k * ( aosys.minTauWFS() + aosys.deltaTau() ),
436 2 );
437 }
438 }
439
440 psd( N + i, N + j ) = P / pow( D * overSample, 2 );
441 psd( N - i, N - j ) = P / pow( D * overSample, 2 );
442 }
443 }
444
445 // Create Airy PSF for convolution with PSD psd.
446 Eigen::Array<realT, -1, -1> psf;
447 psf.resize( 2 * N + 3, 2 * N + 3 );
448 for( int i = 0; i < psf.rows(); ++i )
449 {
450 for( int j = 0; j < psf.cols(); ++j )
451 {
452 psf( i, j ) = mx::math::func::airyPattern(
453 sqrt( pow( i - floor( .5 * psf.rows() ), 2 ) + pow( j - floor( .5 * psf.cols() ), 2 ) ) / overSample );
454 }
455 }
456
457 mx::AO::analysis::varmapToImage( var, psd, psf );
458
459 return 0;
460}
461
462template <typename realT>
464 const std::string &fname, ///< [out] the path where the output FITS file will be written
465 int N, ///< [in] the linear number of Fourier modes across the aperture. The Nyquist frequency is set by N/2.
466 realT D,
467 realT L_0,
468 bool subPist,
469 bool subTilt,
470 realT absTol,
471 realT relTol,
472 bool modified = true )
473{
474 std::vector<mx::sigproc::fourierModeDef> ml;
476
478
479 aosys.loadMagAOX();
480
481 // This is just a normalization parameter in this context.
482 aosys.atm.r_0( 1.0, 0.5e-6 );
483
484 aosys.D( D );
485 aosys.atm.L_0( L_0 );
486 aosys.psd.subPiston( subPist );
487 aosys.psd.subTipTilt( subTilt );
488
489 int psz = ml.size();
490
491 Eigen::Array<realT, -1, -1> covar( psz, psz );
492 covar.setZero();
493
494 // int ncalc = 0.5*( psz*psz - psz);
495
496 ipc::ompLoopWatcher<> watcher( psz, std::cout );
497
498 std::cerr << "Starting . . .\n";
499#pragma omp parallel
500 {
502 Pp.absTol = absTol;
503 Pp.relTol = relTol;
504 Pp.aosys = &aosys;
505
506 if( !modified )
507 Pp.useBasic = true;
508
509 realT result, error;
510
511#pragma omp for schedule( static, 5 )
512 for( int i = 0; i < psz; ++i )
513 {
514 for( int j = i; j < psz; ++j )
515 {
516 Pp.p = ml[i].p;
517 Pp.m = ml[i].m;
518 Pp.n = ml[i].n;
519
520 Pp.pp = ml[j].p;
521 Pp.mp = ml[j].m;
522 Pp.np = ml[j].n;
523 result = Pp.getVariance( error );
524
525 covar( i, j ) = result;
526 }
527 watcher.incrementAndOutputStatus();
528 }
529 }
530
531 fits::fitsHeader head;
532 head.append( "DIAMETER", aosys.D(), "Diameter in meters" );
533 head.append( "NSUBAP", N, "Linear number of s.f. sampled" );
534 head.append( "L0", aosys.atm.L_0( 0 ), "Outer scale (L_0) in meters" );
535 head.append( "SUBPIST", aosys.psd.subPiston(), "Piston subtractioon true/false flag" );
536 head.append( "SUBTILT", aosys.psd.subTipTilt(), "Tip/Tilt subtractioon true/false flag" );
537 head.append( "ABSTOL", absTol, "Absolute tolerance in qagiu" );
538 head.append( "RELTOL", relTol, "Relative tolerance in qagiu" );
539
540 fitsHeaderGitStatus( head, "mxlib", mxlib_comp_current_sha1(), mxlib_comp_repo_modified() );
541
543 ff.write( fname + ".fits", covar, head );
544
545 return 0;
546}
547
548template <typename realT, typename aosysT>
549int fourierCovarMapSeparated(
550 const std::string &fname, int N, aosysT &aosys, realT absTol, realT relTol, bool modified = true )
551{
552 std::vector<mx::sigproc::fourierModeDef> ml;
554
555 int psz = 0.5 * ml.size();
556
557 Eigen::Array<realT, -1, -1> covar_pp( (int)( 0.5 * psz ), (int)( .5 * psz ) ),
558 covar_ppp( (int)( 0.5 * psz ), (int)( 0.5 * psz ) );
559 covar_pp.setZero();
560 covar_ppp.setZero();
561
562 realT mnCon = 0;
563 if( aosys.d_min() > 0 )
564 {
565 mnCon = floor( aosys.D() / aosys.d_min() / 2.0 );
566 }
567
568 ipc::ompLoopWatcher<> watcher( ( psz + 1 ) * 0.125 * ( psz + 1 ) * 2, std::cout );
569
570#pragma omp parallel
571 {
572
573 fourierCovariance<realT, aosysT> Pp;
574 Pp.absTol = absTol;
575 Pp.relTol = relTol;
576 Pp.aosys = &aosys;
577
578 if( !modified )
579 Pp.useBasic = true;
580
581 Pp.mnCon = mnCon;
582
583 realT result, error;
584
585#pragma omp for schedule( dynamic, 5 )
586 for( int i = 0; i < psz; i += 2 )
587 {
588 for( int j = 0; j <= 0.5 * i; ++j )
589 {
590 for( int k = 0; k < 2; ++k )
591 {
592 Pp.p = ml[i].p;
593 Pp.m = ml[i].m;
594 Pp.n = ml[i].n;
595
596 Pp.pp = ml[2 * j + k].p;
597 Pp.mp = ml[2 * j + k].m;
598 Pp.np = ml[2 * j + k].n;
599 result = Pp.getVariance( error );
600
601 if( Pp.p == Pp.pp )
602 {
603 covar_pp( i / 2, j ) = result;
604 }
605 else
606 {
607 covar_ppp( i / 2, j ) = result;
608 }
609 watcher.incrementAndOutputStatus();
610 }
611 }
612 }
613 }
614
615 fits::fitsHeader head;
616 head.append( "DIAMETER", aosys.D(), "Diameter in meters" );
617 head.append( "L0", aosys.atm.L_0(), "Outer scale (L_0) in meters" );
618 head.append( "SUBPIST", aosys.psd.subPiston(), "Piston subtractioon true/false flag" );
619 head.append( "SUBTILT", aosys.psd.subTipTilt(), "Tip/Tilt subtractioon true/false flag" );
620 head.append( "ABSTOL", absTol, "Absolute tolerance in qagiu" );
621 head.append( "RELTOL", relTol, "Relative tolerance in qagiu" );
622
623 fitsHeaderGitStatus( head, "mxlib", mxlib_comp_current_sha1(), mxlib_comp_repo_modified() );
624
625 fits::fitsFile<realT> ff;
626 ff.write( fname + "_pp.fits", covar_pp, head );
627 ff.write( fname + "_ppp.fits", covar_ppp, head );
628
629 return 0;
630}
631
632template <typename realT>
633void calcKLCoeffs( const std::string &outFile, const std::string &cvFile )
634{
635 fits::fitsFile<realT> ff;
636
637 Eigen::Array<realT, -1, -1> cvT, cv, evecs, evals;
638
639 ff.read( cv, cvFile );
640
641 // cvT = cv.block(0,0, 1000,1000);//.transpose();
642
643 std::cerr << cvT.rows() << " " << cvT.cols() << "\n";
644 std::cerr << "1\n";
645 math::syevrMem<double> mem;
646
647 double t0 = sys::get_curr_time();
648
649 int info = math::eigenSYEVR( evecs, evals, cv, 0, -1, 'U', &mem );
650
651 double t1 = sys::get_curr_time();
652
653 std::cerr << "2\n";
654
655 if( info != 0 )
656 {
657 std::cerr << "info =" << info << "\n";
658 exit( 0 );
659 }
660
661 std::cerr << "Time = " << t1 - t0 << " secs\n";
662
663 // Normalize the eigenvectors
664 for( int i = 0; i < evecs.cols(); ++i )
665 {
666 evecs.col( i ) = evecs.col( i ) / sqrt( fabs( evals( i ) ) );
667 }
668
669 ff.write( outFile, evecs );
670}
671
672template <typename eigenArrT1, typename eigenArrT2, typename eigenArrT3>
673void makeKL( eigenArrT1 &kl, eigenArrT2 &evecs, eigenArrT3 &&rvecs )
674{
675
676 int tNims = evecs.rows();
677 int tNpix = rvecs.rows();
678
679 int n_modes = tNims;
680
681 // Now calculate KL images
682 /*
683 * KL = E^T * R ==> C = A^T * B
684 */
686 CblasTrans,
687 CblasTrans,
688 n_modes,
689 tNpix,
690 tNims,
691 1.,
692 evecs.data(),
693 evecs.rows(),
694 rvecs.data(),
695 rvecs.rows(),
696 0.,
697 kl.data(),
698 kl.rows() );
699}
700
701template <typename realT>
702void makeFKL( const std::string &outFile, const std::string &coeffs, int N, int pupSize )
703{
704 fits::fitsFile<realT> ff;
705 Eigen::Array<realT, -1, -1> evecs;
706
707 ff.read( evecs, coeffs );
708
709 improc::eigenCube<realT> Rims;
711
712 std::cout << Rims.planes() << " " << evecs.cols() << "\n";
713
714 Eigen::Array<realT, -1, -1> kl;
715 kl.resize( Rims.planes(), Rims.rows() * Rims.cols() );
716
717 std::cerr << 1 << "\n";
718 makeKL( kl, evecs, Rims.cube() );
719 std::cerr << 2 << "\n";
720
721 Eigen::Array<realT, -1, -1> klT = kl.transpose();
722 // kl.resize(0,0);
723 // Rims.resize(0,0);
724 // evecs.resize(0,0);
725
726 improc::eigenCube<realT> klims( klT.data(), Rims.rows(), Rims.cols(), Rims.planes() );
727
728 improc::eigenCube<realT> klimsR;
729 klimsR.resize( klims.rows(), klims.cols(), klims.planes() );
730
731 for( int i = 0; i < klims.planes(); ++i )
732 {
733 klimsR.image( i ) = klims.image( klims.planes() - 1 - i );
734 }
735
736 ff.write( outFile, klimsR );
737 std::cerr << 3 << "\n";
738}
739
740} // namespace analysis
741} // namespace AO
742} // namespace mx
743
744#endif // fourierCovariance_hpp
Utilities related to the Airy pattern point spread function.
Provides a class to specify atmosphere parameters.
Spatial power spectra used in adaptive optics.
Declares and defines an analytical AO system.
realT L_0(const size_t &n)
Get the value of the outer scale for a single layer.
realT r_0()
Get the value of Fried's parameter r_0 at the reference wavelength lam_0.
Describes an analytic adaptive optics (AO) system.
Definition aoSystem.hpp:64
void loadMagAOX()
Load parameters corresponding to the MagAO-X system.
void D(realT nD)
Set the value of the primary mirror diameter.
Class to manage interactions with a FITS file.
Definition fitsFile.hpp:84
error_t write(const dataT *im, int d1, int d2, int d3, fitsHeader< verboseT > *head)
Write the contents of a raw array to the FITS file.
Class to manage a FITS file metadata header and provide fast access to the cards by keyword.
error_t append(const fitsHeaderCard< verboseT > &card)
Append a fitsHeaderCard to the end of the header.
A class to track the number of iterations in an OMP parallelized loop.
void incrementAndOutputStatus()
Increment and output status.
An image cube with an Eigen API.
Tools for using the eigen library for image processing.
Interfaces to Lapack and BLAS for Eigen-like arrays.
Declares and defines a class to work with a FITS file.
realT phiInt_mod(realT phi, void *params)
Worker for the azimuthal integral (in phi) for the modified Fourier mode covariance.
int fourierPSDMap(improc::eigenImage< realT > &var, improc::eigenImage< realT > &psd, int N, int overSample, aosysT &aosys)
Calculate a map of Fourier variances by convolution with the PSD.
int fourierCovarMap(const std::string &fname, int N, realT D, realT L_0, bool subPist, bool subTilt, realT absTol, realT relTol, bool modified=true)
#define WSZ
The size of the gsl_integration workspaces.
int fourierVarVec(const std::string &fname, int N, aosysT &aosys, realT absTol, realT relTol, bool modifed=true)
Calculate a vector of Fourier mode variances.
realT kInt(realT k, void *params)
Worker function for the radial integral in the covariance calculation.
Functions for generating 2D Fourier modes.
@ modified
The modified Fourier basis from males_guyon_2018.
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
MXLAPACK_INT eigenSYEVR(arrT &eigvec, arrT &eigval, arrT &X, int ev0=0, int ev1=-1, char UPLO='L', syevrMem< typename arrT::Scalar > *mem=0)
Calculate select eigenvalues and eigenvectors of an Eigen Array.
@ error
A general error has occurred.
Definition error_t.hpp:28
void fitsHeaderGitStatus(fitsHeaderT &head, const std::string &repoName, const char *sha1, int modified)
Write the status of a Git repository to HISTORY in a FITS header.
int makeFourierBasis_Rect(cubeT &cube, int dim, int N, int basisType, typename cubeT::Scalar ang=0)
Generate a rectangular Fourier basis.
int makeFourierModeFreqs_Rect(std::vector< fourierModeDef > &spf, int N)
Generate a rectangular spatial frequency grid.
#define MX_FOURIER_MODIFIED
Signifies the modified Fourier basis.
realT airyPattern(realT x)
The classical Airy pattern.
T jinc(const T &x)
The Jinc function.
Definition jinc.hpp:61
constexpr T pi()
Get the value of pi.
Definition constants.hpp:62
constexpr T two_pi()
Get the value of 2pi.
realT phiInt_basic(realT phi, void *params)
Worker for the azimuthal integral (in phi) for the basic Fourier mode covariance.
void varmapToImage(imageT &im, imageT &varmap, imageT &psf)
Convert a wavefront variance map to an intensity image by convolving with the PSF.
void gemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA, const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const dataT &alpha, const dataT *A, const int lda, const dataT *B, const int ldb, const dataT &beta, dataT *C, const int ldc)
Template Wrapper for cblas xGEMM.
typeT get_curr_time()
Get the current system time in seconds.
Declares and defines the Jinc and Jinc2 functions.
Declarations of some libarary wide utilities.
The mxlib c++ namespace.
Definition mxlib.hpp:37
Track iterations in an OMP parallelized looop.
Structure to manage the Fourier mode covariance calculation, passed to integration functions.
realT m
The m-index of the unprimed mode, corresponding to the component of spatial frequency.
int p
p-index of the unprimed mode. +/-1 for modified modes. If basic, then +1==>cosine,...
realT n
The n-indexof the unprimed mode, corresponding to the component of spatial frequency.
realT getVariance(realT &error)
Calculate the covariance between the two modes.
realT absTol
Absolute tolerance for the radial integral. Default is 1e-7.
int pp
p-index of the primed mode. +/-1 for modified modes. If basic, then +1==>cosine, -1==>sine.
aosysT * aosys
Pointer to an AO system, which contains the relevant spatial PSD of turbulence.
realT np
The n-indexof the primed mode, corresponding to the component of spatial frequency.
gsl_integration_workspace * phi_w
Working memory for the azimuthal integral.
gsl_integration_workspace * k_w
Working memory for the radial integral.
realT relTol
Relative tolerance for the radial integral. Default is 1e-7.
realT mnCon
The maximum controlled value of spatial frequency (k*D). If < 0 then not controlled.
realT mp
The m-index of the primed mode, corresponding to the component of spatial frequency.
realT k
Spatial frequency being calculated, passed for use in the integrand worker functions.
Utilities for working with time.
A utility to convert a wavefront variance map to an intensity image.