API
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>
12 using 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 
32 namespace MagAOX
33 {
34 namespace 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  */
53 class 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 
81  typedef dev::telemeter<dmPokeXCorr> telemeterT;
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 
97 public:
98  /// Default c'tor.
99  dmPokeXCorr();
100 
101  /// D'tor, declared and defined for noexcept.
102  ~dmPokeXCorr() noexcept
103  {
104  }
105 
106  /**\name MagAOX Interface
107  *
108  * @{
109  */
110  virtual void setupConfig();
111 
112  /// Implementation of loadConfig logic, separated for testing.
113  /** This is called by loadConfig().
114  */
115  int loadConfigImpl(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,
157  const zrespShmimT & dummy
158  );
159 
160  using dmPokeWFST::allocate;
161 
162  using dmPokeWFST::processImage;
163 
164  ///@}
165 
166  /** \name dmPokeWFS Interface
167  * @{
168  */
169 
170  /// Run the sensor steps
171  /** Coordinates the actions of poking and collecting images.
172  * Upon completion this calls runSensor. If \p firstRun == true, one time
173  * actions such as taking a dark can be executed.
174  *
175  * \returns 0 on success
176  * \returns < 0 on an error
177  */
178  int runSensor(bool firstRun /**< [in] flag indicating this is the first call. triggers taking a dark if true.*/);
179 
180  /// Analyze the poke image
181  /** This analyzes the resulting poke image and reports the results.
182  *
183  * \returns 0 on success
184  * \returns < 0 on an error
185  */
186  int analyzeSensor();
187 
188  ///@}
189 
190  /** \name INDI Interface
191  * @{
192  */
193 protected:
194  ///@}
195 
196  /** \name Telemeter Interface
197  *
198  * @{
199  */
200  int checkRecordTimes();
201 
202 
203 
204  ///@}
205 };
206 
207 dmPokeXCorr::dmPokeXCorr() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
208 {
209  return;
210 }
211 
213 {
214  DMPOKEWFS_SETUP_CONFIG(config);
215 
217 
218  TELEMETER_SETUP_CONFIG(config);
219 }
220 
221 int dmPokeXCorr::loadConfigImpl(mx::app::appConfigurator &_config)
222 {
223  DMPOKEWFS_LOAD_CONFIG(_config);
224 
226 
227  TELEMETER_LOAD_CONFIG(_config);
228 
229  return 0;
230 }
231 
233 {
234  if (loadConfigImpl(config) < 0)
235  {
236  m_shutdown = true;
237  }
238 }
239 
241 {
243 
245 
247 
248  //Gotta connect to the DM stream to find out its size
249  mx::improc::milkImage<float> mdm;
250  try
251  {
252  mdm.open(m_dmChan);
253  }
254  catch(const std::exception& e) //this can check for invalid_argument and distinguish not existing
255  {
256  return log<software_error,-1>({__FILE__, __LINE__, std::string("exception opening DM: ") + e.what()});
257  }
258 
259 
261 
262  return 0;
263 }
264 
266 {
268 
273 
275 
276  return 0;
277 }
278 
280 {
282 
284 
286 
287  return 0;
288 }
289 
291 {
292  static_cast<void>(dummy);
293 
295  {
297  }
298 
299  return 0;
300 }
301 
302 int dmPokeXCorr::processImage( void * curr_src,
303  const zrespShmimT & dummy
304  )
305 {
306  static_cast<void>(dummy);
307 
308  //Gotta connect to the DM stream to find out its size
309  //can't assume that we have connected anywhere else.
310  mx::improc::milkImage<float> mdm;
311  try
312  {
313  mdm.open(m_dmChan);
314  }
315  catch(const std::exception& e)
316  {
317  return log<software_error,-1>({__FILE__, __LINE__, std::string("exception opening DM: ") + e.what()});
318  }
319 
320  mx::improc::eigenCube<float> zRespM ((float *) curr_src, zrespShmimMonitorT::m_width, zrespShmimMonitorT::m_height, zrespShmimMonitorT::m_depth);
321 
322  mx::improc::eigenImage<float> refIm;
323  refIm.resize(zRespM.rows(), zRespM.cols());
324  refIm.setZero();
325 
326  for(size_t n = 0; n < m_poke_x.size(); ++n)
327  {
328  int actno = m_poke_y[n]*mdm.rows() + m_poke_x[n];
329 
330  refIm += zRespM.image(actno);
331  }
332 
333  m_refIm = refIm;
334 
335  m_xcorr.refIm(m_refIm());
336 
337  return 0;
338 }
339 
340 int dmPokeXCorr::runSensor(bool firstRun)
341 {
342  static_cast<void>(firstRun);
343 
344  int rv = dmPokeWFST::basicRunSensor();
345 
346  if (rv > 0)
347  {
348  return 0;
349  }
350  else if (rv < 0)
351  {
352  log<software_error>({__FILE__, __LINE__});
353  return rv;
354  }
355 
356  return 0;
357 }
358 
360 {
361  if(m_xcorr.refIm().rows() != m_pokeImage().rows() || m_xcorr.refIm().rows() != m_pokeImage().cols() )
362  {
363  return 0;
364  }
365 
366  float xs, ys;
367 
368  m_xcorr(xs, ys, m_pokeImage());
369 
370  std::cerr << "dmPokeXCorr::analyzeSensor: " << xs << " " << ys << "\n";
371 
372  if(updateMeasurement(xs, ys) < 0)
373  {
374  return log<software_error,-1>({__FILE__, __LINE__, "error from dmPokeWFS::updateMeasurement"});
375  }
376 
377  return 0;
378 }
379 
381 {
383 }
384 
385 
386 
387 } // namespace app
388 } // namespace MagAOX
389 
390 #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.
Definition: MagAOXApp.hpp:2297
int m_shutdown
Flag to signal it's time to shutdown. When not 0, the main loop exits.
Definition: MagAOXApp.hpp:100
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
Definition: MagAOXApp.hpp:1804
A base class to coordinate poking a deformable mirror's actuators and synchronizedreads of a camera i...
Definition: dmPokeWFS.hpp:137
int updateMeasurement(float deltaX, float deltaY)
Definition: dmPokeWFS.hpp:1015
mx::improc::milkImage< float > m_pokeImage
Definition: dmPokeWFS.hpp:198
int basicRunSensor()
Run the basic +/- poke sensor steps.
Definition: dmPokeWFS.hpp:944
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.
Definition: dmPokeXCorr.hpp:59
int processImage(void *curr_src, const zrespShmimT &dummy)
mx::improc::milkImage< float > m_refIm
Definition: dmPokeXCorr.hpp:94
mx::improc::imageXCorrFFT< eigenImage< float > > m_xcorr
Definition: dmPokeXCorr.hpp:92
int runSensor(bool firstRun)
Run the sensor steps.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
virtual int appShutdown()
Shutdown the app.
virtual void loadConfig()
virtual void setupConfig()
int allocate(const zrespShmimT &dummy)
shmimMonitorT & shmimMonitor()
int analyzeSensor()
Analyze the poke image.
virtual int appLogic()
Implementation of the FSM for dmPokeXCorr.
darkShmimMonitorT & darkShmimMonitor()
virtual int appStartup()
Startup function.
#define DMPOKEWFS_APP_SHUTDOWN
Call dmPokeWFS::appShutdown with error checking.
Definition: dmPokeWFS.hpp:1238
#define DMPOKEWFS_APP_STARTUP
Call dmPokeWFS::appStartup with error checking.
Definition: dmPokeWFS.hpp:1224
#define DMPOKEWFS_SETUP_CONFIG(cfig)
Call dmPokeWFS::setupConfig with error checking.
Definition: dmPokeWFS.hpp:1205
#define DMPOKEWFS_LOAD_CONFIG(cfig)
Call dmPokeWFS::loadConfig with error checking.
Definition: dmPokeWFS.hpp:1217
#define DMPOKEWFS_APP_LOGIC
Call dmPokeWFS::appLogic with error checking.
Definition: dmPokeWFS.hpp:1231
@ READY
The device is ready for operation, but is not operating.
Definition: stateCodes.hpp:56
std::ostream & cerr()
Definition: dm.hpp:24
#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.
Definition: telemeter.hpp:281
static std::string configSection()
Definition: dmPokeXCorr.hpp:39
static std::string indiPrefix()
Definition: dmPokeXCorr.hpp:43
Software ERR log entry.
Log entry recording DM poke centering results.
#define TELEMETER_APP_LOGIC
Call telemeter::appLogic with error checking.
Definition: telemeter.hpp:339
#define TELEMETER_LOAD_CONFIG(cfig)
Call telemeter::loadConfig with error checking.
Definition: telemeter.hpp:325
#define TELEMETER_APP_STARTUP
Call telemeter::appStartup with error checking.
Definition: telemeter.hpp:332
#define TELEMETER_SETUP_CONFIG(cfig)
Call telemeter::setupConfig with error checking.
Definition: telemeter.hpp:314
#define TELEMETER_APP_SHUTDOWN
Call telemeter::appShutdown with error checking.
Definition: telemeter.hpp:346