API
 
Loading...
Searching...
No Matches
dmPokeXCorr.hpp
Go to the documentation of this file.
1/** \file dmPokeXCorr.hpp
2 * \brief The MagAO-X DM Poke Centering header file
3 *
4 * \ingroup dmPokeXCorr_files
5 */
6
7#ifndef dmPokeXCorr_hpp
8#define dmPokeXCorr_hpp
9
10#include <mx/improc/imageFilters.hpp>
11#include <mx/improc/imageXCorrFFT.hpp>
12using namespace mx::improc;
13
14#include <mx/math/fit/fitGaussian.hpp>
15
16#include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
17#include "../../magaox_git_version.h"
18
19/** \defgroup dmPokeXCorr
20 * \brief The MagAO-X application to center a DM pupil by poking actuators
21 *
22 * <a href="../handbook/operating/software/apps/dmPokeXCorr.html">Application Documentation</a>
23 *
24 * \ingroup apps
25 *
26 */
27
28/** \defgroup dmPokeXCorr_files
29 * \ingroup dmPokeXCorr
30 */
31
32namespace MagAOX
33{
34namespace app
35{
36
38{
39 static std::string configSection()
40 {
41 return "zrespM";
42 };
43 static std::string indiPrefix()
44 {
45 return "zrespM";
46 };
47};
48
49/// The MagAO-X DM to PWFS alignment Application
50/**
51 * \ingroup dmPokeXCorr
52 */
53class dmPokeXCorr : public MagAOXApp<true>,
54 public dev::dmPokeWFS<dmPokeXCorr>,
55 public dev::shmimMonitor<dmPokeXCorr, dev::dmPokeWFS<dmPokeXCorr>::wfsShmimT>,
56 public dev::shmimMonitor<dmPokeXCorr, dev::dmPokeWFS<dmPokeXCorr>::darkShmimT>,
57 public dev::shmimMonitor<dmPokeXCorr, zrespShmimT>,
58 public dev::telemeter<dmPokeXCorr>
59{
60 // Give the test harness access.
61 friend class dmPokeXCorr_test;
62
63 friend class dev::dmPokeWFS<dmPokeXCorr>;
64
66
67 friend class dev::shmimMonitor<dmPokeXCorr, dev::dmPokeWFS<dmPokeXCorr>::wfsShmimT>;
68
69 typedef dev::shmimMonitor<dmPokeXCorr, dev::dmPokeWFS<dmPokeXCorr>::wfsShmimT> shmimMonitorT;
70
71 friend class dev::shmimMonitor<dmPokeXCorr, dev::dmPokeWFS<dmPokeXCorr>::darkShmimT>;
72
73 typedef dev::shmimMonitor<dmPokeXCorr, dev::dmPokeWFS<dmPokeXCorr>::darkShmimT> darkShmimMonitorT;
74
75 friend class dev::shmimMonitor<dmPokeXCorr, zrespShmimT>;
76
77 typedef dev::shmimMonitor<dmPokeXCorr, zrespShmimT> zrespShmimMonitorT;
78
79 friend class dev::telemeter<dmPokeXCorr>;
80
82
83 protected:
84 /** \name Configurable Parameters
85 *@{
86 */
87
88 std::string m_zRespMFile;
89
90 ///@}
91
92 mx::improc::imageXCorrFFT<eigenImage<float>> m_xcorr;
93
94 mx::improc::milkImage<float> m_refIm;
95
96 public:
97 /// Default c'tor.
99
100 /// D'tor, declared and defined for noexcept.
102 {
103 }
104
105 /**\name MagAOX Interface
106 *
107 * @{
108 */
109 virtual void setupConfig();
110
111 /// Implementation of loadConfig logic, separated for testing.
112 /** This is called by loadConfig().
113 */
114 int loadConfigImpl(
115 mx::app::appConfigurator &_config /**< [in] an application configuration from which to load values*/ );
116
117 virtual void loadConfig();
118
119 /// Startup function
120 /**
121 *
122 */
123 virtual int appStartup();
124
125 /// Implementation of the FSM for dmPokeXCorr.
126 /**
127 * \returns 0 on no critical error
128 * \returns -1 on an error requiring shutdown
129 */
130 virtual int appLogic();
131
132 /// Shutdown the app.
133 /**
134 *
135 */
136 virtual int appShutdown();
137
138 ///@}
139
141 {
142 return *dynamic_cast<shmimMonitorT *>( this );
143 }
144
146 {
147 return *static_cast<darkShmimMonitorT *>( this );
148 }
149
150 /** \name zrespShmimMonitorT inteface
151 * @{
152 */
153
154 int allocate( const zrespShmimT &dummy );
155
156 int processImage( void *curr_src, const zrespShmimT &dummy );
157
159
161
162 ///@}
163
164 /** \name dmPokeWFS Interface
165 * @{
166 */
167
168 /// Run the sensor steps
169 /** Coordinates the actions of poking and collecting images.
170 * Upon completion this calls runSensor. If \p firstRun == true, one time
171 * actions such as taking a dark can be executed.
172 *
173 * \returns 0 on success
174 * \returns < 0 on an error
175 */
176 int runSensor( bool firstRun /**< [in] flag indicating this is the first call. triggers taking a dark if true.*/ );
177
178 /// Analyze the poke image
179 /** This analyzes the resulting poke image and reports the results.
180 *
181 * \returns 0 on success
182 * \returns < 0 on an error
183 */
184 int analyzeSensor();
185
186 ///@}
187
188 /** \name INDI Interface
189 * @{
190 */
191 protected:
192 ///@}
193
194 /** \name Telemeter Interface
195 *
196 * @{
197 */
198 int checkRecordTimes();
199
200 ///@}
201};
202
203dmPokeXCorr::dmPokeXCorr() : MagAOXApp( MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED )
204{
207
208 return;
209}
210
219
220int dmPokeXCorr::loadConfigImpl( mx::app::appConfigurator &_config )
221{
223
225
227
228 return 0;
229}
230
232{
233 if( loadConfigImpl( config ) < 0 )
234 {
235 m_shutdown = true;
236 }
237}
238
240{
242
244
246
247 // Gotta connect to the DM stream to find out its size
248 mx::improc::milkImage<float> mdm;
249 try
250 {
251 mdm.open( m_dmChan );
252 }
253 catch( const std::exception &e ) // this can check for invalid_argument and distinguish not existing
254 {
255 return log<software_error, -1>( { __FILE__, __LINE__, std::string( "exception opening DM: " ) + e.what() } );
256 }
257
259
260 return 0;
261}
262
276
287
289{
290 static_cast<void>( dummy );
291
293 {
295 }
296
297 return 0;
298}
299
300int dmPokeXCorr::processImage( void *curr_src, const zrespShmimT &dummy )
301{
302 static_cast<void>( dummy );
303
304 // Gotta connect to the DM stream to find out its size
305 // can't assume that we have connected anywhere else.
306 mx::improc::milkImage<float> mdm;
307 try
308 {
309 mdm.open( m_dmChan );
310 }
311 catch( const std::exception &e )
312 {
313 return log<software_error, -1>( { __FILE__, __LINE__, std::string( "exception opening DM: " ) + e.what() } );
314 }
315
316 mx::improc::eigenCube<float> zRespM(
318
319 mx::improc::eigenImage<float> refIm;
320 refIm.resize( zRespM.rows(), zRespM.cols() );
321 refIm.setZero();
322
323 for( size_t n = 0; n < m_poke_x.size(); ++n )
324 {
325 int actno = m_poke_y[n] * mdm.rows() + m_poke_x[n];
326
327 refIm += zRespM.image( actno );
328 }
329
330 m_refIm = refIm;
331
332 std::cerr << "Got reference: " << refIm.rows() << " x " << refIm.cols() << '\n';
333 try
334 {
335 m_xcorr.peakMethod( xcorrPeakMethod::mftOversamp );
336 m_xcorr.normalize( true );
337 m_xcorr.maxLag( 10 );
338 m_xcorr.tol( 0.001 );
339
340 m_xcorr.refIm( refIm, 1 );
341
342 }
343 catch( const std::exception &e )
344 {
345 return log<software_error, -1>( { __FILE__, __LINE__, std::string( "exception caught: \n" ) + e.what() } );
346 }
347 return 0;
348}
349
350int dmPokeXCorr::runSensor( bool firstRun )
351{
352 static_cast<void>( firstRun );
353
355
356 if( rv > 0 )
357 {
358 return 0;
359 }
360 else if( rv < 0 )
361 {
363 return rv;
364 }
365
366 return 0;
367}
368
370{
371 if( m_xcorr.refIm().rows() != m_pokeImage().rows() || m_xcorr.refIm().cols() != m_pokeImage().cols() )
372 {
373 std::cerr << "refIm: " << m_xcorr.refIm().rows() << " x " << m_xcorr.refIm().cols() << '\n';
374 std::cerr << "pokeIm: " << m_pokeImage().rows() << " x " << m_pokeImage().cols() << '\n';
375 return log<software_error, -1>( { __FILE__, __LINE__, "reference is not valid" } );
376 }
377
378 float xs, ys;
379
380 try
381 {
382 m_xcorr( xs, ys, m_pokeImage() );
383 }
384 catch( const std::exception &e )
385 {
386 return log<software_error, -1>( { __FILE__, __LINE__, std::string( "exception caught: \n" ) + e.what() } );
387 }
388
389 std::cerr.precision( 5 );
390 std::cerr << "dmPokeXCorr::analyzeSensor: " << xs << " " << ys << "\n";
391
392 if( updateMeasurement( xs, ys ) < 0 )
393 {
394 return log<software_error, -1>( { __FILE__, __LINE__, "error from dmPokeWFS::updateMeasurement" } );
395 }
396
397 return 0;
398}
399
404
405} // namespace app
406} // namespace MagAOX
407
408#endif // dmPokeXCorr_hpp
The base-class for MagAO-X applications.
Definition MagAOXApp.hpp:73
std::string m_configName
The name of the configuration file (minus .conf).
Definition MagAOXApp.hpp:83
stateCodes::stateCodeT state()
Get the current state code.
int m_shutdown
Flag to signal it's time to shutdown. When not 0, the main loop exits.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
A base class to coordinate poking a deformable mirror's actuators and synchronizedreads of a camera i...
int updateMeasurement(float deltaX, float deltaY)
mx::improc::milkImage< float > m_pokeImage
int basicRunSensor()
Run the basic +/- poke sensor steps.
int processImage(void *curr_src, const wfsShmimT &)
uint32_t m_depth
The depth of the circular buffer in the stream.
uint32_t m_width
The width of the images in the stream.
uint32_t m_height
The height of the images in the stream.
The MagAO-X DM to PWFS alignment Application.
dev::dmPokeWFS< dmPokeXCorr > dmPokeWFST
int processImage(void *curr_src, const zrespShmimT &dummy)
mx::improc::milkImage< float > m_refIm
mx::improc::imageXCorrFFT< eigenImage< float > > m_xcorr
int runSensor(bool firstRun)
Run the sensor steps.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
shmimMonitorT & shmimMonitor()
virtual int appShutdown()
Shutdown the app.
darkShmimMonitorT & darkShmimMonitor()
int allocate(const zrespShmimT &dummy)
int analyzeSensor()
Analyze the poke image.
virtual int appLogic()
Implementation of the FSM for dmPokeXCorr.
virtual int appStartup()
Startup function.
dmPokeXCorr()
Default c'tor.
friend class dmPokeXCorr_test
#define DMPOKEWFS_APP_SHUTDOWN
Call dmPokeWFS::appShutdown with error checking.
#define DMPOKEWFS_APP_STARTUP
Call dmPokeWFS::appStartup with error checking.
#define DMPOKEWFS_SETUP_CONFIG(cfig)
Call dmPokeWFS::setupConfig with error checking.
#define DMPOKEWFS_LOAD_CONFIG(cfig)
Call dmPokeWFS::loadConfig with error checking.
#define DMPOKEWFS_APP_LOGIC
Call dmPokeWFS::appLogic with error checking.
@ READY
The device is ready for operation, but is not operating.
Definition dm.hpp:26
#define SHMIMMONITORT_APP_STARTUP(SHMIMMONITORT)
Call shmimMonitorT::appStartup with error checking for a typedef-ed shmimMonitor.
#define SHMIMMONITORT_UPDATE_INDI(SHMIMMONITORT)
Call shmimMonitorT::updateINDI with error checking for a typedef-ed shmimMonitor.
#define SHMIMMONITORT_SETUP_CONFIG(SHMIMMONITORT, cfig)
Call shmimMonitorT::setupConfig with error checking for a typedef-ed shmimMonitor.
#define SHMIMMONITORT_APP_LOGIC(SHMIMMONITORT)
Call shmimMonitorT::appLogic with error checking for a typedef-ed shmimMonitor.
#define SHMIMMONITORT_APP_SHUTDOWN(SHMIMMONITORT)
Call shmimMonitorT::appShutodwn with error checking for a typedef-ed shmimMonitor.
#define SHMIMMONITORT_LOAD_CONFIG(SHMIMMONITORT, cfig)
Call shmimMonitorT::loadConfig with error checking for a typedef-ed shmimMonitor.
A device base class which saves telemetry.
Definition telemeter.hpp:69
int checkRecordTimes(const telT &tel, telTs... tels)
Check the time of the last record for each telemetry type and make an entry if needed.
static std::string configSection()
static std::string indiPrefix()
Software ERR log entry.
Log entry recording DM poke centering results.
#define TELEMETER_APP_LOGIC
Call telemeter::appLogic with error checking.
#define TELEMETER_LOAD_CONFIG(cfig)
Call telemeter::loadConfig with error checking.
#define TELEMETER_APP_STARTUP
Call telemeter::appStartup with error checking.
#define TELEMETER_SETUP_CONFIG(cfig)
Call telemeter::setupConfig with error checking.
#define TELEMETER_APP_SHUTDOWN
Call telemeter::appShutdown with error checking.