Line data Source code
1 : /** \file pupilFit.hpp
2 : * \brief The MagAO-X Pyramid Pupil Fitter application header
3 : *
4 : * \ingroup pupilFit_files
5 : */
6 :
7 : #ifndef pupilFit_hpp
8 : #define pupilFit_hpp
9 :
10 : #include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
11 : #include "../../magaox_git_version.h"
12 :
13 : #include "pupilFitter.hpp"
14 :
15 : /** \defgroup pupilFit
16 : * \brief The MagAO-X pyramid pupil fitter.
17 : *
18 : * <a href="../handbook/operating/software/apps/pupilFit.html">Application Documentation</a>
19 : *
20 : * \ingroup apps
21 : *
22 : */
23 :
24 : /** \defgroup pupilFit_files
25 : * \ingroup pupilFit
26 : */
27 :
28 : namespace MagAOX
29 : {
30 : namespace app
31 : {
32 :
33 : struct refShmimT
34 : {
35 0 : static std::string configSection()
36 : {
37 0 : return "refShmim";
38 : };
39 :
40 0 : static std::string indiPrefix()
41 : {
42 0 : return "ref";
43 : };
44 : };
45 :
46 : #define USEDEFSET (0)
47 : #define USEREFIM (1)
48 : #define USEUSERSET (2)
49 :
50 : /// The MagAO-X Pyramid Pupil Fitter
51 : /**
52 : * \ingroup pupilFit
53 : */
54 : class pupilFit : public MagAOXApp<true>, public dev::shmimMonitor<pupilFit>, public dev::shmimMonitor<pupilFit,refShmimT>, public dev::frameGrabber<pupilFit>, public dev::telemeter<pupilFit>
55 : {
56 : //Give the test harness access.
57 : friend class pupilFit_test;
58 :
59 : friend class dev::shmimMonitor<pupilFit>;
60 : friend class dev::shmimMonitor<pupilFit,refShmimT>;
61 : friend class dev::frameGrabber<pupilFit>;
62 :
63 : friend class dev::telemeter<pupilFit>;
64 :
65 : public:
66 : //The base shmimMonitor type
67 : typedef dev::shmimMonitor<pupilFit> shmimMonitorT;
68 :
69 : typedef dev::shmimMonitor<pupilFit,refShmimT> refShmimMonitorT;
70 :
71 : //The base frameGrabber type
72 : typedef dev::frameGrabber<pupilFit> frameGrabberT;
73 :
74 : //The base telemeter type
75 : typedef dev::telemeter<pupilFit> telemeterT;
76 :
77 : ///Floating point type in which to do all calculations.
78 : typedef float realT;
79 :
80 : /** \name app::dev Configurations
81 : *@{
82 : */
83 :
84 : static constexpr bool c_frameGrabber_flippable = false; ///< app:dev config to tell framegrabber these images can not be flipped
85 :
86 : ///@}
87 :
88 : protected:
89 :
90 : /** \name Configurable Parameters
91 : *@{
92 : */
93 :
94 : std::string m_threshShmimName {"camwfs_thresh"}; ///<The name of the image stream for the thresholded images. Default is camwfs_thresh.
95 : std::string m_edgeShmimName {"camwfs_edge"}; ///<The name of the image stream for the edge images. Default is camwfs_edge.
96 :
97 : float m_threshold {0.5};
98 :
99 : int m_numPupils {4}; ///< The number of pupils. Default is 4. 3 is also supported.
100 : ///@}
101 :
102 : mx::improc::eigenImage<float> m_refIm;
103 : mx::improc::eigenImage<float> m_fitIm;
104 : mx::improc::eigenImage<float> m_edgeIm;
105 :
106 : pupilFitter<realT> m_fitter;
107 :
108 : IMAGE m_threshShmim;
109 : bool m_threshShmimConnected {false};
110 :
111 : IMAGE m_edgeShmim;
112 : bool m_edgeShmimConnected {false};
113 :
114 : float m_defSetx1 {29.5};
115 : float m_defSety1 {29.5};
116 : float m_defSetD1 {56.0};
117 :
118 : float m_defSetx2 {89.5};
119 : float m_defSety2 {29.5};
120 : float m_defSetD2 {56.0};
121 :
122 : float m_defSetx3 {29.5};
123 : float m_defSety3 {89.5};
124 : float m_defSetD3 {56.0};
125 :
126 : float m_defSetx4 {89.5};
127 : float m_defSety4 {89.5};
128 : float m_defSetD4 {56.0};
129 :
130 : float m_userSetx1 {29.5};
131 : float m_userSety1 {29.5};
132 : float m_userSetD1 {56.0};
133 :
134 : float m_userSetx2 {89.5};
135 : float m_userSety2 {29.5};
136 : float m_userSetD2 {56.0};
137 :
138 : float m_userSetx3 {29.5};
139 : float m_userSety3 {89.5};
140 : float m_userSetD3 {56.0};
141 :
142 : float m_userSetx4 {89.5};
143 : float m_userSety4 {89.5};
144 : float m_userSetD4 {56.0};
145 :
146 : int m_setPointSource {USEDEFSET};
147 :
148 : bool m_refUpdated {false}; ///< Flag set if the online reference update is used.
149 :
150 : float m_setx1 {29.5};
151 : float m_sety1 {29.5};
152 : float m_setD1 {56.0};
153 :
154 : float m_setx2 {89.5};
155 : float m_sety2 {29.5};
156 : float m_setD2 {56.0};
157 :
158 : float m_setx3 {29.5};
159 : float m_sety3 {89.5};
160 : float m_setD3 {56.0};
161 :
162 : float m_setx4 {89.5};
163 : float m_sety4 {89.5};
164 : float m_setD4 {56.0};
165 :
166 : float m_avg_dx {0};
167 : float m_avg_dy {0};
168 :
169 : bool m_averaging {false};
170 : size_t m_navg {0};
171 :
172 : float m_avgx1_accum {0};
173 : float m_avgx1sq_accum {0};
174 :
175 : float m_avgy1_accum {0};
176 : float m_avgy1sq_accum {0};
177 :
178 : float m_avgD1_accum {0};
179 : float m_avgD1sq_accum {0};
180 :
181 : float m_avgmed1_accum {0};
182 : float m_avgmed1sq_accum {0};
183 :
184 : float m_avgx1 {0};
185 : float m_varx1 {0};
186 :
187 : float m_avgy1 {0};
188 : float m_vary1 {0};
189 :
190 : float m_avgD1 {0};
191 : float m_varD1 {0};
192 :
193 : float m_avgmed1 {0};
194 : float m_varmed1 {0};
195 :
196 : float m_avgx2_accum {0};
197 : float m_avgx2sq_accum {0};
198 :
199 : float m_avgy2_accum {0};
200 : float m_avgy2sq_accum {0};
201 :
202 : float m_avgD2_accum {0};
203 : float m_avgD2sq_accum {0};
204 :
205 : float m_avgmed2_accum {0};
206 : float m_avgmed2sq_accum {0};
207 :
208 : float m_avgx2 {0};
209 : float m_varx2 {0};
210 :
211 : float m_avgy2 {0};
212 : float m_vary2 {0};
213 :
214 : float m_avgD2 {0};
215 : float m_varD2 {0};
216 :
217 : float m_avgmed2 {0};
218 : float m_varmed2 {0};
219 :
220 : float m_avgx3_accum {0};
221 : float m_avgx3sq_accum {0};
222 :
223 : float m_avgy3_accum {0};
224 : float m_avgy3sq_accum {0};
225 :
226 : float m_avgD3_accum {0};
227 : float m_avgD3sq_accum {0};
228 :
229 : float m_avgmed3_accum {0};
230 : float m_avgmed3sq_accum {0};
231 :
232 : float m_avgx3 {0};
233 : float m_varx3 {0};
234 :
235 : float m_avgy3 {0};
236 : float m_vary3 {0};
237 :
238 : float m_avgD3 {0};
239 : float m_varD3 {0};
240 :
241 : float m_avgmed3 {0};
242 : float m_varmed3 {0};
243 :
244 : float m_avgx4_accum {0};
245 : float m_avgx4sq_accum {0};
246 :
247 : float m_avgy4_accum {0};
248 : float m_avgy4sq_accum {0};
249 :
250 : float m_avgD4_accum {0};
251 : float m_avgD4sq_accum {0};
252 :
253 : float m_avgmed4_accum {0};
254 : float m_avgmed4sq_accum {0};
255 :
256 : float m_avgx4 {0};
257 : float m_varx4 {0};
258 :
259 : float m_avgy4 {0};
260 : float m_vary4 {0};
261 :
262 : float m_avgD4 {0};
263 : float m_varD4 {0};
264 :
265 : float m_avgmed4 {0};
266 : float m_varmed4 {0};
267 :
268 : float m_avgxAll_accum {0};
269 : float m_avgxAllsq_accum {0};
270 :
271 : float m_avgyAll_accum {0};
272 : float m_avgyAllsq_accum {0};
273 :
274 : float m_avgDAll_accum {0};
275 : float m_avgDAllsq_accum {0};
276 :
277 : float m_avgmedAll_accum {0};
278 : float m_avgmedAllsq_accum {0};
279 :
280 : float m_avgxAll {0};
281 : float m_varxAll {0};
282 :
283 : float m_avgyAll {0};
284 : float m_varyAll {0};
285 :
286 : float m_avgDAll {0};
287 : float m_varDAll {0};
288 :
289 : float m_avgmedAll {0};
290 : float m_varmedAll {0};
291 :
292 : public:
293 : /// Default c'tor.
294 : pupilFit();
295 :
296 : /// D'tor, declared and defined for noexcept.
297 : ~pupilFit() noexcept;
298 :
299 : virtual void setupConfig();
300 :
301 : /// Implementation of loadConfig logic, separated for testing.
302 : /** This is called by loadConfig().
303 : */
304 : int loadConfigImpl( mx::app::appConfigurator & _config /**< [in] an application configuration from which to load values*/);
305 :
306 : virtual void loadConfig();
307 :
308 : /// Startup function
309 : /**
310 : *
311 : */
312 : virtual int appStartup();
313 :
314 : /// Implementation of the FSM for pupilFit.
315 : /**
316 : * \returns 0 on no critical error
317 : * \returns -1 on an error requiring shutdown
318 : */
319 : virtual int appLogic();
320 :
321 : /// Shutdown the app.
322 : /**
323 : *
324 : */
325 : virtual int appShutdown();
326 :
327 : // shmimMonitor interface:
328 : int allocate( const dev::shmimT &);
329 :
330 : int processImage( void* curr_src,
331 : const dev::shmimT &
332 : );
333 :
334 : // shmimMonitor interface for referenc:
335 : int allocate( const refShmimT &);
336 :
337 : int processImage( void* curr_src,
338 : const refShmimT &
339 : );
340 :
341 : protected:
342 :
343 : bool m_updated {false}; //tells the f.g. that there is an actual image, not just a sem timeout
344 :
345 : sem_t m_smSemaphore {0}; ///< Semaphore used to synchronize the fg thread and the sm thread.
346 :
347 : public:
348 :
349 : /** \name dev::frameGrabber interface
350 : *
351 : * @{
352 : */
353 :
354 : /// Implementation of the framegrabber configureAcquisition interface
355 : /**
356 : * \returns 0 on success
357 : * \returns -1 on error
358 : */
359 : int configureAcquisition();
360 :
361 : /// Implementation of the framegrabber fps interface
362 : /**
363 : * \todo this needs to infer the stream fps and return it
364 : */
365 0 : float fps()
366 : {
367 0 : return 1.0;
368 : }
369 :
370 : /// Implementation of the framegrabber startAcquisition interface
371 : /**
372 : * \returns 0 on success
373 : * \returns -1 on error
374 : */
375 : int startAcquisition();
376 :
377 : /// Implementation of the framegrabber acquireAndCheckValid interface
378 : /**
379 : * \returns 0 on success
380 : * \returns -1 on error
381 : */
382 : int acquireAndCheckValid();
383 :
384 : /// Implementation of the framegrabber loadImageIntoStream interface
385 : /**
386 : * \returns 0 on success
387 : * \returns -1 on error
388 : */
389 : int loadImageIntoStream( void * dest /**< [in] */);
390 :
391 : /// Implementation of the framegrabber reconfig interface
392 : /**
393 : * \returns 0 on success
394 : * \returns -1 on error
395 : */
396 : int reconfig();
397 :
398 : ///@}
399 :
400 : protected:
401 :
402 : /** \name INDI
403 : * @{
404 : */
405 :
406 : pcf::IndiProperty m_indiP_thresh;
407 :
408 0 : INDI_NEWCALLBACK_DECL(pupilFit, m_indiP_thresh);
409 :
410 : pcf::IndiProperty m_indiP_averaging;
411 0 : INDI_NEWCALLBACK_DECL(pupilFit, m_indiP_averaging);
412 :
413 : pcf::IndiProperty m_indiP_numPupils;
414 :
415 : pcf::IndiProperty m_indiP_quad1;
416 : pcf::IndiProperty m_indiP_quad2;
417 : pcf::IndiProperty m_indiP_quad3;
418 : pcf::IndiProperty m_indiP_quad4;
419 :
420 : pcf::IndiProperty m_indiP_avg;
421 :
422 : pcf::IndiProperty m_indiP_reload;
423 0 : INDI_NEWCALLBACK_DECL(pupilFit, m_indiP_reload);
424 :
425 : pcf::IndiProperty m_indiP_update;
426 0 : INDI_NEWCALLBACK_DECL(pupilFit, m_indiP_update);
427 :
428 : pcf::IndiProperty m_indiP_refmode;
429 0 : INDI_NEWCALLBACK_DECL(pupilFit, m_indiP_refmode);
430 :
431 : ///@}
432 :
433 : /** \name Telemeter Interface
434 : *
435 : * @{
436 : */
437 : int checkRecordTimes();
438 :
439 : int recordTelem( const telem_fgtimings * );
440 :
441 : ///@}
442 : };
443 :
444 : inline
445 : pupilFit::pupilFit() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
446 : {
447 : refShmimMonitorT::m_getExistingFirst = true;
448 : return;
449 : }
450 :
451 : inline
452 0 : pupilFit::~pupilFit() noexcept
453 : {
454 0 : if(m_threshShmimConnected)
455 : {
456 0 : ImageStreamIO_destroyIm( &m_threshShmim );
457 : }
458 :
459 0 : if(m_edgeShmimConnected)
460 : {
461 0 : ImageStreamIO_destroyIm( &m_edgeShmim );
462 : }
463 0 : }
464 :
465 : inline
466 0 : void pupilFit::setupConfig()
467 : {
468 0 : shmimMonitorT::setupConfig(config);
469 0 : refShmimMonitorT::setupConfig(config);
470 0 : frameGrabberT::setupConfig(config);
471 0 : telemeterT::setupConfig(config);
472 :
473 0 : config.add("shmimMonitor.shmimName", "", "shmimMonitor.shmimName", argType::Required, "shmimMonitor", "shmimName", false, "string", "The name of the ImageStreamIO shared memory image. Will be used as /tmp/<shmimName>.im.shm. Default is camwfs_avg");
474 :
475 0 : config.add("fit.threshold", "", "fit.threshold", argType::Required, "fit", "threshold", false, "float", "The pupil finding threshold. 0 < threshold < 1");
476 0 : config.add("fit.threshShmimName", "", "fit.threshShmimName", argType::Required, "fit", "threshShmimName", false, "float", "The name of the image stream for the thresholded images. Default is camwfs_thresh.");
477 0 : config.add("fit.edgeShmimName", "", "fit.edgeShmimName", argType::Required, "fit", "edgeShmimName", false, "float", "The name of the image stream for the edge images. Default is camwfs_edge.");
478 :
479 0 : config.add("fit.numPupils", "", "fit.numPupils", argType::Required, "fit", "numPupils", false, "int", "The number of pupils. Default is 4. 3 is also supported.");
480 0 : config.add("fit.pupMedIndex", "", "fit.pupMedIndex", argType::Required, "fit", "pupMedIndex", false, "float", "The index of the pupil median in a sorted quadrant.");
481 :
482 0 : config.add("cal.setx1", "", "cal.setx1", argType::Required, "cal", "setx1", false, "float", "The x set point for quad 1 (LL).");
483 0 : config.add("cal.sety1", "", "cal.sety1", argType::Required, "cal", "sety1", false, "float", "The y set point for quad 1 (LL).");
484 0 : config.add("cal.setD1", "", "cal.setD1", argType::Required, "cal", "setD1", false, "float", "The D set point for quad 1 (LL).");
485 :
486 0 : config.add("cal.setx2", "", "cal.setx2", argType::Required, "cal", "setx2", false, "float", "The x set point for quad 2 (LL).");
487 0 : config.add("cal.sety2", "", "cal.sety2", argType::Required, "cal", "sety2", false, "float", "The y set point for quad 2 (LL).");
488 0 : config.add("cal.setD2", "", "cal.setD2", argType::Required, "cal", "setD2", false, "float", "The D set point for quad 2 (LL).");
489 :
490 0 : config.add("cal.setx3", "", "cal.setx3", argType::Required, "cal", "setx3", false, "float", "The x set point for quad 3 (LL).");
491 0 : config.add("cal.sety3", "", "cal.sety3", argType::Required, "cal", "sety3", false, "float", "The y set point for quad 3 (LL).");
492 0 : config.add("cal.setD3", "", "cal.setD3", argType::Required, "cal", "setD3", false, "float", "The D set point for quad 3 (LL).");
493 :
494 0 : config.add("cal.setx4", "", "cal.setx4", argType::Required, "cal", "setx4", false, "float", "The x set point for quad 4 (LL).");
495 0 : config.add("cal.sety4", "", "cal.sety4", argType::Required, "cal", "sety4", false, "float", "The y set point for quad 4 (LL).");
496 0 : config.add("cal.setD4", "", "cal.setD4", argType::Required, "cal", "setD4", false, "float", "The D set point for quad 4 (LL).");
497 0 : }
498 :
499 :
500 : inline
501 0 : int pupilFit::loadConfigImpl( mx::app::appConfigurator & _config )
502 : {
503 0 : shmimMonitorT::m_shmimName = "camwfs_avg";
504 0 : shmimMonitorT::loadConfig(_config);
505 0 : refShmimMonitorT::loadConfig(_config);
506 0 : if(refShmimMonitorT::m_shmimName != "") m_setPointSource = USEREFIM;
507 :
508 0 : frameGrabberT::loadConfig(_config);
509 0 : telemeterT::loadConfig(_config);
510 :
511 0 : _config(m_threshold, "fit.threshold");
512 0 : _config(m_threshShmimName, "fit.threshShmimName");
513 0 : _config(m_edgeShmimName, "fit.edgeShmimName");
514 0 : _config(m_numPupils, "fit.numPupils");
515 0 : _config(m_fitter.m_pupMedIndex, "fit.pupMedIndex");
516 :
517 0 : _config(m_defSetx1, "cal.setx1");
518 0 : _config(m_defSety1, "cal.sety1");
519 0 : _config(m_defSetD1, "cal.setD1");
520 :
521 0 : _config(m_defSetx2, "cal.setx2");
522 0 : _config(m_defSety2, "cal.sety2");
523 0 : _config(m_defSetD2, "cal.setD2");
524 :
525 0 : _config(m_defSetx3, "cal.setx3");
526 0 : _config(m_defSety3, "cal.sety3");
527 0 : _config(m_defSetD3, "cal.setD3");
528 :
529 0 : _config(m_defSetx4, "cal.setx4");
530 0 : _config(m_defSety4, "cal.sety4");
531 0 : _config(m_defSetD4, "cal.setD4");
532 :
533 :
534 0 : return 0;
535 : }
536 :
537 : inline
538 0 : void pupilFit::loadConfig()
539 : {
540 0 : loadConfigImpl(config);
541 0 : }
542 :
543 : inline
544 0 : int pupilFit::appStartup()
545 : {
546 0 : if(shmimMonitorT::appStartup() < 0)
547 : {
548 0 : return log<software_error,-1>({__FILE__, __LINE__});
549 : }
550 :
551 0 : if(refShmimMonitorT::appStartup() < 0)
552 : {
553 0 : return log<software_error,-1>({__FILE__, __LINE__});
554 : }
555 :
556 0 : if(sem_init(&m_smSemaphore, 0,0) < 0)
557 : {
558 0 : log<software_critical>({__FILE__, __LINE__, errno,0, "Initializing S.M. semaphore"});
559 0 : return -1;
560 : }
561 :
562 0 : if(frameGrabberT::appStartup() < 0)
563 : {
564 0 : return log<software_error,-1>({__FILE__, __LINE__});
565 : }
566 :
567 0 : if(telemeterT::appStartup() < 0)
568 : {
569 0 : return log<software_error,-1>({__FILE__, __LINE__});
570 : }
571 :
572 0 : createStandardIndiNumber<float>( m_indiP_thresh, "threshold", 0, 1 ,0, "%0.2f", "Threshold");
573 0 : m_indiP_thresh["current"].set(m_threshold);
574 0 : m_indiP_thresh["target"].set(m_threshold);
575 0 : registerIndiPropertyNew(m_indiP_thresh, INDI_NEWCALLBACK(m_indiP_thresh));
576 :
577 0 : createStandardIndiToggleSw( m_indiP_averaging, "averaging", "Start/Stop Averaging");
578 0 : m_indiP_averaging["toggle"].set(pcf::IndiElement::Off);
579 0 : if( registerIndiPropertyNew( m_indiP_averaging, INDI_NEWCALLBACK(m_indiP_averaging)) < 0)
580 : {
581 0 : log<software_error>({__FILE__,__LINE__});
582 0 : return -1;
583 : }
584 :
585 0 : createROIndiNumber( m_indiP_numPupils, "numPupils", "Number of Pupils");
586 0 : indi::addNumberElement<int>( m_indiP_numPupils, "value", 3, 4, 1, "%d", "");
587 0 : m_indiP_numPupils["value"].set(m_numPupils);
588 0 : registerIndiPropertyReadOnly(m_indiP_numPupils);
589 :
590 0 : createROIndiNumber( m_indiP_quad1, "quadrant1", "Quadrant 1");
591 0 : indi::addNumberElement<float>( m_indiP_quad1, "x", 0, 59, 0, "%0.2f", "center x");
592 0 : indi::addNumberElement<float>( m_indiP_quad1, "dx", 0, 59, 0, "%0.2f", "delta-x");
593 0 : indi::addNumberElement<float>( m_indiP_quad1, "y", 0, 59, 0, "%0.2f", "center x");
594 0 : indi::addNumberElement<float>( m_indiP_quad1, "dy", 0, 59, 0, "%0.2f", "delta-y");
595 0 : indi::addNumberElement<float>( m_indiP_quad1, "D", 0, 59, 0, "%0.2f", "diameter");
596 0 : indi::addNumberElement<float>( m_indiP_quad1, "dD", 0, 59, 0, "%0.2f", "delta-D");
597 0 : indi::addNumberElement<float>( m_indiP_quad1, "med", 0, std::numeric_limits<uint16_t>::max(), 0, "%0.1f", "flux");
598 0 : indi::addNumberElement<float>( m_indiP_quad1, "bg", 0, std::numeric_limits<uint16_t>::max(), 0, "%0.1f", "background");
599 0 : indi::addNumberElement<float>( m_indiP_quad1, "set-x", 0, 59, 0, "%0.2f", "set pt. center x");
600 0 : m_indiP_quad1["set-x"] = m_setx1;
601 0 : indi::addNumberElement<float>( m_indiP_quad1, "set-y", 0, 59, 0, "%0.2f", "set pt. center x");
602 0 : m_indiP_quad1["set-y"] = m_sety1;
603 0 : indi::addNumberElement<float>( m_indiP_quad1, "set-D", 0, 59, 0, "%0.2f", "set pt. diameter");
604 0 : m_indiP_quad1["set-D"] = m_setD1;
605 :
606 0 : registerIndiPropertyReadOnly(m_indiP_quad1);
607 :
608 0 : createROIndiNumber( m_indiP_quad2, "quadrant2", "Quadrant 2");
609 0 : indi::addNumberElement<float>( m_indiP_quad2, "x", 0, 59, 0, "%0.2f", "center x");
610 0 : indi::addNumberElement<float>( m_indiP_quad2, "dx", 0, 59, 0, "%0.2f", "delta-x");
611 0 : indi::addNumberElement<float>( m_indiP_quad2, "y", 0, 59, 0, "%0.2f", "center y");
612 0 : indi::addNumberElement<float>( m_indiP_quad2, "dy", 0, 59, 0, "%0.2f", "delta-y");
613 0 : indi::addNumberElement<float>( m_indiP_quad2, "D", 0, 59, 0, "%0.2f", "diameter");
614 0 : indi::addNumberElement<float>( m_indiP_quad2, "dD", 0, 59, 0, "%0.2f", "delta-D");
615 0 : indi::addNumberElement<float>( m_indiP_quad2, "med", 0, std::numeric_limits<uint16_t>::max(), 0, "%0.1f", "flux");
616 0 : indi::addNumberElement<float>( m_indiP_quad2, "bg", 0, std::numeric_limits<uint16_t>::max(), 0, "%0.1f", "background");
617 0 : indi::addNumberElement<float>( m_indiP_quad2, "set-x", 0, 59, 0, "%0.2f", "set pt. center x");
618 0 : m_indiP_quad2["set-x"] = m_setx2;
619 0 : indi::addNumberElement<float>( m_indiP_quad2, "set-y", 0, 59, 0, "%0.2f", "set pt. center x");
620 0 : m_indiP_quad2["set-y"] = m_sety2;
621 0 : indi::addNumberElement<float>( m_indiP_quad2, "set-D", 0, 59, 0, "%0.2f", "set pt. diameter");
622 0 : m_indiP_quad2["set-D"] = m_setD2;
623 0 : registerIndiPropertyReadOnly(m_indiP_quad2);
624 :
625 0 : createROIndiNumber( m_indiP_quad3, "quadrant3", "Quadrant 3");
626 0 : indi::addNumberElement<float>( m_indiP_quad3, "x", 0, 59, 0, "%0.2f", "center x");
627 0 : indi::addNumberElement<float>( m_indiP_quad3, "dx", 0, 59, 0, "%0.2f", "delta-x");
628 0 : indi::addNumberElement<float>( m_indiP_quad3, "y", 0, 59, 0, "%0.2f", "center y");
629 0 : indi::addNumberElement<float>( m_indiP_quad3, "dy", 0, 59, 0, "%0.2f", "delta-y");
630 0 : indi::addNumberElement<float>( m_indiP_quad3, "D", 0, 59, 0, "%0.2f", "diameter");
631 0 : indi::addNumberElement<float>( m_indiP_quad3, "dD", 0, 59, 0, "%0.2f", "delta-D");
632 0 : indi::addNumberElement<float>( m_indiP_quad3, "med", 0, std::numeric_limits<uint16_t>::max(), 0, "%0.1f", "flux");
633 0 : indi::addNumberElement<float>( m_indiP_quad3, "bg", 0, std::numeric_limits<uint16_t>::max(), 0, "%0.1f", "background");
634 0 : indi::addNumberElement<float>( m_indiP_quad3, "set-x", 0, 59, 0, "%0.2f", "set pt. center x");
635 0 : m_indiP_quad3["set-x"] = m_setx3;
636 0 : indi::addNumberElement<float>( m_indiP_quad3, "set-y", 0, 59, 0, "%0.2f", "set pt. center x");
637 0 : m_indiP_quad3["set-y"] = m_sety3;
638 0 : indi::addNumberElement<float>( m_indiP_quad3, "set-D", 0, 59, 0, "%0.2f", "set pt. diameter");
639 0 : m_indiP_quad3["set-D"] = m_setD3;
640 0 : registerIndiPropertyReadOnly(m_indiP_quad3);
641 :
642 0 : if(m_numPupils != 3)
643 : {
644 0 : createROIndiNumber( m_indiP_quad4, "quadrant4", "Quadrant 4");
645 0 : indi::addNumberElement<float>( m_indiP_quad4, "x", 0, 59, 0, "%0.2f", "center x");
646 0 : indi::addNumberElement<float>( m_indiP_quad4, "dx", 0, 59, 0, "%0.2f", "delta-x");
647 0 : indi::addNumberElement<float>( m_indiP_quad4, "y", 0, 59, 0, "%0.2f", "center y");
648 0 : indi::addNumberElement<float>( m_indiP_quad4, "dy", 0, 59, 0, "%0.2f", "delta-y");
649 0 : indi::addNumberElement<float>( m_indiP_quad4, "D", 0, 59, 0, "%0.2f", "diameter");
650 0 : indi::addNumberElement<float>( m_indiP_quad4, "dD", 0, 59, 0, "%0.2f", "delta-D");
651 0 : indi::addNumberElement<float>( m_indiP_quad4, "med", 0, std::numeric_limits<uint16_t>::max(), 0, "%0.1f", "flux");
652 0 : indi::addNumberElement<float>( m_indiP_quad4, "bg", 0, std::numeric_limits<uint16_t>::max(), 0, "%0.1f", "background");
653 0 : indi::addNumberElement<float>( m_indiP_quad4, "set-x", 0, 59, 0, "%0.2f", "set pt. center x");
654 0 : m_indiP_quad4["set-x"] = m_setx4;
655 0 : indi::addNumberElement<float>( m_indiP_quad4, "set-y", 0, 59, 0, "%0.2f", "set pt. center x");
656 0 : m_indiP_quad4["set-y"] = m_sety4;
657 0 : indi::addNumberElement<float>( m_indiP_quad4, "set-D", 0, 59, 0, "%0.2f", "set pt. diameter");
658 0 : m_indiP_quad4["set-D"] = m_setD4;
659 0 : registerIndiPropertyReadOnly(m_indiP_quad4);
660 : }
661 :
662 0 : createROIndiNumber( m_indiP_avg, "average", "Average");
663 0 : indi::addNumberElement<float>( m_indiP_avg, "x", 0, 59, 0, "%0.2f", "center x");
664 0 : indi::addNumberElement<float>( m_indiP_avg, "dx", 0, 59, 0, "%0.2f", "delta-x");
665 0 : indi::addNumberElement<float>( m_indiP_avg, "y", 0, 59, 0, "%0.2f", "center y");
666 0 : indi::addNumberElement<float>( m_indiP_avg, "dy", 0, 59, 0, "%0.2f", "delta-y");
667 0 : indi::addNumberElement<float>( m_indiP_avg, "D", 0, 59, 0, "%0.2f", "diameter");
668 0 : indi::addNumberElement<float>( m_indiP_avg, "dD", 0, 59, 0, "%0.2f", "delta-D");
669 0 : registerIndiPropertyReadOnly(m_indiP_avg);
670 :
671 0 : createStandardIndiRequestSw( m_indiP_reload, "setpt_reload", "Reload Calibration");
672 0 : m_indiP_reload["request"].set(pcf::IndiElement::Off);
673 0 : if( registerIndiPropertyNew( m_indiP_reload, INDI_NEWCALLBACK(m_indiP_reload)) < 0)
674 : {
675 0 : log<software_error>({__FILE__,__LINE__});
676 0 : return -1;
677 : }
678 :
679 0 : createStandardIndiRequestSw( m_indiP_update, "setpt_current", "Set Reference");
680 0 : m_indiP_update["request"].set(pcf::IndiElement::Off);
681 0 : if( registerIndiPropertyNew( m_indiP_update, INDI_NEWCALLBACK(m_indiP_update)) < 0)
682 : {
683 0 : log<software_error>({__FILE__,__LINE__});
684 0 : return -1;
685 : }
686 :
687 0 : createStandardIndiSelectionSw( m_indiP_refmode, "setpt_mode", {"default", "refim", "user"}, "Reference Mode");
688 0 : if(m_setPointSource == USEREFIM)
689 : {
690 0 : m_indiP_refmode["default"].set(pcf::IndiElement::Off);
691 0 : m_indiP_refmode["refim"].set(pcf::IndiElement::On);
692 0 : m_indiP_refmode["user"].set(pcf::IndiElement::Off);
693 : }
694 0 : if(m_setPointSource == USEUSERSET)
695 : {
696 0 : m_indiP_refmode["default"].set(pcf::IndiElement::Off);
697 0 : m_indiP_refmode["refim"].set(pcf::IndiElement::Off);
698 0 : m_indiP_refmode["user"].set(pcf::IndiElement::On);
699 : }
700 : else
701 : {
702 0 : m_indiP_refmode["default"].set(pcf::IndiElement::On);
703 0 : m_indiP_refmode["refim"].set(pcf::IndiElement::Off);
704 0 : m_indiP_refmode["user"].set(pcf::IndiElement::Off);
705 : }
706 :
707 0 : if( registerIndiPropertyNew( m_indiP_refmode, INDI_NEWCALLBACK(m_indiP_refmode)) < 0)
708 : {
709 0 : log<software_error>({__FILE__,__LINE__});
710 0 : return -1;
711 : }
712 :
713 0 : state(stateCodes::OPERATING);
714 :
715 0 : return 0;
716 : }
717 :
718 : inline
719 0 : int pupilFit::appLogic()
720 : {
721 0 : if( shmimMonitorT::appLogic() < 0)
722 : {
723 0 : return log<software_error,-1>({__FILE__,__LINE__});
724 : }
725 :
726 0 : if( refShmimMonitorT::appLogic() < 0)
727 : {
728 0 : return log<software_error,-1>({__FILE__,__LINE__});
729 : }
730 :
731 0 : if( frameGrabberT::appLogic() < 0)
732 : {
733 0 : return log<software_error,-1>({__FILE__,__LINE__});
734 : }
735 :
736 0 : if( telemeterT::appLogic() < 0)
737 : {
738 0 : return log<software_error,-1>({__FILE__,__LINE__});
739 : }
740 :
741 0 : std::lock_guard<std::mutex> guard(m_indiMutex);
742 0 : updateIfChanged(m_indiP_thresh, "current", m_threshold, INDI_IDLE);
743 0 : updateIfChanged(m_indiP_thresh, "target", m_threshold, INDI_IDLE);
744 :
745 0 : if(m_setPointSource == USEREFIM)
746 : {
747 0 : updateSwitchIfChanged(m_indiP_refmode, "default", pcf::IndiElement::Off);
748 0 : updateSwitchIfChanged(m_indiP_refmode, "refim", pcf::IndiElement::On);
749 0 : updateSwitchIfChanged(m_indiP_refmode, "user", pcf::IndiElement::Off);
750 : }
751 0 : else if(m_setPointSource == USEUSERSET)
752 : {
753 0 : updateSwitchIfChanged(m_indiP_refmode, "default", pcf::IndiElement::Off);
754 0 : updateSwitchIfChanged(m_indiP_refmode, "refim", pcf::IndiElement::Off);
755 0 : updateSwitchIfChanged(m_indiP_refmode, "user", pcf::IndiElement::On);
756 : }
757 : else
758 : {
759 0 : updateSwitchIfChanged(m_indiP_refmode, "default", pcf::IndiElement::On);
760 0 : updateSwitchIfChanged(m_indiP_refmode, "refim", pcf::IndiElement::Off);
761 0 : updateSwitchIfChanged(m_indiP_refmode, "user", pcf::IndiElement::Off);
762 : }
763 :
764 0 : shmimMonitorT::updateINDI();
765 0 : refShmimMonitorT::updateINDI();
766 :
767 0 : if(frameGrabberT::updateINDI() < 0)
768 : {
769 0 : log<software_error>({__FILE__, __LINE__});
770 : }
771 :
772 0 : return 0;
773 0 : }
774 :
775 : inline
776 0 : int pupilFit::appShutdown()
777 : {
778 0 : shmimMonitorT::appShutdown();
779 0 : refShmimMonitorT::appShutdown();
780 0 : frameGrabberT::appShutdown();
781 0 : telemeterT::appShutdown();
782 :
783 0 : return 0;
784 : }
785 :
786 : inline
787 0 : int pupilFit::allocate(const dev::shmimT & dummy)
788 : {
789 : static_cast<void>(dummy);
790 :
791 0 : std::lock_guard<std::mutex> guard(m_indiMutex);
792 :
793 0 : m_fitIm.resize(shmimMonitorT::m_width, shmimMonitorT::m_height);
794 0 : m_edgeIm.resize(shmimMonitorT::m_width, shmimMonitorT::m_height);
795 :
796 0 : m_fitter.m_numPupils = m_numPupils;
797 0 : m_fitter.setSize(0.5*shmimMonitorT::m_width, 0.5*shmimMonitorT::m_height);
798 0 : m_fitter.m_thresh = m_threshold;
799 :
800 0 : if(m_setPointSource == USEREFIM && m_refIm.rows() == shmimMonitorT::m_width && m_refIm.cols() == shmimMonitorT::m_height)
801 : {
802 0 : mx::improc::eigenImage<float> refim, refedge;
803 0 : refim = m_refIm; //cuz it's modified by fitter.
804 0 : if(m_fitter.fit(refim, refedge) < 0)
805 : {
806 0 : return log<software_error, -1>({__FILE__, __LINE__, "error from fitter for reference"});
807 : }
808 :
809 0 : m_setx1 = m_fitter.m_avgx[0];
810 0 : m_sety1 = m_fitter.m_avgy[0];
811 0 : m_setD1 = 2*m_fitter.m_avgr[0];
812 :
813 0 : m_setx2 = m_fitter.m_avgx[1];
814 0 : m_sety2 = m_fitter.m_avgy[1];
815 0 : m_setD2 = 2*m_fitter.m_avgr[1];
816 :
817 0 : m_setx3 = m_fitter.m_avgx[2];
818 0 : m_sety3 = m_fitter.m_avgy[2];
819 0 : m_setD3 = 2*m_fitter.m_avgr[2];
820 :
821 0 : m_setx4 = m_fitter.m_avgx[3];
822 0 : m_sety4 = m_fitter.m_avgy[3];
823 0 : m_setD4 = 2*m_fitter.m_avgr[3];
824 :
825 0 : log<text_log>("Fit to reference image: ");
826 0 : log<text_log>("Quad 1 set points: " + std::to_string(m_setx1) + " " + std::to_string(m_sety1) + " " + std::to_string(m_setD1));
827 0 : log<text_log>("Quad 2 set points: " + std::to_string(m_setx2) + " " + std::to_string(m_sety2) + " " + std::to_string(m_setD2));
828 0 : log<text_log>("Quad 3 set points: " + std::to_string(m_setx3) + " " + std::to_string(m_sety3) + " " + std::to_string(m_setD3));
829 0 : log<text_log>("Quad 4 set points: " + std::to_string(m_setx4) + " " + std::to_string(m_sety4) + " " + std::to_string(m_setD4));
830 0 : }
831 : else
832 : {
833 0 : if(m_setPointSource == USEREFIM && (m_refIm.rows() != shmimMonitorT::m_width || m_refIm.cols() != shmimMonitorT::m_height))
834 : {
835 0 : if(m_refIm.rows()!=0 || m_refIm.cols() != 0) //only complain if the ref image has been loaded
836 : {
837 0 : log<text_log>("Reference image size does not match", logPrio::LOG_ERROR);
838 : }
839 : }
840 :
841 0 : if(m_setPointSource == USEUSERSET)
842 : {
843 0 : m_setx1 = m_userSetx1;
844 0 : m_sety1 = m_userSety1;
845 0 : m_setD1 = m_userSetD1;
846 :
847 0 : m_setx2 = m_userSetx2;
848 0 : m_sety2 = m_userSety2;
849 0 : m_setD2 = m_userSetD2;
850 :
851 0 : m_setx3 = m_userSetx3;
852 0 : m_sety3 = m_userSety3;
853 0 : m_setD3 = m_userSetD3;
854 :
855 0 : if(m_numPupils == 4)
856 : {
857 0 : m_setx4 = m_userSetx4;
858 0 : m_sety4 = m_userSety4;
859 0 : m_setD4 = m_userSetD4;
860 : }
861 0 : log<text_log>("Using user set-points");
862 :
863 : }
864 : else
865 : {
866 0 : m_setx1 = m_defSetx1;
867 0 : m_sety1 = m_defSety1;
868 0 : m_setD1 = m_defSetD1;
869 :
870 0 : m_setx2 = m_defSetx2;
871 0 : m_sety2 = m_defSety2;
872 0 : m_setD2 = m_defSetD2;
873 :
874 0 : m_setx3 = m_defSetx3;
875 0 : m_sety3 = m_defSety3;
876 0 : m_setD3 = m_defSetD3;
877 :
878 0 : if(m_numPupils == 4)
879 : {
880 0 : m_setx4 = m_defSetx4;
881 0 : m_sety4 = m_defSety4;
882 0 : m_setD4 = m_defSetD4;
883 : }
884 0 : log<text_log>("Set default set-points");
885 : }
886 : }
887 :
888 : uint32_t imsize[3];
889 0 : imsize[0] = shmimMonitorT::m_width;
890 0 : imsize[1] = shmimMonitorT::m_height;
891 0 : imsize[2] = 1;
892 :
893 0 : if(m_threshShmimConnected)
894 : {
895 0 : ImageStreamIO_destroyIm( &m_threshShmim );
896 0 : m_threshShmimConnected = false;
897 : }
898 :
899 0 : if(m_edgeShmimConnected)
900 : {
901 0 : ImageStreamIO_destroyIm( &m_edgeShmim );
902 0 : m_edgeShmimConnected = false;
903 : }
904 :
905 0 : ImageStreamIO_createIm_gpu(&m_threshShmim , m_threshShmimName.c_str(), 3, imsize, shmimMonitorT::m_dataType, -1, 1, IMAGE_NB_SEMAPHORE, 0, CIRCULAR_BUFFER | ZAXIS_TEMPORAL,0);
906 0 : m_threshShmimConnected = true;
907 :
908 0 : ImageStreamIO_createIm_gpu(&m_edgeShmim , m_edgeShmimName.c_str(), 3, imsize, shmimMonitorT::m_dataType, -1, 1, IMAGE_NB_SEMAPHORE, 0, CIRCULAR_BUFFER | ZAXIS_TEMPORAL,0);
909 0 : m_edgeShmimConnected = true;
910 :
911 :
912 0 : return 0;
913 0 : }
914 :
915 : inline
916 0 : int pupilFit::processImage( void* curr_src,
917 : const dev::shmimT & dummy
918 : )
919 : {
920 : static_cast<void>(dummy);
921 :
922 0 : for(unsigned nn=0; nn < shmimMonitorT::m_width*shmimMonitorT::m_height; ++nn)
923 : {
924 0 : m_fitIm.data()[nn] = (reinterpret_cast<float *>(curr_src)) [nn];
925 : }
926 :
927 0 : m_fitter.m_thresh = m_threshold;
928 :
929 0 : m_fitter.fit(m_fitIm, m_edgeIm);
930 :
931 :
932 : {//mutex scope
933 :
934 0 : std::lock_guard<std::mutex> guard(m_indiMutex);
935 0 : m_indiP_quad1["set-x"].set(m_setx1);
936 0 : m_indiP_quad1["x"].set(m_fitter.m_avgx[0]);
937 0 : m_indiP_quad1["dx"].set(m_fitter.m_avgx[0]-m_setx1);
938 0 : m_indiP_quad1["set-y"].set(m_sety1);
939 0 : m_indiP_quad1["y"].set(m_fitter.m_avgy[0]);
940 0 : m_indiP_quad1["dy"].set(m_fitter.m_avgy[0]-m_sety1);
941 0 : m_indiP_quad1["set-D"].set(m_setD1);
942 0 : m_indiP_quad1["D"].set(2*m_fitter.m_avgr[0]);
943 0 : m_indiP_quad1["dD"].set(2*m_fitter.m_avgr[0]-m_setD1);
944 0 : m_indiP_quad1["med"].set(m_fitter.m_med[0]);
945 0 : m_indiP_quad1["bg"].set(m_fitter.m_bg[0]);
946 0 : m_indiP_quad1.setState (INDI_BUSY);
947 0 : m_indiDriver->sendSetProperty (m_indiP_quad1);
948 :
949 0 : m_indiP_quad2["set-x"].set(m_setx2);
950 0 : m_indiP_quad2["x"].set(m_fitter.m_avgx[1]);
951 0 : m_indiP_quad2["dx"].set(m_fitter.m_avgx[1]-m_setx2);
952 0 : m_indiP_quad2["set-y"].set(m_sety2);
953 0 : m_indiP_quad2["y"].set(m_fitter.m_avgy[1]);
954 0 : m_indiP_quad2["dy"].set(m_fitter.m_avgy[1]-m_sety2);
955 0 : m_indiP_quad2["set-D"].set(m_setD2);
956 0 : m_indiP_quad2["D"].set(2*m_fitter.m_avgr[1]);
957 0 : m_indiP_quad2["dD"].set(2*m_fitter.m_avgr[1]-m_setD2);
958 0 : m_indiP_quad2["med"].set(m_fitter.m_med[1]);
959 0 : m_indiP_quad2["bg"].set(m_fitter.m_bg[1]);
960 0 : m_indiP_quad2.setState (INDI_BUSY);
961 0 : m_indiDriver->sendSetProperty (m_indiP_quad2);
962 :
963 0 : m_indiP_quad3["set-x"].set(m_setx3);
964 0 : m_indiP_quad3["x"].set(m_fitter.m_avgx[2]);
965 0 : m_indiP_quad3["dx"].set(m_fitter.m_avgx[2]-m_setx3);
966 0 : m_indiP_quad3["set-y"].set(m_sety3);
967 0 : m_indiP_quad3["y"].set(m_fitter.m_avgy[2]);
968 0 : m_indiP_quad3["dy"].set(m_fitter.m_avgy[2]-m_sety3);
969 0 : m_indiP_quad3["set-D"].set(m_setD3);
970 0 : m_indiP_quad3["D"].set(2*m_fitter.m_avgr[2]);
971 0 : m_indiP_quad3["dD"].set(2*m_fitter.m_avgr[2]-m_setD3);
972 0 : m_indiP_quad3["med"].set(m_fitter.m_med[2]);
973 0 : m_indiP_quad3["bg"].set(m_fitter.m_bg[2]);
974 0 : m_indiP_quad3.setState (INDI_BUSY);
975 0 : m_indiDriver->sendSetProperty (m_indiP_quad3);
976 :
977 0 : if(m_numPupils == 3)
978 : {
979 0 : m_indiP_avg["x"].set(.333*(m_fitter.m_avgx[0] + m_fitter.m_avgx[1] + m_fitter.m_avgx[2]));
980 0 : m_indiP_avg["y"].set(.333*(m_fitter.m_avgy[0] + m_fitter.m_avgy[1] + m_fitter.m_avgy[2]));
981 0 : m_indiP_avg["D"].set(.667*(m_fitter.m_avgr[0] + m_fitter.m_avgr[1] + m_fitter.m_avgr[2]));
982 :
983 0 : m_avg_dx = .333*(m_fitter.m_avgx[0] + m_fitter.m_avgx[1] + m_fitter.m_avgx[2] + m_fitter.m_avgx[3]) - 0.25*(m_setx1 + m_setx2 + m_setx3 + m_setx4);
984 0 : m_avg_dy = .333*(m_fitter.m_avgy[0] + m_fitter.m_avgy[1] + m_fitter.m_avgy[2] + m_fitter.m_avgy[3]) - 0.25*(m_sety1 + m_sety2 + m_sety3 + m_sety4);
985 :
986 :
987 0 : m_indiP_avg["dx"].set(.333*(m_fitter.m_avgx[0] + m_fitter.m_avgx[1] + m_fitter.m_avgx[2]) - 0.333*(m_setx1 + m_setx2 + m_setx3));
988 0 : m_indiP_avg["dy"].set(.333*(m_fitter.m_avgy[0] + m_fitter.m_avgy[1] + m_fitter.m_avgy[2]) - 0.333*(m_sety1 + m_sety2 + m_sety3));
989 0 : m_indiP_avg["dD"].set(.667*(m_fitter.m_avgr[0] + m_fitter.m_avgr[1] + m_fitter.m_avgr[2]) - 0.333*(m_setD1 + m_setD2 + m_setD3));
990 : }
991 : else
992 : {
993 0 : m_indiP_quad4["set-x"].set(m_setx4);
994 0 : m_indiP_quad4["x"].set(m_fitter.m_avgx[3]);
995 0 : m_indiP_quad4["dx"].set(m_fitter.m_avgx[3]-m_setx4);
996 0 : m_indiP_quad4["set-y"].set(m_sety4);
997 0 : m_indiP_quad4["y"].set(m_fitter.m_avgy[3]);
998 0 : m_indiP_quad4["dy"].set(m_fitter.m_avgy[3]-m_sety4);
999 0 : m_indiP_quad4["set-D"].set(m_setD4);
1000 0 : m_indiP_quad4["D"].set(2*m_fitter.m_avgr[3]);
1001 0 : m_indiP_quad4["dD"].set(2*m_fitter.m_avgr[3]-m_setD4);
1002 0 : m_indiP_quad4["med"].set(m_fitter.m_med[3]);
1003 0 : m_indiP_quad4["bg"].set(m_fitter.m_bg[3]);
1004 0 : m_indiP_quad4.setState (INDI_BUSY);
1005 0 : m_indiDriver->sendSetProperty (m_indiP_quad4);
1006 :
1007 0 : m_indiP_avg["x"].set(.25*(m_fitter.m_avgx[0] + m_fitter.m_avgx[1] + m_fitter.m_avgx[2] + m_fitter.m_avgx[3]));
1008 0 : m_indiP_avg["y"].set(.25*(m_fitter.m_avgy[0] + m_fitter.m_avgy[1] + m_fitter.m_avgy[2] + m_fitter.m_avgy[3]));
1009 0 : m_indiP_avg["D"].set(.5*(m_fitter.m_avgr[0] + m_fitter.m_avgr[1] + m_fitter.m_avgr[2] + m_fitter.m_avgr[3]));
1010 :
1011 0 : m_avg_dx = .25*(m_fitter.m_avgx[0] + m_fitter.m_avgx[1] + m_fitter.m_avgx[2] + m_fitter.m_avgx[3]) - 0.25*(m_setx1 + m_setx2 + m_setx3 + m_setx4);
1012 0 : m_avg_dy = .25*(m_fitter.m_avgy[0] + m_fitter.m_avgy[1] + m_fitter.m_avgy[2] + m_fitter.m_avgy[3]) - 0.25*(m_sety1 + m_sety2 + m_sety3 + m_sety4);
1013 :
1014 0 : m_indiP_avg["dx"].set(.25*(m_fitter.m_avgx[0] + m_fitter.m_avgx[1] + m_fitter.m_avgx[2] + m_fitter.m_avgx[3]) - 0.25*(m_setx1 + m_setx2 + m_setx3 + m_setx4));
1015 0 : m_indiP_avg["dy"].set(.25*(m_fitter.m_avgy[0] + m_fitter.m_avgy[1] + m_fitter.m_avgy[2] + m_fitter.m_avgy[3]) - 0.25*(m_sety1 + m_sety2 + m_sety3 + m_sety4));
1016 0 : m_indiP_avg["dD"].set(.5*(m_fitter.m_avgr[0] + m_fitter.m_avgr[1] + m_fitter.m_avgr[2] + m_fitter.m_avgr[3]) - 0.25*(m_setD1 + m_setD2 + m_setD3 + m_setD4));
1017 0 : m_indiDriver->sendSetProperty (m_indiP_avg);
1018 :
1019 : }
1020 :
1021 0 : }
1022 :
1023 : //signal framegrabber
1024 : //Now tell the f.g. to get going
1025 0 : m_updated = true;
1026 0 : if(sem_post(&m_smSemaphore) < 0)
1027 : {
1028 0 : log<software_critical>({__FILE__, __LINE__, errno, 0, "Error posting to semaphore"});
1029 0 : return -1;
1030 : }
1031 :
1032 :
1033 0 : if(m_averaging)
1034 : {
1035 0 : ++m_navg;
1036 :
1037 0 : m_avgx1_accum += m_fitter.m_avgx[0];
1038 0 : m_avgx1sq_accum += m_fitter.m_avgx[0]*m_fitter.m_avgx[0];
1039 :
1040 0 : m_avgy1_accum += m_fitter.m_avgy[0];
1041 0 : m_avgy1sq_accum += m_fitter.m_avgy[0]*m_fitter.m_avgy[0];
1042 :
1043 0 : m_avgD1_accum += 2*m_fitter.m_avgr[0];
1044 0 : m_avgD1sq_accum += 4*m_fitter.m_avgr[0]*m_fitter.m_avgr[0];
1045 :
1046 0 : m_avgmed1_accum += m_fitter.m_med[0];
1047 0 : m_avgmed1sq_accum += m_fitter.m_med[0]*m_fitter.m_med[0];
1048 :
1049 0 : m_avgx1 = m_avgx1_accum / m_navg;
1050 0 : m_varx1 = m_avgx1sq_accum / m_navg - m_avgx1*m_avgx1;
1051 :
1052 0 : m_avgy1 = m_avgy1_accum / m_navg;
1053 0 : m_vary1 = m_avgy1sq_accum / m_navg - m_avgy1*m_avgy1;
1054 :
1055 0 : m_avgD1 = m_avgD1_accum / m_navg;
1056 0 : m_varD1 = m_avgD1sq_accum / m_navg - m_avgD1*m_avgD1;
1057 :
1058 0 : m_avgmed1 = m_avgmed1_accum / m_navg;
1059 0 : m_varmed1 = m_avgmed1sq_accum / m_navg - m_avgmed1*m_avgmed1;
1060 :
1061 0 : m_avgx2_accum += m_fitter.m_avgx[1];
1062 0 : m_avgx2sq_accum += m_fitter.m_avgx[1]*m_fitter.m_avgx[1];
1063 :
1064 0 : m_avgy2_accum += m_fitter.m_avgy[1];
1065 0 : m_avgy2sq_accum += m_fitter.m_avgy[1]*m_fitter.m_avgy[1];
1066 :
1067 0 : m_avgD2_accum += 2*m_fitter.m_avgr[1];
1068 0 : m_avgD2sq_accum += 4*m_fitter.m_avgr[1]*m_fitter.m_avgr[1];
1069 :
1070 0 : m_avgmed2_accum += m_fitter.m_med[1];
1071 0 : m_avgmed2sq_accum += m_fitter.m_med[1]*m_fitter.m_med[1];
1072 :
1073 0 : m_avgx2 = m_avgx2_accum / m_navg;
1074 0 : m_varx2 = m_avgx2sq_accum / m_navg - m_avgx2*m_avgx2;
1075 :
1076 0 : m_avgy2 = m_avgy2_accum / m_navg;
1077 0 : m_vary2 = m_avgy2sq_accum / m_navg - m_avgy2*m_avgy2;
1078 :
1079 0 : m_avgD2 = m_avgD2_accum / m_navg;
1080 0 : m_varD2 = m_avgD2sq_accum / m_navg - m_avgD2*m_avgD2;
1081 :
1082 0 : m_avgmed2 = m_avgmed2_accum / m_navg;
1083 0 : m_varmed2 = m_avgmed2sq_accum / m_navg - m_avgmed2*m_avgmed2;
1084 :
1085 :
1086 :
1087 0 : m_avgx3_accum += m_fitter.m_avgx[2];
1088 0 : m_avgx3sq_accum += m_fitter.m_avgx[2]*m_fitter.m_avgx[2];
1089 :
1090 0 : m_avgy3_accum += m_fitter.m_avgy[2];
1091 0 : m_avgy3sq_accum += m_fitter.m_avgy[2]*m_fitter.m_avgy[2];
1092 :
1093 0 : m_avgD3_accum += 2*m_fitter.m_avgr[2];
1094 0 : m_avgD3sq_accum += 4*m_fitter.m_avgr[2]*m_fitter.m_avgr[2];
1095 :
1096 0 : m_avgmed3_accum += m_fitter.m_med[2];
1097 0 : m_avgmed3sq_accum += m_fitter.m_med[2]*m_fitter.m_med[2];
1098 :
1099 0 : m_avgx3 = m_avgx3_accum / m_navg;
1100 0 : m_varx3 = m_avgx3sq_accum / m_navg - m_avgx3*m_avgx3;
1101 :
1102 0 : m_avgy3 = m_avgy3_accum / m_navg;
1103 0 : m_vary3 = m_avgy3sq_accum / m_navg - m_avgy3*m_avgy3;
1104 :
1105 0 : m_avgD3 = m_avgD3_accum / m_navg;
1106 0 : m_varD3 = m_avgD3sq_accum / m_navg - m_avgD3*m_avgD3;
1107 :
1108 0 : m_avgmed3 = m_avgmed3_accum / m_navg;
1109 0 : m_varmed3 = m_avgmed3sq_accum / m_navg - m_avgmed3*m_avgmed3;
1110 :
1111 0 : if(m_numPupils == 3)
1112 : {
1113 0 : float tmp = 0.333*(m_fitter.m_avgx[0]+m_fitter.m_avgx[1]+m_fitter.m_avgx[2]+m_fitter.m_avgx[3]);
1114 0 : m_avgxAll_accum += tmp;
1115 0 : m_avgxAllsq_accum += tmp*tmp;
1116 :
1117 0 : tmp = 0.333*(m_fitter.m_avgy[0]+m_fitter.m_avgy[1]+m_fitter.m_avgy[2]);
1118 0 : m_avgyAll_accum += tmp;
1119 0 : m_avgyAllsq_accum += tmp*tmp;
1120 :
1121 0 : tmp = 2*0.333*(m_fitter.m_avgr[0]+m_fitter.m_avgr[1]+m_fitter.m_avgr[2]);
1122 0 : m_avgDAll_accum += tmp;
1123 0 : m_avgDAllsq_accum += tmp*tmp;
1124 :
1125 0 : tmp = 0.333*(m_fitter.m_med[0]+m_fitter.m_med[1]+m_fitter.m_med[2]);
1126 0 : m_avgmedAll_accum += tmp;
1127 0 : m_avgmedAllsq_accum += tmp*tmp;
1128 :
1129 0 : m_avgxAll = m_avgxAll_accum / m_navg;
1130 0 : m_varxAll = m_avgxAllsq_accum / m_navg - m_avgxAll*m_avgxAll;
1131 :
1132 0 : m_avgyAll = m_avgyAll_accum / m_navg;
1133 0 : m_varyAll = m_avgyAllsq_accum / m_navg - m_avgyAll*m_avgyAll;
1134 :
1135 0 : m_avgDAll = m_avgDAll_accum / m_navg;
1136 0 : m_varDAll = m_avgDAllsq_accum / m_navg - m_avgDAll*m_avgDAll;
1137 :
1138 0 : m_avgmedAll = m_avgmedAll_accum / m_navg;
1139 0 : m_varmedAll = m_avgmedAllsq_accum / m_navg - m_avgmedAll*m_avgmedAll;
1140 :
1141 :
1142 0 : std::cerr << "****************************************************************\n";
1143 0 : std::cerr << "Averaged: " << m_navg << "\n";
1144 0 : std::cerr << "Average x1: " << m_avgx1 << " +/- " << sqrt(m_varx1) << "\n";
1145 0 : std::cerr << "Average y1: " << m_avgy1 << " +/- " << sqrt(m_vary1) << "\n";
1146 0 : std::cerr << "Average D1: " << m_avgD1 << " +/- " << sqrt(m_varD1) << "\n";
1147 0 : std::cerr << "Average med1: " << m_avgmed1 << " +/- " << sqrt(m_varmed1) << "\n\n";
1148 0 : std::cerr << "Average x2: " << m_avgx2 << " +/- " << sqrt(m_varx2) << "\n";
1149 0 : std::cerr << "Average y2: " << m_avgy2 << " +/- " << sqrt(m_vary2) << "\n";
1150 0 : std::cerr << "Average D2: " << m_avgD2 << " +/- " << sqrt(m_varD2) << "\n";
1151 0 : std::cerr << "Average med2: " << m_avgmed2 << " +/- " << sqrt(m_varmed2) << "\n\n";
1152 0 : std::cerr << "Average x3: " << m_avgx3 << " +/- " << sqrt(m_varx3) << "\n";
1153 0 : std::cerr << "Average y3: " << m_avgy3 << " +/- " << sqrt(m_vary3) << "\n";
1154 0 : std::cerr << "Average D3: " << m_avgD3 << " +/- " << sqrt(m_varD3) << "\n";
1155 0 : std::cerr << "Average med3: " << m_avgmed3 << " +/- " << sqrt(m_varmed3) << "\n\n";
1156 0 : std::cerr << "Average xAll: " << m_avgxAll << " +/- " << sqrt(m_varxAll) << "\n";
1157 0 : std::cerr << "Average yAll: " << m_avgyAll << " +/- " << sqrt(m_varyAll) << "\n";
1158 0 : std::cerr << "Average DAll: " << m_avgDAll << " +/- " << sqrt(m_varDAll) << "\n";
1159 0 : std::cerr << "Average medAll: " << m_avgmedAll << " +/- " << sqrt(m_varmedAll) << "\n\n";
1160 : }
1161 : else
1162 : {
1163 0 : m_avgx4_accum += m_fitter.m_avgx[3];
1164 0 : m_avgx4sq_accum += m_fitter.m_avgx[3]*m_fitter.m_avgx[3];
1165 :
1166 0 : m_avgy4_accum += m_fitter.m_avgy[3];
1167 0 : m_avgy4sq_accum += m_fitter.m_avgy[3]*m_fitter.m_avgy[3];
1168 :
1169 0 : m_avgD4_accum += 2*m_fitter.m_avgr[3];
1170 0 : m_avgD4sq_accum += 4*m_fitter.m_avgr[3]*m_fitter.m_avgr[3];
1171 :
1172 0 : m_avgmed4_accum += m_fitter.m_med[3];
1173 0 : m_avgmed4sq_accum += m_fitter.m_med[3]*m_fitter.m_med[3];
1174 :
1175 0 : m_avgx4 = m_avgx4_accum / m_navg;
1176 0 : m_varx4 = m_avgx4sq_accum / m_navg - m_avgx4*m_avgx4;
1177 :
1178 0 : m_avgy4 = m_avgy4_accum / m_navg;
1179 0 : m_vary4 = m_avgy4sq_accum / m_navg - m_avgy4*m_avgy4;
1180 :
1181 0 : m_avgD4 = m_avgD4_accum / m_navg;
1182 0 : m_varD4 = m_avgD4sq_accum / m_navg - m_avgD4*m_avgD4;
1183 :
1184 0 : m_avgmed4 = m_avgmed4_accum / m_navg;
1185 0 : m_varmed4 = m_avgmed4sq_accum / m_navg - m_avgmed4*m_avgmed4;
1186 :
1187 :
1188 0 : float tmp = 0.25*(m_fitter.m_avgx[0]+m_fitter.m_avgx[1]+m_fitter.m_avgx[2]+m_fitter.m_avgx[3]);
1189 0 : m_avgxAll_accum += tmp;
1190 0 : m_avgxAllsq_accum += tmp*tmp;
1191 :
1192 0 : tmp = 0.25*(m_fitter.m_avgy[0]+m_fitter.m_avgy[1]+m_fitter.m_avgy[2]+m_fitter.m_avgy[3]);
1193 0 : m_avgyAll_accum += tmp;
1194 0 : m_avgyAllsq_accum += tmp*tmp;
1195 :
1196 0 : tmp = 2*0.25*(m_fitter.m_avgr[0]+m_fitter.m_avgr[1]+m_fitter.m_avgr[2]+m_fitter.m_avgr[3]);
1197 0 : m_avgDAll_accum += tmp;
1198 0 : m_avgDAllsq_accum += tmp*tmp;
1199 :
1200 0 : tmp = 0.25*(m_fitter.m_med[0]+m_fitter.m_med[1]+m_fitter.m_med[2]+m_fitter.m_med[3]);
1201 0 : m_avgmedAll_accum += tmp;
1202 0 : m_avgmedAllsq_accum += tmp*tmp;
1203 :
1204 0 : m_avgxAll = m_avgxAll_accum / m_navg;
1205 0 : m_varxAll = m_avgxAllsq_accum / m_navg - m_avgxAll*m_avgxAll;
1206 :
1207 0 : m_avgyAll = m_avgyAll_accum / m_navg;
1208 0 : m_varyAll = m_avgyAllsq_accum / m_navg - m_avgyAll*m_avgyAll;
1209 :
1210 0 : m_avgDAll = m_avgDAll_accum / m_navg;
1211 0 : m_varDAll = m_avgDAllsq_accum / m_navg - m_avgDAll*m_avgDAll;
1212 :
1213 0 : m_avgmedAll = m_avgmedAll_accum / m_navg;
1214 0 : m_varmedAll = m_avgmedAllsq_accum / m_navg - m_avgmedAll*m_avgmedAll;
1215 :
1216 :
1217 0 : std::cerr << "****************************************************************\n";
1218 0 : std::cerr << "Averaged: " << m_navg << "\n";
1219 0 : std::cerr << "Average x1: " << m_avgx1 << " +/- " << sqrt(m_varx1) << "\n";
1220 0 : std::cerr << "Average y1: " << m_avgy1 << " +/- " << sqrt(m_vary1) << "\n";
1221 0 : std::cerr << "Average D1: " << m_avgD1 << " +/- " << sqrt(m_varD1) << "\n";
1222 0 : std::cerr << "Average med1: " << m_avgmed1 << " +/- " << sqrt(m_varmed1) << "\n\n";
1223 0 : std::cerr << "Average x2: " << m_avgx2 << " +/- " << sqrt(m_varx2) << "\n";
1224 0 : std::cerr << "Average y2: " << m_avgy2 << " +/- " << sqrt(m_vary2) << "\n";
1225 0 : std::cerr << "Average D2: " << m_avgD2 << " +/- " << sqrt(m_varD2) << "\n";
1226 0 : std::cerr << "Average med2: " << m_avgmed2 << " +/- " << sqrt(m_varmed2) << "\n\n";
1227 0 : std::cerr << "Average x3: " << m_avgx3 << " +/- " << sqrt(m_varx3) << "\n";
1228 0 : std::cerr << "Average y3: " << m_avgy3 << " +/- " << sqrt(m_vary3) << "\n";
1229 0 : std::cerr << "Average D3: " << m_avgD3 << " +/- " << sqrt(m_varD3) << "\n";
1230 0 : std::cerr << "Average med3: " << m_avgmed3 << " +/- " << sqrt(m_varmed3) << "\n\n";
1231 0 : std::cerr << "Average x4: " << m_avgx4 << " +/- " << sqrt(m_varx4) << "\n";
1232 0 : std::cerr << "Average y4: " << m_avgy4 << " +/- " << sqrt(m_vary4) << "\n";
1233 0 : std::cerr << "Average D4: " << m_avgD4 << " +/- " << sqrt(m_varD4) << "\n";
1234 0 : std::cerr << "Average med4: " << m_avgmed4 << " +/- " << sqrt(m_varmed4) << "\n\n";
1235 0 : std::cerr << "Average xAll: " << m_avgxAll << " +/- " << sqrt(m_varxAll) << "\n";
1236 0 : std::cerr << "Average yAll: " << m_avgyAll << " +/- " << sqrt(m_varyAll) << "\n";
1237 0 : std::cerr << "Average DAll: " << m_avgDAll << " +/- " << sqrt(m_varDAll) << "\n";
1238 0 : std::cerr << "Average medAll: " << m_avgmedAll << " +/- " << sqrt(m_varmedAll) << "\n\n";
1239 : }
1240 : }
1241 :
1242 0 : m_threshShmim.md->write=1;
1243 0 : m_edgeShmim.md->write=1;
1244 :
1245 0 : clock_gettime(CLOCK_REALTIME, &m_threshShmim.md->writetime);
1246 0 : m_edgeShmim.md->writetime = m_threshShmim.md->writetime;
1247 :
1248 0 : m_threshShmim.md->atime = m_threshShmim.md->writetime;
1249 0 : m_edgeShmim.md->atime = m_threshShmim.md->writetime;
1250 :
1251 0 : m_threshShmim.md->cnt0++;
1252 0 : m_edgeShmim.md->cnt0++;
1253 :
1254 0 : memcpy(m_threshShmim.array.raw, m_fitIm.data(), m_fitIm.rows()*m_fitIm.cols()*sizeof(float));
1255 0 : memcpy(m_edgeShmim.array.raw, m_edgeIm.data(), m_edgeIm.rows()*m_edgeIm.cols()*sizeof(float));
1256 :
1257 0 : m_threshShmim.md->write=0;
1258 0 : m_edgeShmim.md->write=0;
1259 :
1260 0 : ImageStreamIO_sempost(&m_threshShmim,-1);
1261 0 : ImageStreamIO_sempost(&m_edgeShmim,-1);
1262 :
1263 0 : return 0;
1264 : }
1265 :
1266 : inline
1267 0 : int pupilFit::allocate(const refShmimT & dummy)
1268 : {
1269 : static_cast<void>(dummy);
1270 :
1271 0 : std::lock_guard<std::mutex> guard(m_indiMutex);
1272 :
1273 0 : if(refShmimMonitorT::m_dataType != IMAGESTRUCT_FLOAT)
1274 : {
1275 0 : return log<software_error,-1>({__FILE__, __LINE__, "reference is not float"});
1276 : }
1277 :
1278 0 : m_refIm.resize( refShmimMonitorT::m_width, refShmimMonitorT::m_height );
1279 :
1280 0 : return 0;
1281 0 : }
1282 :
1283 : inline
1284 0 : int pupilFit::processImage( void* curr_src,
1285 : const refShmimT & dummy
1286 : )
1287 : {
1288 : static_cast<void>(dummy);
1289 :
1290 0 : int npix = 0;
1291 0 : for(unsigned nn=0; nn < refShmimMonitorT::m_width*refShmimMonitorT::m_height; ++nn)
1292 : {
1293 0 : m_refIm.data()[nn] = (reinterpret_cast<float *>(curr_src)) [nn];
1294 0 : ++npix;
1295 : }
1296 :
1297 0 : log<text_log>("reference updated", logPrio::LOG_NOTICE);
1298 :
1299 0 : std::cerr << m_refIm.sum() << " " << npix << "\n";
1300 :
1301 0 : shmimMonitorT::m_restart = true;
1302 :
1303 0 : return 0;
1304 : }
1305 :
1306 : inline
1307 0 : int pupilFit::configureAcquisition()
1308 : {
1309 0 : std::unique_lock<std::mutex> lock(m_indiMutex);
1310 :
1311 0 : frameGrabberT::m_width = 2;
1312 0 : frameGrabberT::m_height = 1;
1313 0 : frameGrabberT::m_dataType = _DATATYPE_FLOAT;
1314 :
1315 0 : return 0;
1316 0 : }
1317 :
1318 : inline
1319 0 : int pupilFit::startAcquisition()
1320 : {
1321 0 : return 0;
1322 : }
1323 :
1324 : inline
1325 0 : int pupilFit::acquireAndCheckValid()
1326 : {
1327 : timespec ts;
1328 :
1329 0 : if(clock_gettime(CLOCK_REALTIME, &ts) < 0)
1330 : {
1331 0 : log<software_critical>({__FILE__,__LINE__,errno,0,"clock_gettime"});
1332 0 : return -1;
1333 : }
1334 :
1335 0 : ts.tv_sec += 1;
1336 :
1337 0 : if(sem_timedwait(&m_smSemaphore, &ts) == 0)
1338 : {
1339 0 : if( m_updated )
1340 : {
1341 0 : clock_gettime(CLOCK_REALTIME, &m_currImageTimestamp);
1342 0 : return 0;
1343 : }
1344 : else
1345 : {
1346 0 : return 1;
1347 : }
1348 : }
1349 : else
1350 : {
1351 0 : return 1;
1352 : }
1353 : }
1354 :
1355 : inline
1356 0 : int pupilFit::loadImageIntoStream(void * dest)
1357 : {
1358 0 : (reinterpret_cast<float *>(dest))[0] = m_avg_dx;
1359 0 : (reinterpret_cast<float *>(dest))[1] = m_avg_dy;
1360 :
1361 0 : m_updated = false;
1362 0 : return 0;
1363 : }
1364 :
1365 : inline
1366 0 : int pupilFit::reconfig()
1367 : {
1368 0 : return 0;
1369 : }
1370 :
1371 0 : INDI_NEWCALLBACK_DEFN(pupilFit, m_indiP_thresh)(const pcf::IndiProperty & ipRecv)
1372 : {
1373 0 : if(ipRecv.getName() != m_indiP_thresh.getName())
1374 : {
1375 0 : log<software_error>({__FILE__,__LINE__, "wrong INDI property received."});
1376 0 : return -1;
1377 : }
1378 :
1379 : float target;
1380 :
1381 0 : if( indiTargetUpdate( m_indiP_thresh, target, ipRecv, true) < 0)
1382 : {
1383 0 : log<software_error>({__FILE__,__LINE__});
1384 0 : return -1;
1385 : }
1386 :
1387 0 : m_threshold = target;
1388 :
1389 0 : if(m_setPointSource == USEREFIM) shmimMonitorT::m_restart = true; //need to re-process the reference
1390 :
1391 0 : log<text_log>("set threshold = " + std::to_string(m_threshold), logPrio::LOG_NOTICE);
1392 0 : return 0;
1393 : }
1394 :
1395 0 : INDI_NEWCALLBACK_DEFN(pupilFit, m_indiP_averaging)(const pcf::IndiProperty & ipRecv)
1396 : {
1397 0 : if(ipRecv.getName() != m_indiP_averaging.getName())
1398 : {
1399 0 : log<software_error>({__FILE__,__LINE__, "wrong INDI property received."});
1400 0 : return -1;
1401 : }
1402 :
1403 0 : if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::On)
1404 : {
1405 :
1406 0 : m_avgx1_accum = 0;
1407 0 : m_avgx1sq_accum = 0;
1408 0 : m_avgy1_accum = 0;
1409 0 : m_avgy1sq_accum = 0;
1410 0 : m_avgD1_accum = 0;
1411 0 : m_avgD1sq_accum = 0;
1412 0 : m_avgmed1_accum = 0;
1413 0 : m_avgmed1sq_accum = 0;
1414 :
1415 0 : m_avgx2_accum = 0;
1416 0 : m_avgx2sq_accum = 0;
1417 0 : m_avgy2_accum = 0;
1418 0 : m_avgy2sq_accum = 0;
1419 0 : m_avgD2_accum = 0;
1420 0 : m_avgD2sq_accum = 0;
1421 0 : m_avgmed2_accum = 0;
1422 0 : m_avgmed2sq_accum = 0;
1423 :
1424 0 : m_avgx3_accum = 0;
1425 0 : m_avgx3sq_accum = 0;
1426 0 : m_avgy3_accum = 0;
1427 0 : m_avgy3sq_accum = 0;
1428 0 : m_avgD3_accum = 0;
1429 0 : m_avgD3sq_accum = 0;
1430 0 : m_avgmed3_accum = 0;
1431 0 : m_avgmed3sq_accum = 0;
1432 :
1433 0 : m_avgx4_accum = 0;
1434 0 : m_avgx4sq_accum = 0;
1435 0 : m_avgy4_accum = 0;
1436 0 : m_avgy4sq_accum = 0;
1437 0 : m_avgD4_accum = 0;
1438 0 : m_avgD4sq_accum = 0;
1439 0 : m_avgmed4_accum = 0;
1440 0 : m_avgmed4sq_accum = 0;
1441 :
1442 0 : m_avgxAll_accum = 0;
1443 0 : m_avgxAllsq_accum = 0;
1444 0 : m_avgyAll_accum = 0;
1445 0 : m_avgyAllsq_accum = 0;
1446 0 : m_avgDAll_accum = 0;
1447 0 : m_avgDAllsq_accum = 0;
1448 0 : m_avgmedAll_accum = 0;
1449 0 : m_avgmedAllsq_accum = 0;
1450 :
1451 0 : m_navg = 0;
1452 0 : m_averaging = true;
1453 :
1454 0 : updateSwitchIfChanged(m_indiP_averaging, "toggle", pcf::IndiElement::On, INDI_BUSY);
1455 :
1456 0 : log<text_log>("began averaging");
1457 :
1458 : }
1459 0 : else if( ipRecv["toggle"].getSwitchState() == pcf::IndiElement::Off)
1460 : {
1461 0 : m_averaging = false;
1462 0 : updateSwitchIfChanged(m_indiP_averaging, "toggle", pcf::IndiElement::Off, INDI_IDLE);
1463 :
1464 0 : log<text_log>("stopped averaging");
1465 : }
1466 :
1467 0 : return 0;
1468 : }
1469 :
1470 0 : INDI_NEWCALLBACK_DEFN(pupilFit, m_indiP_reload)(const pcf::IndiProperty & ipRecv)
1471 : {
1472 0 : if(ipRecv.getName() != m_indiP_reload.getName())
1473 : {
1474 0 : log<software_error>({__FILE__,__LINE__, "wrong INDI property received."});
1475 0 : return -1;
1476 : }
1477 :
1478 0 : if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
1479 : {
1480 0 : log<text_log>("reloading");
1481 0 : shmimMonitorT::m_restart = 1;
1482 : }
1483 :
1484 0 : return 0;
1485 : }
1486 :
1487 0 : INDI_NEWCALLBACK_DEFN(pupilFit, m_indiP_update)(const pcf::IndiProperty & ipRecv)
1488 : {
1489 0 : if(ipRecv.getName() != m_indiP_update.getName())
1490 : {
1491 0 : log<software_error>({__FILE__,__LINE__, "wrong INDI property received."});
1492 0 : return -1;
1493 : }
1494 :
1495 0 : if( ipRecv["request"].getSwitchState() == pcf::IndiElement::On)
1496 : {
1497 0 : std::lock_guard<std::mutex> guard(m_indiMutex);
1498 :
1499 0 : m_setx1 = m_indiP_quad1["x"].get<float>();
1500 0 : m_sety1 = m_indiP_quad1["y"].get<float>();
1501 0 : m_setD1 = m_indiP_quad1["D"].get<float>();
1502 :
1503 0 : m_setx2 = m_indiP_quad2["x"].get<float>();
1504 0 : m_sety2 = m_indiP_quad2["y"].get<float>();
1505 0 : m_setD2 = m_indiP_quad2["D"].get<float>();
1506 :
1507 0 : m_setx3 = m_indiP_quad3["x"].get<float>();
1508 0 : m_sety3 = m_indiP_quad3["y"].get<float>();
1509 0 : m_setD3 = m_indiP_quad3["D"].get<float>();
1510 :
1511 0 : log<text_log>("Recorded current set-points: ");
1512 0 : log<text_log>("Quad 1 set points: " + std::to_string(m_setx1) + " " + std::to_string(m_sety1) + " " + std::to_string(m_setD1));
1513 0 : log<text_log>("Quad 2 set points: " + std::to_string(m_setx2) + " " + std::to_string(m_sety2) + " " + std::to_string(m_setD2));
1514 0 : log<text_log>("Quad 3 set points: " + std::to_string(m_setx3) + " " + std::to_string(m_sety3) + " " + std::to_string(m_setD3));
1515 :
1516 0 : if(m_numPupils == 4)
1517 : {
1518 0 : m_setx4 = m_indiP_quad4["x"].get<float>();
1519 0 : m_sety4 = m_indiP_quad4["y"].get<float>();
1520 0 : m_setD4 = m_indiP_quad4["D"].get<float>();
1521 0 : log<text_log>("Quad 4 set points: " + std::to_string(m_setx4) + " " + std::to_string(m_sety4) + " " + std::to_string(m_setD4));
1522 : }
1523 :
1524 0 : if(m_setPointSource == USEUSERSET) shmimMonitorT::m_restart = true;
1525 0 : }
1526 :
1527 0 : return 0;
1528 : }
1529 :
1530 0 : INDI_NEWCALLBACK_DEFN(pupilFit, m_indiP_refmode)(const pcf::IndiProperty & ipRecv)
1531 : {
1532 0 : if(ipRecv.getName() != m_indiP_refmode.getName())
1533 : {
1534 0 : log<software_error>({__FILE__,__LINE__, "wrong INDI property received."});
1535 0 : return -1;
1536 : }
1537 :
1538 0 : if(ipRecv.find("default"))
1539 : {
1540 0 : if( ipRecv["default"].getSwitchState() == pcf::IndiElement::On)
1541 : {
1542 0 : if( m_setPointSource != USEDEFSET)
1543 : {
1544 0 : log<text_log>("using default reference.", logPrio::LOG_NOTICE);
1545 0 : m_setPointSource = USEDEFSET;
1546 0 : shmimMonitorT::m_restart = true;
1547 0 : return 0;
1548 : }
1549 : }
1550 : }
1551 0 : if(ipRecv.find("refim"))
1552 : {
1553 0 : if( ipRecv["refim"].getSwitchState() == pcf::IndiElement::On)
1554 : {
1555 0 : if( m_setPointSource != USEREFIM)
1556 : {
1557 0 : log<text_log>("using reference image.", logPrio::LOG_NOTICE);
1558 0 : m_setPointSource = USEREFIM;
1559 0 : shmimMonitorT::m_restart = true;
1560 0 : return 0;
1561 : }
1562 : }
1563 : }
1564 0 : if(ipRecv.find("user"))
1565 : {
1566 0 : if( ipRecv["user"].getSwitchState() == pcf::IndiElement::On)
1567 : {
1568 0 : if( m_setPointSource != USEUSERSET)
1569 : {
1570 0 : log<text_log>("using user image.", logPrio::LOG_NOTICE);
1571 0 : m_setPointSource = USEUSERSET;
1572 0 : shmimMonitorT::m_restart = true;
1573 0 : return 0;
1574 : }
1575 : }
1576 : }
1577 :
1578 0 : return 0;
1579 : }
1580 :
1581 : inline
1582 0 : int pupilFit::checkRecordTimes()
1583 : {
1584 0 : return telemeterT::checkRecordTimes(telem_fgtimings());
1585 : }
1586 :
1587 : inline
1588 0 : int pupilFit::recordTelem( const telem_fgtimings * )
1589 : {
1590 0 : return recordFGTimings(true);
1591 : }
1592 :
1593 : } //namespace app
1594 : } //namespace MagAOX
1595 :
1596 : #endif //pupilFit_hpp
|