10 #include "../../libMagAOX/libMagAOX.hpp"
11 #include "../../magaox_git_version.h"
167 if(m_threshShmimConnected)
169 ImageStreamIO_destroyIm( &m_threshShmim );
172 if(m_edgeShmimConnected)
174 ImageStreamIO_destroyIm( &m_edgeShmim );
183 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");
185 config.add(
"fit.threshold",
"",
"fit.threshold", argType::Required,
"fit",
"threshold",
false,
"float",
"The pupil finding threshold. 0 < threshold < 1");
186 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.");
187 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.");
189 config.add(
"fit.numPupils",
"",
"fit.numPupils", argType::Required,
"fit",
"numPupils",
false,
"int",
"The number of pupils. Default is 4. 3 is also supported.");
190 config.add(
"fit.pupMedIndex",
"",
"fit.pupMedIndex", argType::Required,
"fit",
"pupMedIndex",
false,
"float",
"The index of the pupil median in a sorted quadrant.");
192 config.add(
"wfsref.path",
"" ,
"wfsref.path", argType::Required,
"wfsref",
"path",
false,
"float",
"The path to the WFS reference image. Default is /opt/MagAOX/cacao/tweeter");
193 config.add(
"wfsref.name",
"" ,
"wfsref.name", argType::Required,
"wfsref",
"name",
false,
"float",
"The name the WFS reference image. Default is wfsref0.fits");
204 _config(m_threshShmimName,
"fit.threshShmimName");
205 _config(m_edgeShmimName,
"fit.edgeShmimName");
206 _config(m_numPupils,
"fit.numPupils");
207 _config(m_fitter.m_pupMedIndex,
"fit.pupMedIndex");
209 _config(m_wfsrefPath,
"wfsref.path");
210 _config(m_wfsrefName,
"wfsref.name");
229 createStandardIndiNumber<float>( m_indiP_thresh,
"threshold", 0, 1 ,0,
"%0.2f",
"Threshold");
235 m_indiP_averaging[
"toggle"].set(pcf::IndiElement::Off);
238 log<software_error>({__FILE__,__LINE__});
243 indi::addNumberElement<int>( m_indiP_numPupils,
"value", 3, 4, 1,
"%d",
"");
244 m_indiP_numPupils[
"value"].set(m_numPupils);
248 indi::addNumberElement<float>( m_indiP_quad1,
"x", 0, 59, 0,
"%0.2f",
"center x");
249 indi::addNumberElement<float>( m_indiP_quad1,
"dx", 0, 59, 0,
"%0.2f",
"delta-x");
250 indi::addNumberElement<float>( m_indiP_quad1,
"y", 0, 59, 0,
"%0.2f",
"center x");
251 indi::addNumberElement<float>( m_indiP_quad1,
"dy", 0, 59, 0,
"%0.2f",
"delta-y");
252 indi::addNumberElement<float>( m_indiP_quad1,
"D", 0, 59, 0,
"%0.2f",
"diameter");
253 indi::addNumberElement<float>( m_indiP_quad1,
"dD", 0, 59, 0,
"%0.2f",
"delta-D");
254 indi::addNumberElement<float>( m_indiP_quad1,
"med", 0, std::numeric_limits<uint16_t>::max(), 0,
"%0.1f",
"flux");
255 indi::addNumberElement<float>( m_indiP_quad1,
"set-x", 0, 59, 0,
"%0.2f",
"set pt. center x");
256 m_indiP_quad1[
"set-x"] = m_setx1;
257 indi::addNumberElement<float>( m_indiP_quad1,
"set-y", 0, 59, 0,
"%0.2f",
"set pt. center x");
258 m_indiP_quad1[
"set-y"] = m_sety1;
259 indi::addNumberElement<float>( m_indiP_quad1,
"set-D", 0, 59, 0,
"%0.2f",
"set pt. diameter");
260 m_indiP_quad1[
"set-D"] = m_setD1;
265 indi::addNumberElement<float>( m_indiP_quad2,
"x", 0, 59, 0,
"%0.2f",
"center x");
266 indi::addNumberElement<float>( m_indiP_quad2,
"dx", 0, 59, 0,
"%0.2f",
"delta-x");
267 indi::addNumberElement<float>( m_indiP_quad2,
"y", 0, 59, 0,
"%0.2f",
"center y");
268 indi::addNumberElement<float>( m_indiP_quad2,
"dy", 0, 59, 0,
"%0.2f",
"delta-y");
269 indi::addNumberElement<float>( m_indiP_quad2,
"D", 0, 59, 0,
"%0.2f",
"diameter");
270 indi::addNumberElement<float>( m_indiP_quad2,
"dD", 0, 59, 0,
"%0.2f",
"delta-D");
271 indi::addNumberElement<float>( m_indiP_quad2,
"med", 0, std::numeric_limits<uint16_t>::max(), 0,
"%0.1f",
"flux");
272 indi::addNumberElement<float>( m_indiP_quad2,
"set-x", 0, 59, 0,
"%0.2f",
"set pt. center x");
273 m_indiP_quad2[
"set-x"] = m_setx2;
274 indi::addNumberElement<float>( m_indiP_quad2,
"set-y", 0, 59, 0,
"%0.2f",
"set pt. center x");
275 m_indiP_quad2[
"set-y"] = m_sety2;
276 indi::addNumberElement<float>( m_indiP_quad2,
"set-D", 0, 59, 0,
"%0.2f",
"set pt. diameter");
277 m_indiP_quad2[
"set-D"] = m_setD2;
281 indi::addNumberElement<float>( m_indiP_quad3,
"x", 0, 59, 0,
"%0.2f",
"center x");
282 indi::addNumberElement<float>( m_indiP_quad3,
"dx", 0, 59, 0,
"%0.2f",
"delta-x");
283 indi::addNumberElement<float>( m_indiP_quad3,
"y", 0, 59, 0,
"%0.2f",
"center y");
284 indi::addNumberElement<float>( m_indiP_quad3,
"dy", 0, 59, 0,
"%0.2f",
"delta-y");
285 indi::addNumberElement<float>( m_indiP_quad3,
"D", 0, 59, 0,
"%0.2f",
"diameter");
286 indi::addNumberElement<float>( m_indiP_quad3,
"dD", 0, 59, 0,
"%0.2f",
"delta-D");
287 indi::addNumberElement<float>( m_indiP_quad3,
"med", 0, std::numeric_limits<uint16_t>::max(), 0,
"%0.1f",
"flux");
288 indi::addNumberElement<float>( m_indiP_quad3,
"set-x", 0, 59, 0,
"%0.2f",
"set pt. center x");
289 m_indiP_quad3[
"set-x"] = m_setx3;
290 indi::addNumberElement<float>( m_indiP_quad3,
"set-y", 0, 59, 0,
"%0.2f",
"set pt. center x");
291 m_indiP_quad3[
"set-y"] = m_sety3;
292 indi::addNumberElement<float>( m_indiP_quad3,
"set-D", 0, 59, 0,
"%0.2f",
"set pt. diameter");
293 m_indiP_quad3[
"set-D"] = m_setD3;
299 indi::addNumberElement<float>( m_indiP_quad4,
"x", 0, 59, 0,
"%0.2f",
"center x");
300 indi::addNumberElement<float>( m_indiP_quad4,
"dx", 0, 59, 0,
"%0.2f",
"delta-x");
301 indi::addNumberElement<float>( m_indiP_quad4,
"y", 0, 59, 0,
"%0.2f",
"center y");
302 indi::addNumberElement<float>( m_indiP_quad4,
"dy", 0, 59, 0,
"%0.2f",
"delta-y");
303 indi::addNumberElement<float>( m_indiP_quad4,
"D", 0, 59, 0,
"%0.2f",
"diameter");
304 indi::addNumberElement<float>( m_indiP_quad4,
"dD", 0, 59, 0,
"%0.2f",
"delta-D");
305 indi::addNumberElement<float>( m_indiP_quad4,
"med", 0, std::numeric_limits<uint16_t>::max(), 0,
"%0.1f",
"flux");
306 indi::addNumberElement<float>( m_indiP_quad4,
"set-x", 0, 59, 0,
"%0.2f",
"set pt. center x");
307 m_indiP_quad4[
"set-x"] = m_setx4;
308 indi::addNumberElement<float>( m_indiP_quad4,
"set-y", 0, 59, 0,
"%0.2f",
"set pt. center x");
309 m_indiP_quad4[
"set-y"] = m_sety4;
310 indi::addNumberElement<float>( m_indiP_quad4,
"set-D", 0, 59, 0,
"%0.2f",
"set pt. diameter");
311 m_indiP_quad4[
"set-D"] = m_setD4;
316 indi::addNumberElement<float>( m_indiP_avg,
"x", 0, 59, 0,
"%0.2f",
"center x");
317 indi::addNumberElement<float>( m_indiP_avg,
"dx", 0, 59, 0,
"%0.2f",
"delta-x");
318 indi::addNumberElement<float>( m_indiP_avg,
"y", 0, 59, 0,
"%0.2f",
"center y");
319 indi::addNumberElement<float>( m_indiP_avg,
"dy", 0, 59, 0,
"%0.2f",
"delta-y");
320 indi::addNumberElement<float>( m_indiP_avg,
"D", 0, 59, 0,
"%0.2f",
"diameter");
321 indi::addNumberElement<float>( m_indiP_avg,
"dD", 0, 59, 0,
"%0.2f",
"delta-D");
325 m_indiP_reload[
"request"].set(pcf::IndiElement::Off);
328 log<software_error>({__FILE__,__LINE__});
333 m_indiP_update[
"request"].set(pcf::IndiElement::Off);
336 log<software_error>({__FILE__,__LINE__});
372 static_cast<void>(dummy);
377 m_fitter.m_numPupils = m_numPupils;
382 std::string reffits = m_wfsrefPath +
"/" + m_wfsrefName;
384 mx::fits::fitsFile<float> ff;
385 mx::improc::eigenImage<float> refedge;
387 ff.read(m_refIm, reffits);
393 if(m_fitter.fit(m_refIm, refedge) < 0)
395 log<software_error>({__FILE__, __LINE__,
"error from fitter"});
399 m_setx1 = m_fitter.m_avgx[0];
400 m_sety1 = m_fitter.m_avgy[0];
401 m_setD1 = 2*m_fitter.m_avgr[0];
403 m_setx2 = m_fitter.m_avgx[1];
404 m_sety2 = m_fitter.m_avgy[1];
405 m_setD2 = 2*m_fitter.m_avgr[1];
407 m_setx3 = m_fitter.m_avgx[2];
408 m_sety3 = m_fitter.m_avgy[2];
409 m_setD3 = 2*m_fitter.m_avgr[2];
411 m_setx4 = m_fitter.m_avgx[3];
412 m_sety4 = m_fitter.m_avgy[3];
413 m_setD4 = 2*m_fitter.m_avgr[3];
415 log<text_log>(
"Read reference image: " + reffits);
416 log<text_log>(
"Quad 1 set points: " + std::to_string(m_setx1) +
" " + std::to_string(m_sety1) +
" " + std::to_string(m_setD1));
417 log<text_log>(
"Quad 2 set points: " + std::to_string(m_setx2) +
" " + std::to_string(m_sety2) +
" " + std::to_string(m_setD2));
418 log<text_log>(
"Quad 3 set points: " + std::to_string(m_setx3) +
" " + std::to_string(m_sety3) +
" " + std::to_string(m_setD3));
419 log<text_log>(
"Quad 4 set points: " + std::to_string(m_setx4) +
" " + std::to_string(m_sety4) +
" " + std::to_string(m_setD4));
424 log<text_log>(
"Reference image " + reffits +
" size does not match shmim stream.",
logPrio::LOG_ERROR);
429 if(m_numPupils == 4 && !m_refUpdated)
447 else if(!m_refUpdated)
468 if(m_threshShmimConnected)
470 ImageStreamIO_destroyIm( &m_threshShmim );
471 m_threshShmimConnected =
false;
474 if(m_edgeShmimConnected)
476 ImageStreamIO_destroyIm( &m_edgeShmim );
477 m_edgeShmimConnected =
false;
480 ImageStreamIO_createIm_gpu(&m_threshShmim , m_threshShmimName .c_str(), 3, imsize,
m_dataType, -1, 1, IMAGE_NB_SEMAPHORE, 0, CIRCULAR_BUFFER | ZAXIS_TEMPORAL,0);
481 m_threshShmimConnected =
true;
483 ImageStreamIO_createIm_gpu(&m_edgeShmim , m_edgeShmimName .c_str(), 3, imsize,
m_dataType, -1, 1, IMAGE_NB_SEMAPHORE, 0, CIRCULAR_BUFFER | ZAXIS_TEMPORAL,0);
484 m_edgeShmimConnected =
true;
486 if(m_edgeShmimConnected)
498 static_cast<void>(dummy);
502 m_fitIm.data()[nn] += ((
float*)curr_src) [nn];
510 m_fitter.fit(m_fitIm, m_edgeIm);
515 m_indiP_quad1[
"set-x"].set(m_setx1);
516 m_indiP_quad1[
"x"].set(m_fitter.m_avgx[0]);
517 m_indiP_quad1[
"dx"].set(m_fitter.m_avgx[0]-m_setx1);
518 m_indiP_quad1[
"set-y"].set(m_sety1);
519 m_indiP_quad1[
"y"].set(m_fitter.m_avgy[0]);
520 m_indiP_quad1[
"dy"].set(m_fitter.m_avgy[0]-m_sety1);
521 m_indiP_quad1[
"set-D"].set(m_setD1);
522 m_indiP_quad1[
"D"].set(2*m_fitter.m_avgr[0]);
523 m_indiP_quad1[
"dD"].set(2*m_fitter.m_avgr[0]-m_setD1);
524 m_indiP_quad1[
"med"].set(m_fitter.m_med[0]);
528 m_indiP_quad2[
"set-x"].set(m_setx2);
529 m_indiP_quad2[
"x"].set(m_fitter.m_avgx[1]);
530 m_indiP_quad2[
"dx"].set(m_fitter.m_avgx[1]-m_setx2);
531 m_indiP_quad2[
"set-y"].set(m_sety2);
532 m_indiP_quad2[
"y"].set(m_fitter.m_avgy[1]);
533 m_indiP_quad2[
"dy"].set(m_fitter.m_avgy[1]-m_sety2);
534 m_indiP_quad2[
"set-D"].set(m_setD2);
535 m_indiP_quad2[
"D"].set(2*m_fitter.m_avgr[1]);
536 m_indiP_quad2[
"dD"].set(2*m_fitter.m_avgr[1]-m_setD2);
537 m_indiP_quad2[
"med"].set(m_fitter.m_med[1]);
541 m_indiP_quad3[
"set-x"].set(m_setx3);
542 m_indiP_quad3[
"x"].set(m_fitter.m_avgx[2]);
543 m_indiP_quad3[
"dx"].set(m_fitter.m_avgx[2]-m_setx3);
544 m_indiP_quad3[
"set-y"].set(m_sety3);
545 m_indiP_quad3[
"y"].set(m_fitter.m_avgy[2]);
546 m_indiP_quad3[
"dy"].set(m_fitter.m_avgy[2]-m_sety3);
547 m_indiP_quad3[
"set-D"].set(m_setD3);
548 m_indiP_quad3[
"D"].set(2*m_fitter.m_avgr[2]);
549 m_indiP_quad3[
"dD"].set(2*m_fitter.m_avgr[2]-m_setD3);
550 m_indiP_quad3[
"med"].set(m_fitter.m_med[2]);
556 m_indiP_avg[
"x"].set(.333*(m_fitter.m_avgx[0] + m_fitter.m_avgx[1] + m_fitter.m_avgx[2]));
557 m_indiP_avg[
"y"].set(.333*(m_fitter.m_avgy[0] + m_fitter.m_avgy[1] + m_fitter.m_avgy[2]));
558 m_indiP_avg[
"D"].set(.667*(m_fitter.m_avgr[0] + m_fitter.m_avgr[1] + m_fitter.m_avgr[2]));
560 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));
561 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));
562 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));
566 m_indiP_quad4[
"set-x"].set(m_setx4);
567 m_indiP_quad4[
"x"].set(m_fitter.m_avgx[3]);
568 m_indiP_quad4[
"dx"].set(m_fitter.m_avgx[3]-m_setx4);
569 m_indiP_quad4[
"set-y"].set(m_sety4);
570 m_indiP_quad4[
"y"].set(m_fitter.m_avgy[3]);
571 m_indiP_quad4[
"dy"].set(m_fitter.m_avgy[3]-m_sety4);
572 m_indiP_quad4[
"set-D"].set(m_setD4);
573 m_indiP_quad4[
"D"].set(2*m_fitter.m_avgr[3]);
574 m_indiP_quad4[
"dD"].set(2*m_fitter.m_avgr[3]-m_setD4);
575 m_indiP_quad4[
"med"].set(m_fitter.m_med[3]);
579 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]));
580 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]));
581 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]));
583 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));
584 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));
585 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));
597 m_avgx1_accum += m_fitter.m_avgx[0];
598 m_avgx1sq_accum += m_fitter.m_avgx[0]*m_fitter.m_avgx[0];
600 m_avgy1_accum += m_fitter.m_avgy[0];
601 m_avgy1sq_accum += m_fitter.m_avgy[0]*m_fitter.m_avgy[0];
603 m_avgD1_accum += 2*m_fitter.m_avgr[0];
604 m_avgD1sq_accum += 4*m_fitter.m_avgr[0]*m_fitter.m_avgr[0];
606 m_avgmed1_accum += m_fitter.m_med[0];
607 m_avgmed1sq_accum += m_fitter.m_med[0]*m_fitter.m_med[0];
609 m_avgx1 = m_avgx1_accum /
m_navg;
610 m_varx1 = m_avgx1sq_accum /
m_navg - m_avgx1*m_avgx1;
612 m_avgy1 = m_avgy1_accum /
m_navg;
613 m_vary1 = m_avgy1sq_accum /
m_navg - m_avgy1*m_avgy1;
615 m_avgD1 = m_avgD1_accum /
m_navg;
616 m_varD1 = m_avgD1sq_accum /
m_navg - m_avgD1*m_avgD1;
618 m_avgmed1 = m_avgmed1_accum /
m_navg;
619 m_varmed1 = m_avgmed1sq_accum /
m_navg - m_avgmed1*m_avgmed1;
621 m_avgx2_accum += m_fitter.m_avgx[1];
622 m_avgx2sq_accum += m_fitter.m_avgx[1]*m_fitter.m_avgx[1];
624 m_avgy2_accum += m_fitter.m_avgy[1];
625 m_avgy2sq_accum += m_fitter.m_avgy[1]*m_fitter.m_avgy[1];
627 m_avgD2_accum += 2*m_fitter.m_avgr[1];
628 m_avgD2sq_accum += 4*m_fitter.m_avgr[1]*m_fitter.m_avgr[1];
630 m_avgmed2_accum += m_fitter.m_med[1];
631 m_avgmed2sq_accum += m_fitter.m_med[1]*m_fitter.m_med[1];
633 m_avgx2 = m_avgx2_accum /
m_navg;
634 m_varx2 = m_avgx2sq_accum /
m_navg - m_avgx2*m_avgx2;
636 m_avgy2 = m_avgy2_accum /
m_navg;
637 m_vary2 = m_avgy2sq_accum /
m_navg - m_avgy2*m_avgy2;
639 m_avgD2 = m_avgD2_accum /
m_navg;
640 m_varD2 = m_avgD2sq_accum /
m_navg - m_avgD2*m_avgD2;
642 m_avgmed2 = m_avgmed2_accum /
m_navg;
643 m_varmed2 = m_avgmed2sq_accum /
m_navg - m_avgmed2*m_avgmed2;
647 m_avgx3_accum += m_fitter.m_avgx[2];
648 m_avgx3sq_accum += m_fitter.m_avgx[2]*m_fitter.m_avgx[2];
650 m_avgy3_accum += m_fitter.m_avgy[2];
651 m_avgy3sq_accum += m_fitter.m_avgy[2]*m_fitter.m_avgy[2];
653 m_avgD3_accum += 2*m_fitter.m_avgr[2];
654 m_avgD3sq_accum += 4*m_fitter.m_avgr[2]*m_fitter.m_avgr[2];
656 m_avgmed3_accum += m_fitter.m_med[2];
657 m_avgmed3sq_accum += m_fitter.m_med[2]*m_fitter.m_med[2];
659 m_avgx3 = m_avgx3_accum /
m_navg;
660 m_varx3 = m_avgx3sq_accum /
m_navg - m_avgx3*m_avgx3;
662 m_avgy3 = m_avgy3_accum /
m_navg;
663 m_vary3 = m_avgy3sq_accum /
m_navg - m_avgy3*m_avgy3;
665 m_avgD3 = m_avgD3_accum /
m_navg;
666 m_varD3 = m_avgD3sq_accum /
m_navg - m_avgD3*m_avgD3;
668 m_avgmed3 = m_avgmed3_accum /
m_navg;
669 m_varmed3 = m_avgmed3sq_accum /
m_navg - m_avgmed3*m_avgmed3;
673 double tmp = 0.333*(m_fitter.m_avgx[0]+m_fitter.m_avgx[1]+m_fitter.m_avgx[2]+m_fitter.m_avgx[3]);
674 m_avgxAll_accum += tmp;
675 m_avgxAllsq_accum += tmp*tmp;
677 tmp = 0.333*(m_fitter.m_avgy[0]+m_fitter.m_avgy[1]+m_fitter.m_avgy[2]);
678 m_avgyAll_accum += tmp;
679 m_avgyAllsq_accum += tmp*tmp;
681 tmp = 2*0.333*(m_fitter.m_avgr[0]+m_fitter.m_avgr[1]+m_fitter.m_avgr[2]);
682 m_avgDAll_accum += tmp;
683 m_avgDAllsq_accum += tmp*tmp;
685 tmp = 0.333*(m_fitter.m_med[0]+m_fitter.m_med[1]+m_fitter.m_med[2]);
686 m_avgmedAll_accum += tmp;
687 m_avgmedAllsq_accum += tmp*tmp;
689 m_avgxAll = m_avgxAll_accum /
m_navg;
690 m_varxAll = m_avgxAllsq_accum /
m_navg - m_avgxAll*m_avgxAll;
692 m_avgyAll = m_avgyAll_accum /
m_navg;
693 m_varyAll = m_avgyAllsq_accum /
m_navg - m_avgyAll*m_avgyAll;
695 m_avgDAll = m_avgDAll_accum /
m_navg;
696 m_varDAll = m_avgDAllsq_accum /
m_navg - m_avgDAll*m_avgDAll;
698 m_avgmedAll = m_avgmedAll_accum /
m_navg;
699 m_varmedAll = m_avgmedAllsq_accum /
m_navg - m_avgmedAll*m_avgmedAll;
702 std::cerr <<
"****************************************************************\n";
704 std::cerr <<
"Average x1: " << m_avgx1 <<
" +/- " << sqrt(m_varx1) <<
"\n";
705 std::cerr <<
"Average y1: " << m_avgy1 <<
" +/- " << sqrt(m_vary1) <<
"\n";
706 std::cerr <<
"Average D1: " << m_avgD1 <<
" +/- " << sqrt(m_varD1) <<
"\n";
707 std::cerr <<
"Average med1: " << m_avgmed1 <<
" +/- " << sqrt(m_varmed1) <<
"\n\n";
708 std::cerr <<
"Average x2: " << m_avgx2 <<
" +/- " << sqrt(m_varx2) <<
"\n";
709 std::cerr <<
"Average y2: " << m_avgy2 <<
" +/- " << sqrt(m_vary2) <<
"\n";
710 std::cerr <<
"Average D2: " << m_avgD2 <<
" +/- " << sqrt(m_varD2) <<
"\n";
711 std::cerr <<
"Average med2: " << m_avgmed2 <<
" +/- " << sqrt(m_varmed2) <<
"\n\n";
712 std::cerr <<
"Average x3: " << m_avgx3 <<
" +/- " << sqrt(m_varx3) <<
"\n";
713 std::cerr <<
"Average y3: " << m_avgy3 <<
" +/- " << sqrt(m_vary3) <<
"\n";
714 std::cerr <<
"Average D3: " << m_avgD3 <<
" +/- " << sqrt(m_varD3) <<
"\n";
715 std::cerr <<
"Average med3: " << m_avgmed3 <<
" +/- " << sqrt(m_varmed3) <<
"\n\n";
716 std::cerr <<
"Average xAll: " << m_avgxAll <<
" +/- " << sqrt(m_varxAll) <<
"\n";
717 std::cerr <<
"Average yAll: " << m_avgyAll <<
" +/- " << sqrt(m_varyAll) <<
"\n";
718 std::cerr <<
"Average DAll: " << m_avgDAll <<
" +/- " << sqrt(m_varDAll) <<
"\n";
719 std::cerr <<
"Average medAll: " << m_avgmedAll <<
" +/- " << sqrt(m_varmedAll) <<
"\n\n";
723 m_avgx4_accum += m_fitter.m_avgx[3];
724 m_avgx4sq_accum += m_fitter.m_avgx[3]*m_fitter.m_avgx[3];
726 m_avgy4_accum += m_fitter.m_avgy[3];
727 m_avgy4sq_accum += m_fitter.m_avgy[3]*m_fitter.m_avgy[3];
729 m_avgD4_accum += 2*m_fitter.m_avgr[3];
730 m_avgD4sq_accum += 4*m_fitter.m_avgr[3]*m_fitter.m_avgr[3];
732 m_avgmed4_accum += m_fitter.m_med[3];
733 m_avgmed4sq_accum += m_fitter.m_med[3]*m_fitter.m_med[3];
735 m_avgx4 = m_avgx4_accum /
m_navg;
736 m_varx4 = m_avgx4sq_accum /
m_navg - m_avgx4*m_avgx4;
738 m_avgy4 = m_avgy4_accum /
m_navg;
739 m_vary4 = m_avgy4sq_accum /
m_navg - m_avgy4*m_avgy4;
741 m_avgD4 = m_avgD4_accum /
m_navg;
742 m_varD4 = m_avgD4sq_accum /
m_navg - m_avgD4*m_avgD4;
744 m_avgmed4 = m_avgmed4_accum /
m_navg;
745 m_varmed4 = m_avgmed4sq_accum /
m_navg - m_avgmed4*m_avgmed4;
748 double tmp = 0.25*(m_fitter.m_avgx[0]+m_fitter.m_avgx[1]+m_fitter.m_avgx[2]+m_fitter.m_avgx[3]);
749 m_avgxAll_accum += tmp;
750 m_avgxAllsq_accum += tmp*tmp;
752 tmp = 0.25*(m_fitter.m_avgy[0]+m_fitter.m_avgy[1]+m_fitter.m_avgy[2]+m_fitter.m_avgy[3]);
753 m_avgyAll_accum += tmp;
754 m_avgyAllsq_accum += tmp*tmp;
756 tmp = 2*0.25*(m_fitter.m_avgr[0]+m_fitter.m_avgr[1]+m_fitter.m_avgr[2]+m_fitter.m_avgr[3]);
757 m_avgDAll_accum += tmp;
758 m_avgDAllsq_accum += tmp*tmp;
760 tmp = 0.25*(m_fitter.m_med[0]+m_fitter.m_med[1]+m_fitter.m_med[2]+m_fitter.m_med[3]);
761 m_avgmedAll_accum += tmp;
762 m_avgmedAllsq_accum += tmp*tmp;
764 m_avgxAll = m_avgxAll_accum /
m_navg;
765 m_varxAll = m_avgxAllsq_accum /
m_navg - m_avgxAll*m_avgxAll;
767 m_avgyAll = m_avgyAll_accum /
m_navg;
768 m_varyAll = m_avgyAllsq_accum /
m_navg - m_avgyAll*m_avgyAll;
770 m_avgDAll = m_avgDAll_accum /
m_navg;
771 m_varDAll = m_avgDAllsq_accum /
m_navg - m_avgDAll*m_avgDAll;
773 m_avgmedAll = m_avgmedAll_accum /
m_navg;
774 m_varmedAll = m_avgmedAllsq_accum /
m_navg - m_avgmedAll*m_avgmedAll;
777 std::cerr <<
"****************************************************************\n";
779 std::cerr <<
"Average x1: " << m_avgx1 <<
" +/- " << sqrt(m_varx1) <<
"\n";
780 std::cerr <<
"Average y1: " << m_avgy1 <<
" +/- " << sqrt(m_vary1) <<
"\n";
781 std::cerr <<
"Average D1: " << m_avgD1 <<
" +/- " << sqrt(m_varD1) <<
"\n";
782 std::cerr <<
"Average med1: " << m_avgmed1 <<
" +/- " << sqrt(m_varmed1) <<
"\n\n";
783 std::cerr <<
"Average x2: " << m_avgx2 <<
" +/- " << sqrt(m_varx2) <<
"\n";
784 std::cerr <<
"Average y2: " << m_avgy2 <<
" +/- " << sqrt(m_vary2) <<
"\n";
785 std::cerr <<
"Average D2: " << m_avgD2 <<
" +/- " << sqrt(m_varD2) <<
"\n";
786 std::cerr <<
"Average med2: " << m_avgmed2 <<
" +/- " << sqrt(m_varmed2) <<
"\n\n";
787 std::cerr <<
"Average x3: " << m_avgx3 <<
" +/- " << sqrt(m_varx3) <<
"\n";
788 std::cerr <<
"Average y3: " << m_avgy3 <<
" +/- " << sqrt(m_vary3) <<
"\n";
789 std::cerr <<
"Average D3: " << m_avgD3 <<
" +/- " << sqrt(m_varD3) <<
"\n";
790 std::cerr <<
"Average med3: " << m_avgmed3 <<
" +/- " << sqrt(m_varmed3) <<
"\n\n";
791 std::cerr <<
"Average x4: " << m_avgx4 <<
" +/- " << sqrt(m_varx4) <<
"\n";
792 std::cerr <<
"Average y4: " << m_avgy4 <<
" +/- " << sqrt(m_vary4) <<
"\n";
793 std::cerr <<
"Average D4: " << m_avgD4 <<
" +/- " << sqrt(m_varD4) <<
"\n";
794 std::cerr <<
"Average med4: " << m_avgmed4 <<
" +/- " << sqrt(m_varmed4) <<
"\n\n";
795 std::cerr <<
"Average xAll: " << m_avgxAll <<
" +/- " << sqrt(m_varxAll) <<
"\n";
796 std::cerr <<
"Average yAll: " << m_avgyAll <<
" +/- " << sqrt(m_varyAll) <<
"\n";
797 std::cerr <<
"Average DAll: " << m_avgDAll <<
" +/- " << sqrt(m_varDAll) <<
"\n";
798 std::cerr <<
"Average medAll: " << m_avgmedAll <<
" +/- " << sqrt(m_varmedAll) <<
"\n\n";
802 m_threshShmim.md->write=1;
803 m_edgeShmim.md->write=1;
805 clock_gettime(CLOCK_REALTIME, &m_threshShmim.md->writetime);
806 m_edgeShmim.md->writetime = m_threshShmim.md->writetime;
808 m_threshShmim.md->atime = m_threshShmim.md->writetime;
809 m_edgeShmim.md->atime = m_threshShmim.md->writetime;
811 m_threshShmim.md->cnt0++;
812 m_edgeShmim.md->cnt0++;
814 memcpy(m_threshShmim.array.raw, m_fitIm.data(), m_fitIm.rows()*m_fitIm.cols()*
sizeof(
float));
815 memcpy(m_edgeShmim.array.raw, m_edgeIm.data(), m_edgeIm.rows()*m_edgeIm.cols()*
sizeof(
float));
817 m_threshShmim.md->write=0;
818 m_edgeShmim.md->write=0;
820 ImageStreamIO_sempost(&m_threshShmim,-1);
821 ImageStreamIO_sempost(&m_edgeShmim,-1);
829 if(
ipRecv.getName() != m_indiP_thresh.getName())
831 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
839 log<software_error>({__FILE__,__LINE__});
853 if(
ipRecv.getName() != m_indiP_averaging.getName())
855 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
861 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
873 m_avgmed1sq_accum = 0;
882 m_avgmed2sq_accum = 0;
891 m_avgmed3sq_accum = 0;
900 m_avgmed4sq_accum = 0;
903 m_avgxAllsq_accum = 0;
905 m_avgyAllsq_accum = 0;
907 m_avgDAllsq_accum = 0;
908 m_avgmedAll_accum = 0;
909 m_avgmedAllsq_accum = 0;
913 log<text_log>(
"began averaging");
916 else if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off)
921 log<text_log>(
"stopped averaging");
929 if(
ipRecv.getName() != m_indiP_reload.getName())
931 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
937 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
939 log<text_log>(
"reloading");
948 if(
ipRecv.getName() != m_indiP_update.getName())
950 log<software_error>({__FILE__,__LINE__,
"wrong INDI property received."});
956 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
960 log<text_log>(
"updating cal");
961 m_setx1 = m_indiP_quad1[
"x"].get<
float>();
962 m_sety1 = m_indiP_quad1[
"y"].get<
float>();
963 m_setD1 = m_indiP_quad1[
"D"].get<
float>();
965 m_setx2 = m_indiP_quad2[
"x"].get<
float>();
966 m_sety2 = m_indiP_quad2[
"y"].get<
float>();
967 m_setD2 = m_indiP_quad2[
"D"].get<
float>();
969 m_setx3 = m_indiP_quad3[
"x"].get<
float>();
970 m_sety3 = m_indiP_quad3[
"y"].get<
float>();
971 m_setD3 = m_indiP_quad3[
"D"].get<
float>();
975 m_setx4 = m_indiP_quad4[
"x"].get<
float>();
976 m_sety4 = m_indiP_quad4[
"y"].get<
float>();
977 m_setD4 = m_indiP_quad4[
"D"].get<
float>();
The base-class for MagAO-X applications.
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.
int createStandardIndiRequestSw(pcf::IndiProperty &prop, const std::string &name, const std::string &label="", const std::string &group="")
Create a standard R/W INDI switch with a single request element.
stateCodes::stateCodeT state()
Get the current state code.
int registerIndiPropertyNew(pcf::IndiProperty &prop, int(*)(void *, const pcf::IndiProperty &))
Register an INDI property which is exposed for others to request a New Property for.
int createStandardIndiToggleSw(pcf::IndiProperty &prop, const std::string &name, const std::string &label="", const std::string &group="")
Create a standard R/W INDI switch with a single toggle element.
indiDriver< MagAOXApp > * m_indiDriver
The INDI driver wrapper. Constructed and initialized by execute, which starts and stops communication...
void updateSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, const pcf::IndiElement::SwitchStateType &newVal, pcf::IndiProperty::PropertyStateType ipState=pcf::IndiProperty::Ok)
Update an INDI switch element value if it has changed.
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.
int indiTargetUpdate(pcf::IndiProperty &localProperty, T &localTarget, const pcf::IndiProperty &remoteProperty, bool setBusy=true)
Get the target element value from an new property.
int appStartup()
Startup function.
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.
std::string m_shmimName
The name of the shared memory image, is used in /tmp/<shmimName>.im.shm. Derived classes should set a...
int appShutdown()
Shuts down the shmimMonitor thread.
uint8_t m_dataType
The ImageStreamIO type code.
bool m_restart
Flag indicating tha the shared memory should be reinitialized.
int loadConfig(mx::app::appConfigurator &config)
load the configuration system results
The MagAO-X Pyramid Pupil Fitter.
pcf::IndiProperty m_indiP_takeTgt
std::string m_darkShmimName
The name of the dark shared memory stream. Default is <m_pupilShmimName>_dark.
~pupilAlign() noexcept
D'tor, declared and defined for noexcept.
bool m_tgtPupSubShmimConnected
virtual void loadConfig()
pcf::IndiProperty m_indiP_takePupil
virtual int appLogic()
Implementation of the FSM for pupilAlign.
int allocate(const dev::shmimT &)
int m_navg
Number of images to average. Default is 10.
int processImage(void *curr_src, const dev::shmimT &)
virtual void setupConfig()
mx::improc::eigenImage< float > m_pupIm
mx::improc::eigenImage< float > m_darkIm
std::vector< pixelT > srcPos
pupilAlign()
Default c'tor.
virtual int appShutdown()
Shutdown the app.
mx::improc::sourceFinder< float >::pixelT pixelT
mx::improc::eigenImage< float > m_tgtIm
dev::shmimMonitor< pupilAlign > shmimMonitorT
mx::improc::sourceFinder< float > m_srcFind
friend class pupilAlign_test
virtual int appStartup()
Startup function.
float m_threshold
The default SNR threshold for finding the pupil.
mx::improc::eigenImage< float > m_tgtPupSubIm
float realT
Floating point type in which to do all calculations.
int loadConfigImpl(mx::app::appConfigurator &_config)
Implementation of loadConfig logic, separated for testing.
pcf::IndiProperty m_indiP_navg
pcf::IndiProperty m_indiP_tgtCoords
std::string m_pupilShmimName
The name of the pupil shared memory image.
INDI_NEWCALLBACK_DECL(pupilAlign, m_indiP_navg)
pcf::IndiProperty m_indiP_threshold
#define INDI_NEWCALLBACK(prop)
Get the name of the static callback wrapper for a new property.
@ OPERATING
The device is operating, other than homing.
const pcf::IndiProperty & ipRecv
INDI_NEWCALLBACK_DEFN(acesxeCtrl, m_indiP_windspeed)(const pcf
constexpr static logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
constexpr static logPrioT LOG_NOTICE
A normal but significant condition.