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";
80template <
typename _aoSystemT>
85 typedef _aoSystemT aoSystemT;
86 typedef typename aoSystemT::realT realT;
87 typedef Eigen::Array<realT, -1, -1> imageT;
304 uint32_t scrnLengthPixels();
306 uint32_t scrnLengthPixels( uint32_t n );
310 realT scrnLength( uint32_t n );
312 uint32_t maxShift( realT dt );
314 uint32_t maxShift( uint32_t n, realT dt );
341template <
typename aoSystemT>
347template <
typename aoSystemT>
356template <
typename aoSystemT>
366template <
typename aoSystemT>
372template <
typename aoSystemT>
382template <
typename aoSystemT>
388template <
typename aoSystemT>
398template <
typename aoSystemT>
404template <
typename aoSystemT>
407 if( shl != m_shLevel )
414template <
typename aoSystemT>
420template <
typename aoSystemT>
423 if( osh != m_outerSubHarmonics )
425 m_outerSubHarmonics = osh;
430template <
typename aoSystemT>
433 return m_outerSubHarmonics;
436template <
typename aoSystemT>
439 if( shp != m_shPreCalc )
446template <
typename aoSystemT>
452template <
typename aoSystemT>
455 if( rtn != m_retain )
462template <
typename aoSystemT>
468template <
typename aoSystemT>
471 if( fg != m_forceGen )
479template <
typename aoSystemT>
485template <
typename aoSystemT>
488 if( dd != m_dataDir )
496template <
typename aoSystemT>
502template <
typename aoSystemT>
505 if( m_aosys ==
nullptr )
508 err::paramnotset,
"mx::AO::sim::turbAtmosphere::setLayers",
"ao system is not set (m_aosys is nullptr)" );
511 size_t nLayers = scrnSz.size();
513 if( nLayers != m_aosys->atm.n_layers() )
516 "mx::AO::sim::turbAtmosphere::setLayers",
517 "Size of scrnSz vector does not match atmosphere." );
520 if( nLayers != m_layers.size() )
525 m_layers.resize( nLayers );
527 for(
size_t i = 0; i < nLayers; ++i )
529 m_layers[i].setLayer(
this, i, scrnSz[i] );
534 if( nLayers != m_subHarms.size() )
539 m_subHarms.resize( nLayers );
541 for(
size_t i = 0; i < nLayers; ++i )
543 m_subHarms[i].turbAtmo(
this );
544 m_subHarms[i].preCalc( m_shPreCalc );
545 m_subHarms[i].level( m_shLevel );
546 m_subHarms[i].outerSubHarmonics( m_outerSubHarmonics );
547 m_subHarms[i].initGrid( i );
552template <
typename aoSystemT>
555 if( m_aosys ==
nullptr )
558 err::paramnotset,
"mx::AO::sim::turbAtmosphere::setLayers",
"atmosphere is not set (m_atm is nullptr)" );
561 size_t n = m_aosys->atm.n_layers();
563 setLayers( std::vector<size_t>( n, scrnSz ) );
566template <
typename aoSystemT>
569 return m_layers.size();
572template <
typename aoSystemT>
575 if( n >= m_layers.size() )
577 mxThrowException(
err::invalidarg,
"mx::AO::sim::turbAtmosphere::layer",
"n too large for number of layers." );
583template <
typename aoSystemT>
589template <
typename aoSystemT>
595template <
typename aoSystemT>
596uint32_t turbAtmosphere<aoSystemT>::scrnLengthPixels( uint32_t n )
606template <
typename aoSystemT>
607realT turbAtmosphere<aoSystemT>::scrnLength()
612template <
typename aoSystemT>
613realT turbAtmosphere<aoSystemT>::scrnLength( uint32_t n )
618template <
typename aoSystemT>
619uint32_t turbAtmosphere<aoSystemT>::maxShift( realT dt )
624template <
typename aoSystemT>
625uint32_t turbAtmosphere<aoSystemT>::maxShift( uint32_t n, realT dt )
630template <
typename aoSystemT>
633 if( m_dataDir !=
"" && !m_forceGen )
635 std::string fbase = m_dataDir;
641 for(
size_t i = 0; i < m_layers.size(); ++i )
643 fname = fbase + ioutils::convertToString<int>( i ) +
".fits";
644 ff.
read( m_layers[i].m_phase, fname );
647 this->setChangePoint();
652 sigproc::psdFilter<realT, 2> filt;
654 for(
size_t i = 0; i < m_layers.size(); ++i )
656 if( m_layers[i].m_phase.rows() != m_layers[i].scrnSz() || m_layers[i].m_phase.cols() != m_layers[i].scrnSz() )
658 mxThrowException(
err::sizeerr,
"mx::AO::sim::turbAtmosphere::genLayers",
"layer phase not allocated." );
661 if( m_layers[i].m_freq.rows() != m_layers[i].scrnSz() || m_layers[i].m_freq.cols() != m_layers[i].scrnSz() )
663 mxThrowException(
err::sizeerr,
"mx::AO::sim::turbAtmosphere::genLayers",
"layer freq not allocated." );
666 if( m_layers[i].m_psd.rows() != m_layers[i].scrnSz() || m_layers[i].m_psd.cols() != m_layers[i].scrnSz() )
668 mxThrowException(
err::sizeerr,
"mx::AO::sim::turbAtmosphere::genLayers",
"layer psd not allocated." );
671 for(
size_t jj = 0; jj < m_layers[i].m_scrnSz; ++jj )
673 for(
size_t ii = 0; ii < m_layers[i].m_scrnSz; ++ii )
675 m_layers[i].m_phase( ii, jj ) = m_normVar;
679 realT dkx = m_layers[i].m_freq( 1, 0 ) - m_layers[i].m_freq( 0, 0 );
680 realT dky = m_layers[i].m_freq( 0, 1 ) - m_layers[i].m_freq( 0, 0 );
681 filt.psdSqrt( m_layers[i].m_psd, dkx, dky );
683 filt( m_layers[i].m_phase );
687 m_subHarms[i].screen( m_layers[i].m_phase );
693 for(
size_t i = 0; i < m_layers.size(); ++i )
695 m_layers[i].genDealloc();
698 for(
size_t i = 0; i < m_subHarms.size(); ++i )
700 m_subHarms[i].deinit();
704 if( m_dataDir !=
"" )
706 std::string fbase = m_dataDir;
712 for(
size_t i = 0; i < m_layers.size(); ++i )
714 fname = fbase + ioutils::convertToString<int>( i ) +
".fits";
715 ff.
write( fname, m_layers[i].m_phase );
719 this->setChangePoint();
722template <
typename aoSystemT>
725 if( this->isChanged() )
728 "mx::AO::sim::turbAtmosphere::shift",
729 "configuration has changed but genLayers has not been run." );
734 if( phase.rows() != m_wfSz || phase.cols() != m_wfSz )
739 if( m_layers.size() > 1 )
741#pragma omp parallel for
742 for(
size_t j = 0; j < m_layers.size(); ++j )
744 m_layers[j].shift( dt );
749 for(
size_t j = 0; j < m_layers.size(); ++j )
751 m_layers[j].shift( dt );
757 for(
size_t j = 0; j < m_layers.size(); ++j )
760 sqrt( m_aosys->atm.layer_Cn2( j ) ) * m_layers[j].m_shiftPhase.block( m_buffSz, m_buffSz, m_wfSz, m_wfSz );
767template <
typename aoSystemT>
768int turbAtmosphere<aoSystemT>::frames(
int f )
775template <
typename aoSystemT>
776size_t turbAtmosphere<aoSystemT>::frames()
781template <
typename aoSystemT>
784 static_cast<void>( ps );
788template <
typename aoSystemT>
794 err::paramnotset,
"mx::AO::sim::turbAtmosphere<aoSystemT>::nextWF",
"the AO system pointer is not set" );
800 err::paramnotset,
"mx::AO::sim::turbAtmosphere<aoSystemT>::nextWF",
"the m_pupil pointer is not set" );
803 shift( wf.
phase, m_nWf * m_timeStep );
806 wf.
phase *= *m_pupil;
808 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 invalid config settings
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 setWrite(bool wrflag=true)
Set the write flag.
void post()
Update the metadata and post all semaphores.
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.
bool outerSubHarmonics()
Get whether outer subharmonics are included.
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 outerSubHarmonics(bool osh)
Set whether outer subharmonics are included.
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.