API
 
Loading...
Searching...
No Matches
refRMS.hpp
Go to the documentation of this file.
1/** \file refRMS.hpp
2 * \brief The MagAO-X user gain control app
3 *
4 * \ingroup app_files
5 */
6
7#ifndef refRMS_hpp
8#define refRMS_hpp
9
10#include <limits>
11
12#include <mx/improc/eigenCube.hpp>
13#include <mx/improc/eigenImage.hpp>
14
15#include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
16#include "../../magaox_git_version.h"
17
18namespace MagAOX
19{
20namespace app
21{
22
23struct refShmimT
24{
25 static std::string configSection()
26 {
27 return "refShmim";
28 };
29
30 static std::string indiPrefix()
31 {
32 return "refShmim";
33 };
34};
35
36
38{
39 static std::string configSection()
40 {
41 return "maskShmim";
42 };
43
44 static std::string indiPrefix()
45 {
46 return "maskShmim";
47 };
48};
49
50/** \defgroup refRMS Calculate the RMS of the ref subtracted image
51 * \brief Calculates the r.m.s. of the reference subtracted WFS image.
52 *
53 * <a href="../handbook/operating/software/apps/refRMS.html">Application Documentation</a>
54 *
55 * \ingroup apps
56 *
57 */
58
59/** \defgroup refRMS_files User Gain Control
60 * \ingroup refRMS
61 */
62
63/** MagAO-X application to calculate the RMS of the reference subtracted WFS image.
64 *
65 * \ingroup refRMS
66 *
67 */
68class refRMS : public MagAOXApp<true>, public dev::shmimMonitor<refRMS, refShmimT>,
69 public dev::shmimMonitor<refRMS,maskShmimT>
70{
71
72 //Give the test harness access.
73 friend class refRMS_test;
74
77
78public:
79
80 //The base shmimMonitor type
83
84 ///Floating point type in which to do all calculations.
85 typedef float realT;
86
88
89protected:
90
91 /** \name Configurable Parameters
92 *@{
93 */
94
95 std::string m_fpsSource; ///< Device name for getting fps. This device should have *.fps.current.
96
97 ///@}
98
99 mx::improc::eigenImage<realT> m_currRef;
100 mx::improc::eigenImage<realT> m_mask;
101 bool m_maskValid {false};
103
104 mx::sigproc::circularBufferIndex<float, cbIndexT> m_rms;
105
106 mx::sigproc::circularBufferIndex<float, cbIndexT> m_mean;
107
112
113 float m_fps {0}; ///< Current FPS from the FPS source.
114
115public:
116 /// Default c'tor.
117 refRMS();
118
119 /// D'tor, declared and defined for noexcept.
122
123 virtual void setupConfig();
124
125 /// Implementation of loadConfig logic, separated for testing.
126 /** This is called by loadConfig().
127 */
128 int loadConfigImpl( mx::app::appConfigurator & _config /**< [in] an application configuration from which to load values*/);
129
130 virtual void loadConfig();
131
132 /// Startup function
133 /**
134 *
135 */
136 virtual int appStartup();
137
138 /// Implementation of the FSM for refRMS.
139 /**
140 * \returns 0 on no critical error
141 * \returns -1 on an error requiring shutdown
142 */
143 virtual int appLogic();
144
145 /// Shutdown the app.
146 /**
147 *
148 */
149 virtual int appShutdown();
150
151protected:
152
153
154 int allocate( const refShmimT & dummy /**< [in] tag to differentiate shmimMonitor parents.*/);
155
156 int processImage( void * curr_src, ///< [in] pointer to start of current frame.
157 const refShmimT & dummy ///< [in] tag to differentiate shmimMonitor parents.
158 );
159
160
161 int allocate( const maskShmimT & dummy /**< [in] tag to differentiate shmimMonitor parents.*/);
162
163 int processImage( void * curr_src, ///< [in] pointer to start of current frame.
164 const maskShmimT & dummy ///< [in] tag to differentiate shmimMonitor parents.
165 );
166
167
168 pcf::IndiProperty m_indiP_refrms;
169
170 pcf::IndiProperty m_indiP_fpsSource;
172
173
174};
175
176inline
177refRMS::refRMS() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
178{
179
182
183 return;
184}
185
186inline
188{
191
192 config.add("rms.fpsSource", "", "rms.fpsSource", argType::Required, "rms", "fpsSource", false, "string", "Device name for getting fps. This device should have *.fps.current.");
193}
194
195inline
196int refRMS::loadConfigImpl( mx::app::appConfigurator & _config )
197{
199
201
202 _config(m_fpsSource, "rms.fpsSource");
203
204 return 0;
205}
206
207inline
209{
210 loadConfigImpl(config);
211}
212
213inline
215{
216 createROIndiNumber( m_indiP_refrms, "refrms", "Reference RMS", "");
217 indi::addNumberElement(m_indiP_refrms, "one_sec", 0, 1, 1000, "One Second rms");
218 indi::addNumberElement(m_indiP_refrms, "two_sec", 0, 1, 1000, "Two Second rms");
219 indi::addNumberElement(m_indiP_refrms, "five_sec", 0, 1, 1000, "Five Second rms");
220 indi::addNumberElement(m_indiP_refrms, "ten_sec", 0, 1, 1000, "Five Second rms");
222
223 if(m_fpsSource != "")
224 {
225 REG_INDI_SETPROP(m_indiP_fpsSource, m_fpsSource, std::string("fps"));
226 }
227
229 {
230 return log<software_error,-1>({__FILE__, __LINE__});
231 }
232
234 {
235 return log<software_error,-1>({__FILE__, __LINE__});
236 }
237
239
240 return 0;
241}
242
243inline
245{
246
248 {
249 return log<software_error,-1>({__FILE__,__LINE__});
250 }
251
253 {
254 return log<software_error,-1>({__FILE__,__LINE__});
255 }
256
257 if( m_rms.size() > 0 )
258 {
259 if(m_rms.size() >= m_rms.maxEntries())
260 {
261 m_rms_1sec = 0;
262 if(m_rms.size() > 1.0*m_fps)
263 {
264 int N = 0;
265 for(size_t n=0; n < 1.0*m_fps; ++n)
266 {
267 m_rms_1sec += m_rms[n];
268 ++N;
269 }
270 m_rms_1sec /= N;
271
272 std::cerr << m_rms_1sec << " ";
273
274 }
275
276 m_rms_2sec = 0;
277 if(m_rms.size() > 2.0*m_fps)
278 {
279 int N = 0;
280 for(size_t n=0; n < 2.0*m_fps; ++n)
281 {
282 m_rms_2sec += m_rms[n];
283 ++N;
284 }
285 m_rms_2sec /= N;
286
287 std::cerr << m_rms_2sec << " ";
288 }
289
290 m_rms_5sec = 0;
291 if(m_rms.size() > 5.0*m_fps)
292 {
293 int N = 0;
294 for(size_t n=0; n < 5.0*m_fps; ++n)
295 {
296 m_rms_5sec += m_rms[n];
297 ++N;
298 }
299 m_rms_5sec /= N;
300
301 std::cerr << m_rms_5sec << " ";
302 }
303
304 m_rms_10sec = 0;
305 if(m_rms.size() > 10.0*m_fps)
306 {
307 int N = 0;
308 for(size_t n=0; n < 10.0*m_fps; ++n)
309 {
310 m_rms_10sec += m_rms[n];
311 ++N;
312 }
313 m_rms_10sec /= N;
314
315 std::cerr << m_rms_10sec << " ";
316 }
317
318 std::cerr << "\n";
319
320 updateIfChanged(m_indiP_refrms, std::vector<std::string>({"one_sec","two_sec","five_sec","ten_sec"}), std::vector<double>({m_rms_1sec, m_rms_2sec, m_rms_5sec, m_rms_10sec}));
321
322 }
323 }
324
325
326 std::unique_lock<std::mutex> lock(m_indiMutex);
327
329 {
331 }
332
334 {
336 }
337
338 return 0;
339}
340
341inline
349
350
351inline
352int refRMS::allocate(const refShmimT & dummy)
353{
354 static_cast<void>(dummy); //be unused
355
356 std::unique_lock<std::mutex> lock(m_indiMutex);
357
359
360 std::cerr << "got ref: " << refShmimMonitorT::m_width << " " << refShmimMonitorT::m_height << "\n";
361
362 if(m_mask.rows() != m_currRef.rows() || m_mask.cols() != m_currRef.cols())
363 {
364 m_maskValid = false;
365 m_mask.resize(m_currRef.rows(), m_currRef.cols());
366 m_mask.setConstant(1);
367 }
368
369 while(m_fps == 0)
370 {
371 sleep(5);
372 /*if(m_fps == 0)
373 {
374 return log<text_log,-1>("fps not updated", logPrio::LOG_ERROR);
375 }*/
376 }
377
378 cbIndexT cbSz = 11 * m_fps;
379 m_mean.maxEntries(cbSz);
380 m_rms.maxEntries(cbSz);
381
382 std::cerr << "allocated\n";
383
384 return 0;
385}
386
387inline
388int refRMS::processImage( void * curr_src,
389 const refShmimT & dummy
390 )
391{
392 static_cast<void>(dummy); //be unused
393
394 //Copy it out first so we can afford to be slow and skipping frames
395 m_currRef = Eigen::Map<Eigen::Matrix<float,-1,-1>>((float *)curr_src, refShmimMonitorT::m_width, refShmimMonitorT::m_height);//,1);
396
397 //std::cerr << "pi\n";
398
399 //If mask has changed we skip
400 if(m_mask.rows() != m_currRef.rows() || m_mask.cols() != m_currRef.cols())
401 {
402 std::cerr << m_mask.rows() << " " << m_mask.cols() << "\n";
403 std::cerr << m_currRef.rows() << " " << m_currRef.cols() << "\n";
404
405 return 0;
406 }
407
408 //mult by mask, etc.
409 float mean = (m_currRef * m_mask).sum()/m_maskSum;
410 float rms = sqrt(((m_currRef - mean)*m_mask).square().sum()/m_maskSum);
411
412 m_mean.nextEntry(mean);
413 m_rms.nextEntry(rms);
414
415 return 0;
416}
417
418
419inline
420int refRMS::allocate(const maskShmimT & dummy)
421{
422 static_cast<void>(dummy); //be unused
423
424 std::unique_lock<std::mutex> lock(m_indiMutex);
425
426 std::cerr << "got mask: " << maskShmimMonitorT::m_width << " " << maskShmimMonitorT::m_height << "\n";
427
429
430 return 0;
431}
432
433inline
434int refRMS::processImage( void * curr_src,
435 const maskShmimT & dummy
436 )
437{
438 static_cast<void>(dummy); //be unused
439
440 //copy curr_src to mask
441 m_mask = Eigen::Map<Eigen::Matrix<float,-1,-1>>((float *)curr_src, maskShmimMonitorT::m_width,maskShmimMonitorT::m_height);
442
443 m_maskSum = m_mask.sum();
444
445 if(m_mask.rows() == m_currRef.rows() || m_mask.cols() == m_currRef.cols())
446 {
447 m_maskValid = true;
448 }
449
450 return 0;
451}
452
453INDI_SETCALLBACK_DEFN( refRMS, m_indiP_fpsSource )(const pcf::IndiProperty &ipRecv)
454{
455 if( ipRecv.getName() != m_indiP_fpsSource.getName())
456 {
457 log<software_error>({__FILE__, __LINE__, "Invalid INDI property."});
458 return -1;
459 }
460
461 if( ipRecv.find("current") != true ) //this isn't valie
462 {
463 return 0;
464 }
465
466 //std::lock<std::mutex> mut(m_indiMutex);
467
468 realT fps = ipRecv["current"].get<float>();
469 //mut.unlock();
470
471 if(fps != m_fps)
472 {
473 m_fps = fps;
474 std::cout << "Got fps: " << m_fps << "\n";
475 refShmimMonitorT::m_restart = true;
476 }
477
478 return 0;
479}
480
481} //namespace app
482} //namespace MagAOX
483
484#endif //refRMS_hpp
The base-class for MagAO-X applications.
Definition MagAOXApp.hpp:73
void updateIfChanged(pcf::IndiProperty &p, const std::string &el, const T &newVal, pcf::IndiProperty::PropertyStateType ipState=pcf::IndiProperty::Ok)
Update an INDI property element value if it has changed.
stateCodes::stateCodeT state()
Get the current state code.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
int createROIndiNumber(pcf::IndiProperty &prop, const std::string &propName, const std::string &propLabel="", const std::string &propGroup="")
Create a ReadOnly INDI Number property.
int registerIndiPropertyReadOnly(pcf::IndiProperty &prop)
Register an INDI property which is read only.
std::mutex m_indiMutex
Mutex for locking INDI communications.
uint32_t m_width
The width of the images in the stream.
int setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
int updateINDI()
Update the INDI properties for this device controller.
int appLogic()
Checks the shmimMonitor thread.
uint32_t m_height
The height of the images in the stream.
int appShutdown()
Shuts down the shmimMonitor thread.
int loadConfig(mx::app::appConfigurator &config)
load the configuration system results
bool m_getExistingFirst
If set to true by derivedT, any existing image will be grabbed and sent to processImage before waitin...
int processImage(void *curr_src, const refShmimT &dummy)
Definition refRMS.hpp:388
refRMS()
Default c'tor.
Definition refRMS.hpp:177
mx::sigproc::circularBufferIndex< float, cbIndexT > m_rms
Definition refRMS.hpp:104
dev::shmimMonitor< refRMS, maskShmimT > maskShmimMonitorT
Definition refRMS.hpp:82
virtual int appShutdown()
Shutdown the app.
Definition refRMS.hpp:342
friend class refRMS_test
Definition refRMS.hpp:73
std::string m_fpsSource
Device name for getting fps. This device should have *.fps.current.
Definition refRMS.hpp:95
~refRMS() noexcept
D'tor, declared and defined for noexcept.
Definition refRMS.hpp:120
int allocate(const refShmimT &dummy)
Definition refRMS.hpp:352
virtual int appStartup()
Startup function.
Definition refRMS.hpp:214
virtual int appLogic()
Implementation of the FSM for refRMS.
Definition refRMS.hpp:244
float realT
Floating point type in which to do all calculations.
Definition refRMS.hpp:85
mx::sigproc::circularBufferIndex< float, cbIndexT > m_mean
Definition refRMS.hpp:106
INDI_SETCALLBACK_DECL(refRMS, m_indiP_fpsSource)
mx::improc::eigenImage< realT > m_currRef
Definition refRMS.hpp:99
virtual void setupConfig()
Definition refRMS.hpp:187
uint16_t cbIndexT
Definition refRMS.hpp:87
virtual void loadConfig()
Definition refRMS.hpp:208
float m_fps
Current FPS from the FPS source.
Definition refRMS.hpp:113
mx::improc::eigenImage< realT > m_mask
Definition refRMS.hpp:100
pcf::IndiProperty m_indiP_refrms
Definition refRMS.hpp:168
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
Definition refRMS.hpp:196
dev::shmimMonitor< refRMS, refShmimT > refShmimMonitorT
Definition refRMS.hpp:81
pcf::IndiProperty m_indiP_fpsSource
Definition refRMS.hpp:170
#define INDI_SETCALLBACK_DEFN(class, prop)
Define the callback for a set property request.
#define REG_INDI_SETPROP(prop, devName, propName)
Register a SET INDI property with the class, using the standard callback name.
@ OPERATING
The device is operating, other than homing.
int addNumberElement(pcf::IndiProperty &prop, const std::string &name, const T &min, const T &max, const T &step, const std::string &format, const std::string &label="")
Add a standard INDI Number element.
Definition indiUtils.hpp:63
const pcf::IndiProperty & ipRecv
std::unique_lock< std::mutex > lock(m_indiMutex)
Definition dm.hpp:24
static std::string indiPrefix()
Definition refRMS.hpp:44
static std::string configSection()
Definition refRMS.hpp:39
static std::string indiPrefix()
Definition refRMS.hpp:30
static std::string configSection()
Definition refRMS.hpp:25
Software ERR log entry.