29 #ifndef mx_AO_sim_turbAtmosphere_hpp
30 #define mx_AO_sim_turbAtmosphere_hpp
35 #include "../../sigproc/psdFilter.hpp"
36 #include "../../sigproc/psdUtils.hpp"
38 #include "../../base/changeable.hpp"
40 #include "../../improc/milkImage.hpp"
42 #include "../../math/constants.hpp"
43 #include "../../math/func/jinc.hpp"
44 #include "../../math/randomT.hpp"
46 #include "../../ioutils/fits/fitsFile.hpp"
47 #include "../../ioutils/stringUtils.hpp"
48 #include "../../sys/timeUtils.hpp"
51 #include "turbSubHarmonic.hpp"
52 #include "wavefront.hpp"
55 #define BREAD_CRUMB std::cout << "DEBUG: " << __FILE__ << " " << __LINE__ << "\n";
81 template<
typename _aoSystemT>
87 typedef _aoSystemT aoSystemT;
88 typedef typename aoSystemT::realT realT;
90 typedef Eigen::Array<realT, -1, -1> imageT;
321 template<
typename aoSystemT>
327 template<
typename aoSystemT>
340 template<
typename aoSystemT>
349 m_phaseWork.resize(m_wfSz, m_wfSz);
352 template<
typename aoSystemT>
358 template<
typename aoSystemT>
369 template<
typename aoSystemT>
375 template<
typename aoSystemT>
385 template<
typename aoSystemT>
391 template<
typename aoSystemT>
401 template<
typename aoSystemT>
407 template<
typename aoSystemT>
410 if(shp != m_shPreCalc)
417 template<
typename aoSystemT>
423 template<
typename aoSystemT>
433 template<
typename aoSystemT>
439 template<
typename aoSystemT>
450 template<
typename aoSystemT>
456 template<
typename aoSystemT>
467 template<
typename aoSystemT>
473 template<
typename aoSystemT>
476 if(m_aosys ==
nullptr)
478 mxThrowException(
err::paramnotset,
"mx::AO::sim::turbAtmosphere::setLayers",
"ao system is not set (m_aosys is nullptr)");
481 size_t nLayers = scrnSz.size();
483 if(nLayers != m_aosys->atm.n_layers())
485 mxThrowException(
err::invalidarg,
"mx::AO::sim::turbAtmosphere::setLayers",
"Size of scrnSz vector does not match atmosphere.");
488 if(nLayers != m_layers.size())
493 m_layers.resize(nLayers);
495 for(
size_t i=0; i< nLayers; ++i)
497 m_layers[i].setLayer(
this, i, scrnSz[i]);
502 if(nLayers != m_subHarms.size())
507 m_subHarms.resize(nLayers);
509 for(
size_t i=0; i< nLayers; ++i)
511 m_subHarms[i].turbAtmo(
this);
512 m_subHarms[i].preCalc(m_shPreCalc);
513 m_subHarms[i].level(m_shLevel);
514 m_subHarms[i].initGrid(i);
519 template<
typename aoSystemT>
522 if(m_aosys ==
nullptr)
524 mxThrowException(
err::paramnotset,
"mx::AO::sim::turbAtmosphere::setLayers",
"atmosphere is not set (m_atm is nullptr)");
527 size_t n = m_aosys->atm.n_layers();
529 setLayers( std::vector<size_t>(n, scrnSz));
532 template<
typename aoSystemT>
535 return m_layers.size();
538 template<
typename aoSystemT>
541 if(n >= m_layers.size())
543 mxThrowException(
err::invalidarg,
"mx::AO::sim::turbAtmosphere::layer",
"n too large for number of layers.");
549 template<
typename aoSystemT>
555 template<
typename aoSystemT>
558 if(m_dataDir !=
"" && !m_forceGen)
560 std::string fbase = m_dataDir;
566 for(
size_t i=0; i< m_layers.size(); ++i)
568 fname = fbase + ioutils::convertToString<int>(i) +
".fits";
569 ff.
read(m_layers[i].m_phase, fname);
575 sigproc::psdFilter<realT,2> filt;
577 for(
size_t i=0; i< m_layers.size(); ++i)
579 if(m_layers[i].m_phase.rows() != m_layers[i].scrnSz() || m_layers[i].m_phase.cols() != m_layers[i].scrnSz())
581 mxThrowException(
err::sizeerr,
"mx::AO::sim::turbAtmosphere::genLayers",
"layer phase not allocated.");
584 if(m_layers[i].m_freq.rows() != m_layers[i].scrnSz() || m_layers[i].m_freq.cols() != m_layers[i].scrnSz())
586 mxThrowException(
err::sizeerr,
"mx::AO::sim::turbAtmosphere::genLayers",
"layer freq not allocated.");
589 if(m_layers[i].m_psd.rows() != m_layers[i].scrnSz() || m_layers[i].m_psd.cols() != m_layers[i].scrnSz())
591 mxThrowException(
err::sizeerr,
"mx::AO::sim::turbAtmosphere::genLayers",
"layer psd not allocated.");
594 for(
size_t jj = 0; jj < m_layers[i].m_scrnSz; ++jj)
596 for(
size_t ii = 0; ii < m_layers[i].m_scrnSz; ++ii)
598 m_layers[i].m_phase(ii,jj) = m_normVar;
602 realT dkx = m_layers[i].m_freq(1,0)-m_layers[i].m_freq(0,0);
603 realT dky = m_layers[i].m_freq(0,1)-m_layers[i].m_freq(0,0);
604 filt.psdSqrt(m_layers[i].m_psd, dkx, dky);
606 filt(m_layers[i].m_phase);
610 m_subHarms[i].screen(m_layers[i].m_phase);
616 for(
size_t i=0; i< m_layers.size(); ++i)
618 m_layers[i].genDealloc();
621 for(
size_t i=0; i< m_subHarms.size(); ++i)
623 m_subHarms[i].deinit();
629 std::string fbase = m_dataDir;
635 for(
size_t i=0; i< m_layers.size(); ++i)
637 fname = fbase + ioutils::convertToString<int>(i) +
".fits";
638 ff.
write(fname, m_layers[i].m_phase);
643 template<
typename aoSystemT>
650 if(phase.rows() != m_wfSz || phase.cols() != m_wfSz)
654 m_phaseWork.setZero();
656 #pragma omp parallel for
657 for(
size_t j=0; j< m_layers.size(); ++j)
659 m_layers[j].shift( dt );
663 m_phaseWork += sqrt( m_aosys->atm.layer_Cn2(j)) * m_layers[j].m_shiftPhase.block(m_buffSz, m_buffSz, m_wfSz, m_wfSz);
672 template<
typename aoSystemT>
673 int turbAtmosphere<aoSystemT>::frames(
int f)
680 template<
typename aoSystemT>
681 size_t turbAtmosphere<aoSystemT>::frames()
686 template<
typename aoSystemT>
689 static_cast<void>(ps);
693 template<
typename aoSystemT>
698 mxThrowException(
err::paramnotset,
"mx::AO::sim::turbAtmosphere<aoSystemT>::nextWF",
"the AO system pointer is not set");
703 mxThrowException(
err::paramnotset,
"mx::AO::sim::turbAtmosphere<aoSystemT>::nextWF",
"the m_pupil pointer is not set");
706 shift( wf.
phase, m_nWf * m_timeStep);
709 wf.
phase *= *m_pupil;
711 realT pixVal = sqrt(m_aosys->Fg())*(m_aosys->D()/m_wfSz);
A simple class to track member data changes.
mxException for invalid arguments
mxException for parameters which aren't set
mxException for a size error
Class to manage interactions with a FITS file.
int write(const dataT *im, int d1, int d2, int d3, fitsHeader *head)
Write the contents of a raw array to the FITS file.
int read(dataT *data)
Read the contents of the FITS file into an array.
Class to interface with an ImageStreamIO image in shared memory.
void post()
Update the metadata and post all semaphores.
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
Eigen::Map< Eigen::Array< scalarT, -1, -1 > > eigenMap
Definition of the eigenMap type, which is an alias for Eigen::Map<Array>.
A turbulent atmosphere simulator.
uint32_t buffSz()
Get the interpolation buffer size.
aoSystemT * m_aosys
The AO system object containing all system parameters. See aoSystem.
uint32_t m_buffSz
Buffer to apply around wavefront for interpolation.
int wfPS(realT ps)
dummy function for simulatedAOSystem. Does nothing.
uint32_t nLayers()
Get the number of layers.
std::vector< turbLayer< aoSystemT > > m_layers
Vector of turbulent layers.
bool forceGen()
Get whether new screen generation is forced.
int m_nWf
Number of iterations which have occurred.
void retain(bool rtn)
Set whether memory for screen generation is retained.
std::vector< turbSubHarmonic< turbAtmosphere > > m_subHarms
Sub-harmonic layers.
void wfSz(uint32_t ws)
Set the wavefront size.
void genLayers()
Generate all phase screens.
std::string dataDir()
Get the data directory for saving phase screens.
aoSystemT * aosys()
Get the pointer to an AO system object.
uint32_t shLevel()
Get the subharmonic level.
imageT * m_pupil
A pointer to the pupil mask.
uint32_t wfSz()
Get the wavefront size.
bool retain()
Get whether memory for screen generation is retained.
realT m_timeStep
Length of each iteration, in seconds.
void setLayers(const std::vector< size_t > &scrnSz)
Setup the layers and prepare them for phase screen generation.
void forceGen(bool fg)
Set whether new screen generation is forced.
bool shPreCalc()
Get whether subharmonic modes are pre-calculated.
math::normDistT< realT > & normVar()
Get the random number generator.
void shPreCalc(bool shp)
Set whether subharmonic modes are pre-calculated.
void shLevel(uint32_t shl)
Set the subharmonic level.
void dataDir(const std::string &dd)
Set the data directory for saving phase screens.
size_t m_frames
Length of the turbulence sequence.
turbLayer< aoSystemT > & layer(uint32_t n)
Get a layer.
turbAtmosphere()
Default c'tor.
uint32_t m_wfSz
Size of the wavefront in pixels.
math::normDistT< realT > m_normVar
Normal random deviate generator. This seeded in the constructor.
void setup(uint32_t wfSz, uint32_t buffSz, aoSystemT *aosys, uint32_t shLevel)
Setup the overall atmosphere.
void buffSz(uint32_t bs)
Set the interpolation buffer size.
void setLayers(const size_t scrnSz)
Setup the layers and prepare them for phase screen generation.
void aosys(aoSystemT *aos)
Set the pointer to an AO system object.
Simulation of a single turbulent layer.
Structure containing the phase and amplitude of a wavefront
realImageT amplitude
The wavefront amplitude.
realImageT phase
The wavefront phase.
Declaration and definition of a turbulence layer.