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