LCOV - code coverage report
Current view: top level - apps/pwfsSlopeCalc - pwfsSlopeCalc.hpp (source / functions) Coverage Total Hit
Test: MagAOX Lines: 0.0 % 268 0
Test Date: 2026-01-03 21:03:39 Functions: 0.0 % 29 0

            Line data    Source code
       1              : /** \file pwfsSlopeCalc.hpp
       2              :   * \brief The MagAO-X PWFS Slope Calculator
       3              :   *
       4              :   * \ingroup app_files
       5              :   */
       6              : 
       7              : #ifndef pwfsSlopeCalc_hpp
       8              : #define pwfsSlopeCalc_hpp
       9              : 
      10              : #include <limits>
      11              : 
      12              : #include <mx/improc/eigenCube.hpp>
      13              : #include <mx/improc/eigenImage.hpp>
      14              : using namespace mx::improc;
      15              : 
      16              : #include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
      17              : #include "../../magaox_git_version.h"
      18              : 
      19              : namespace MagAOX
      20              : {
      21              : namespace app
      22              : {
      23              : 
      24              : struct darkShmimT
      25              : {
      26            0 :    static std::string configSection()
      27              :    {
      28            0 :       return "darkShmim";
      29              :    };
      30              : 
      31            0 :    static std::string indiPrefix()
      32              :    {
      33            0 :       return "dark";
      34              :    };
      35              : };
      36              : 
      37              : 
      38              : /** \defgroup pwfsSlopeCalc PWFS Slope Calculator
      39              :   * \brief Calculates slopes from a PWFS image.
      40              :   *
      41              :   * <a href="../handbook/operating/software/apps/pwfsSlopeCalc.html">Application Documentation</a>
      42              :   *
      43              :   * \ingroup apps
      44              :   *
      45              :   */
      46              : 
      47              : /** \defgroup pwfsSlopeCalc_files PWFS Slope Calculator Files
      48              :   * \ingroup pwfsSlopeCalc
      49              :   */
      50              : 
      51              : /** MagAO-X application to calculate slopes from PWFS images.
      52              :   *
      53              :   * \ingroup pwfsSlopeCalc
      54              :   *
      55              :   */
      56              : class pwfsSlopeCalc : public MagAOXApp<true>, public dev::shmimMonitor<pwfsSlopeCalc>, public dev::shmimMonitor<pwfsSlopeCalc,darkShmimT>, public dev::frameGrabber<pwfsSlopeCalc>, public dev::telemeter<pwfsSlopeCalc>
      57              : {
      58              : 
      59              :    //Give the test harness access.
      60              :    friend class pwfsSlopeCalc_test;
      61              : 
      62              :    friend class dev::shmimMonitor<pwfsSlopeCalc>;
      63              :    friend class dev::shmimMonitor<pwfsSlopeCalc,darkShmimT>;
      64              :    friend class dev::frameGrabber<pwfsSlopeCalc>;
      65              :    friend class dev::telemeter<pwfsSlopeCalc>;
      66              : 
      67              :    //The base shmimMonitor type
      68              :    typedef dev::shmimMonitor<pwfsSlopeCalc> shmimMonitorT;
      69              : 
      70              :    //The dark shmimMonitor type
      71              :    typedef dev::shmimMonitor<pwfsSlopeCalc, darkShmimT> darkMonitorT;
      72              : 
      73              :    //The base frameGrabber type
      74              :    typedef dev::frameGrabber<pwfsSlopeCalc> frameGrabberT;
      75              : 
      76              :    //The base telemeter type
      77              :    typedef dev::telemeter<pwfsSlopeCalc> telemeterT;
      78              : 
      79              :    ///Floating point type in which to do all calculations.
      80              :    typedef float realT;
      81              : 
      82              :    static constexpr bool c_frameGrabber_flippable = false; ///< app:dev config to tell framegrabber these images can not be flipped
      83              : 
      84              : protected:
      85              : 
      86              :    /** \name Configurable Parameters
      87              :      *@{
      88              :      */
      89              : 
      90              :    std::string m_fitter; ///< Device name of the pupil fitter process. If set, the number of pupils
      91              :    int m_numPupils {4};
      92              : 
      93              :    float m_pupil_cx_1; ///< the center x coordinate of pupil 1
      94              :    float m_pupil_cy_1; ///< the center y coordinate of pupil 1
      95              :    float m_pupil_D_1 {0}; ///< the diameter of pupil 1, used only for averaging the fitter output
      96              : 
      97              :    float m_pupil_cx_2; ///< the center x coordinate of pupil 2
      98              :    float m_pupil_cy_2; ///< the center y coordinate of pupil 2
      99              :    float m_pupil_D_2 {0}; ///< the diameter of pupil 2, used only for averaging the fitter output
     100              : 
     101              :    float m_pupil_cx_3; ///< the center x coordinate of pupil 3
     102              :    float m_pupil_cy_3; ///< the center y coordinate of pupil 3
     103              :    float m_pupil_D_3 {0}; ///< the diameter of pupil 3, used only for averaging the fitter output
     104              : 
     105              :    float m_pupil_cx_4; ///< the center x coordinate of pupil 4
     106              :    float m_pupil_cy_4; ///< the center y coordinate of pupil 4
     107              :    float m_pupil_D_4 {0}; ///< the diameter of pupil 4, used only for averaging the fitter output
     108              : 
     109              :    int m_pupil_D {56}; ///< the pupil diameter, just one applied to all pupils.
     110              : 
     111              :    int m_pupil_buffer {1}; ///< the edge buffer for the pupils, just one applied to all pupils.  Default is 1.
     112              : 
     113              :    ///@}
     114              : 
     115              :    sem_t m_smSemaphore; ///< Semaphore used to synchronize the fg thread and the sm thread.
     116              : 
     117              :    realT (*pixget)(void *, size_t) {nullptr}; ///< Pointer to a function to extract the image data as our desired type realT.
     118              : 
     119              :    void * m_curr_src {nullptr};
     120              : 
     121              :    int m_quadSize {60};
     122              : 
     123              :    mx::improc::eigenImage<realT> m_darkImage;
     124              :    realT (*dark_pixget)(void *, size_t) {nullptr}; ///< Pointer to a function to extract the image data as our desired type realT.
     125              :    bool m_darkSet {false};
     126              : 
     127              :    int m_pupil_sx_1; ///< the starting x-coordinate of pupil 1 quadrant, calculated from the pupil center, diameter, and buffer.
     128              :    int m_pupil_sy_1; ///< the starting y-coordinate of pupil 1 quadrant, calculated from the pupil center, diameter, and buffer.
     129              : 
     130              :    int m_pupil_sx_2; ///< the starting x-coordinate of pupil 2 quadrant, calculated from the pupil center, diameter, and buffer.
     131              :    int m_pupil_sy_2; ///< the starting y-coordinate of pupil 2 quadrant, calculated from the pupil center, diameter, and buffer.
     132              : 
     133              :    int m_pupil_sx_3; ///< the starting x-coordinate of pupil 3 quadrant, calculated from the pupil center, diameter, and buffer.
     134              :    int m_pupil_sy_3; ///< the starting y-coordinate of pupil 3 quadrant, calculated from the pupil center, diameter, and buffer.
     135              : 
     136              :    int m_pupil_sx_4; ///< the starting x-coordinate of pupil 4 quadrant, calculated from the pupil center, diameter, and buffer.
     137              :    int m_pupil_sy_4; ///< the starting y-coordinate of pupil 4 quadrant, calculated from the pupil center, diameter, and buffer.
     138              : 
     139              : public:
     140              :    /// Default c'tor.
     141              :    pwfsSlopeCalc();
     142              : 
     143              :    /// D'tor, declared and defined for noexcept.
     144            0 :    ~pwfsSlopeCalc() noexcept
     145            0 :    {}
     146              : 
     147              :    virtual void setupConfig();
     148              : 
     149              :    /// Implementation of loadConfig logic, separated for testing.
     150              :    /** This is called by loadConfig().
     151              :      */
     152              :    int loadConfigImpl( mx::app::appConfigurator & _config /**< [in] an application configuration from which to load values*/);
     153              : 
     154              :    virtual void loadConfig();
     155              : 
     156              :    /// Startup function
     157              :    /**
     158              :      *
     159              :      */
     160              :    virtual int appStartup();
     161              : 
     162              :    /// Implementation of the FSM for pwfsSlopeCalc.
     163              :    /**
     164              :      * \returns 0 on no critical error
     165              :      * \returns -1 on an error requiring shutdown
     166              :      */
     167              :    virtual int appLogic();
     168              : 
     169              :    /// Shutdown the app.
     170              :    /**
     171              :      *
     172              :      */
     173              :    virtual int appShutdown();
     174              : 
     175              :    int allocate( const dev::shmimT & dummy /**< [in] tag to differentiate shmimMonitor parents.*/);
     176              : 
     177              :    int processImage( void * curr_src,          ///< [in] pointer to start of current frame.
     178              :                      const dev::shmimT & dummy ///< [in] tag to differentiate shmimMonitor parents.
     179              :                    );
     180              : 
     181              :    int allocate( const darkShmimT & dummy /**< [in] tag to differentiate shmimMonitor parents.*/);
     182              : 
     183              :    int processImage( void * curr_src,          ///< [in] pointer to start of current frame.
     184              :                      const darkShmimT & dummy ///< [in] tag to differentiate shmimMonitor parents.
     185              :                    );
     186              : 
     187            0 :    float fps()
     188              :    {
     189            0 :       return 250;
     190              :    }
     191              : 
     192              : protected:
     193              : 
     194              :    /** \name dev::frameGrabber interface
     195              :      *
     196              :      * @{
     197              :      */
     198              : 
     199              :    /// Implementation of the framegrabber configureAcquisition interface
     200              :    /**
     201              :      * \returns 0 on success
     202              :      * \returns -1 on error
     203              :      */
     204              :    int configureAcquisition();
     205              : 
     206              :    /// Implementation of the framegrabber startAcquisition interface
     207              :    /**
     208              :      * \returns 0 on success
     209              :      * \returns -1 on error
     210              :      */
     211              :    int startAcquisition();
     212              : 
     213              :    /// Implementation of the framegrabber acquireAndCheckValid interface
     214              :    /**
     215              :      * \returns 0 on success
     216              :      * \returns -1 on error
     217              :      */
     218              :    int acquireAndCheckValid();
     219              : 
     220              :    /// Implementation of the framegrabber loadImageIntoStream interface
     221              :    /**
     222              :      * \returns 0 on success
     223              :      * \returns -1 on error
     224              :      */
     225              :    int loadImageIntoStream( void * dest  /**< [in] */);
     226              : 
     227              :    /// Implementation of the framegrabber reconfig interface
     228              :    /**
     229              :      * \returns 0 on success
     230              :      * \returns -1 on error
     231              :      */
     232              :    int reconfig();
     233              : 
     234              :    ///@}
     235              : 
     236              :    pcf::IndiProperty m_indiP_quad1;
     237              :    pcf::IndiProperty m_indiP_quad2;
     238              :    pcf::IndiProperty m_indiP_quad3;
     239              :    pcf::IndiProperty m_indiP_quad4;
     240              : 
     241              : public:
     242            0 :    INDI_SETCALLBACK_DECL(pwfsSlopeCalc, m_indiP_quad1);
     243            0 :    INDI_SETCALLBACK_DECL(pwfsSlopeCalc, m_indiP_quad2);
     244            0 :    INDI_SETCALLBACK_DECL(pwfsSlopeCalc, m_indiP_quad3);
     245            0 :    INDI_SETCALLBACK_DECL(pwfsSlopeCalc, m_indiP_quad4);
     246              : 
     247              :    /** \name Telemeter Interface
     248              :      *
     249              :      * @{
     250              :      */
     251              :    int checkRecordTimes();
     252              : 
     253              :    int recordTelem( const telem_fgtimings * );
     254              : 
     255              :    ///@}
     256              : };
     257              : 
     258              : 
     259              : inline
     260              : pwfsSlopeCalc::pwfsSlopeCalc() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
     261              : {
     262              :    darkMonitorT::m_getExistingFirst = true;
     263              :    return;
     264              : }
     265              : 
     266              : inline
     267            0 : void pwfsSlopeCalc::setupConfig()
     268              : {
     269            0 :    shmimMonitorT::setupConfig(config);
     270            0 :    darkMonitorT::setupConfig(config);
     271              : 
     272            0 :    frameGrabberT::setupConfig(config);
     273            0 :    telemeterT::setupConfig(config);
     274              : 
     275            0 :    config.add("pupil.fitter", "", "pupil.fitter", argType::Required, "pupil", "fitter", false, "int", "The device name of the pupil fitter.  If set, then pupil position is set by the fitter reference.");
     276              : 
     277            0 :    config.add("pupil.D", "", "pupil.D", argType::Required, "pupil", "D", false, "int", "The diameter of the pupils, fixed. Default is 56.");
     278              : 
     279            0 :    config.add("pupil.buffer", "", "pupil.buffer", argType::Required, "pupil", "buffer", false, "int", "The edge buffer for the pupils.  Default is 1.");
     280              : 
     281            0 :    config.add("pupil.numPupils", "", "pupil.numPupils", argType::Required, "pupil", "numPupils", false, "int", "The number of pupils.  Default is 4.  3 is also supported.");
     282              : 
     283              : 
     284              : 
     285            0 :    config.add("pupil.cx_1", "", "pupil.cx_1", argType::Required, "pupil", "cx_1", false, "int", "The default x-coordinate of pupil 1 (LL).  Can be updated from real-time fitter.");
     286            0 :    config.add("pupil.cy_1", "", "pupil.cy_1", argType::Required, "pupil", "cy_1", false, "int", "The default y-coordinate of pupil 1 (LL).  Can be updated from real-time fitter.");
     287              : 
     288            0 :    config.add("pupil.cx_2", "", "pupil.cx_2", argType::Required, "pupil", "cx_2", false, "int", "The default x-coordinate of pupil 2 (LL).  Can be updated from real-time fitter.");
     289            0 :    config.add("pupil.cy_2", "", "pupil.cy_2", argType::Required, "pupil", "cy_2", false, "int", "The default y-coordinate of pupil 2 (LL).  Can be updated from real-time fitter.");
     290              : 
     291            0 :    config.add("pupil.cx_3", "", "pupil.cx_3", argType::Required, "pupil", "cx_3", false, "int", "The default x-coordinate of pupil 3 (LL).  Can be updated from real-time fitter.");
     292            0 :    config.add("pupil.cy_3", "", "pupil.cy_3", argType::Required, "pupil", "cy_3", false, "int", "The default y-coordinate of pupil 3 (LL).  Can be updated from real-time fitter.");
     293              : 
     294            0 :    config.add("pupil.cx_4", "", "pupil.cx_4", argType::Required, "pupil", "cx_4", false, "int", "The default x-coordinate of pupil 4 (LL).  Can be updated from real-time fitter.");
     295            0 :    config.add("pupil.cy_4", "", "pupil.cy_4", argType::Required, "pupil", "cy_4", false, "int", "The default y-coordinate of pupil 4 (LL).  Can be updated from real-time fitter.");
     296            0 : }
     297              : 
     298              : inline
     299            0 : int pwfsSlopeCalc::loadConfigImpl( mx::app::appConfigurator & _config )
     300              : {
     301              : 
     302            0 :    shmimMonitorT::loadConfig(_config);
     303            0 :    darkMonitorT::loadConfig(_config);
     304            0 :    frameGrabberT::loadConfig(_config);
     305            0 :    telemeterT::loadConfig(_config);
     306              : 
     307            0 :    config(m_fitter, "pupil.fitter");
     308            0 :    config(m_numPupils, "pupil.numPupils");
     309            0 :    config(m_pupil_D, "pupil.D");
     310            0 :    config(m_pupil_buffer, "pupil.buffer");
     311            0 :    config(m_pupil_cx_1, "pupil.cx_1");
     312            0 :    config(m_pupil_cy_1, "pupil.cy_1");
     313            0 :    config(m_pupil_cx_2, "pupil.cx_2");
     314            0 :    config(m_pupil_cy_2, "pupil.cy_2");
     315            0 :    config(m_pupil_cx_3, "pupil.cx_3");
     316            0 :    config(m_pupil_cy_3, "pupil.cy_3");
     317            0 :    config(m_pupil_cx_4, "pupil.cx_4");
     318            0 :    config(m_pupil_cy_4, "pupil.cy_4");
     319            0 :    return 0;
     320              : }
     321              : 
     322              : inline
     323            0 : void pwfsSlopeCalc::loadConfig()
     324              : {
     325            0 :    loadConfigImpl(config);
     326            0 : }
     327              : 
     328              : inline
     329            0 : int pwfsSlopeCalc::appStartup()
     330              : {
     331            0 :    if(sem_init(&m_smSemaphore, 0,0) < 0)
     332              :    {
     333            0 :       log<software_critical>({__FILE__, __LINE__, errno,0, "Initializing S.M. semaphore"});
     334            0 :       return -1;
     335              :    }
     336              : 
     337            0 :    if(shmimMonitorT::appStartup() < 0)
     338              :    {
     339            0 :       return log<software_error,-1>({__FILE__, __LINE__});
     340              :    }
     341              : 
     342            0 :    if(darkMonitorT::appStartup() < 0)
     343              :    {
     344            0 :       return log<software_error,-1>({__FILE__, __LINE__});
     345              :    }
     346              : 
     347            0 :    if(frameGrabberT::appStartup() < 0)
     348              :    {
     349            0 :       return log<software_error,-1>({__FILE__, __LINE__});
     350              :    }
     351              : 
     352            0 :    if(telemeterT::appStartup() < 0)
     353              :    {
     354            0 :       return log<software_error,-1>({__FILE__, __LINE__});
     355              :    }
     356              : 
     357            0 :    if(m_fitter != "")
     358              :    {
     359            0 :       REG_INDI_SETPROP(m_indiP_quad1, m_fitter, "quadrant1");
     360            0 :       REG_INDI_SETPROP(m_indiP_quad2, m_fitter, "quadrant2");
     361            0 :       REG_INDI_SETPROP(m_indiP_quad3, m_fitter, "quadrant3");
     362            0 :       if(m_numPupils == 4)
     363              :       {
     364            0 :          REG_INDI_SETPROP(m_indiP_quad4, m_fitter, "quadrant4");
     365              :       }
     366              :    }
     367              : 
     368            0 :    state(stateCodes::OPERATING);
     369              : 
     370            0 :    return 0;
     371              : }
     372              : 
     373              : inline
     374            0 : int pwfsSlopeCalc::appLogic()
     375              : {
     376            0 :    if( shmimMonitorT::appLogic() < 0)
     377              :    {
     378            0 :       return log<software_error,-1>({__FILE__,__LINE__});
     379              :    }
     380              : 
     381            0 :    if( darkMonitorT::appLogic() < 0)
     382              :    {
     383            0 :       return log<software_error,-1>({__FILE__,__LINE__});
     384              :    }
     385              : 
     386              : 
     387            0 :    if( frameGrabberT::appLogic() < 0)
     388              :    {
     389            0 :       return log<software_error,-1>({__FILE__,__LINE__});
     390              :    }
     391              : 
     392            0 :    if( telemeterT::appLogic() < 0)
     393              :    {
     394            0 :       return log<software_error,-1>({__FILE__,__LINE__});
     395              :    }
     396              : 
     397            0 :    std::unique_lock<std::mutex> lock(m_indiMutex);
     398              : 
     399            0 :    if(shmimMonitorT::updateINDI() < 0)
     400              :    {
     401            0 :       log<software_error>({__FILE__, __LINE__});
     402              :    }
     403              : 
     404            0 :    if(darkMonitorT::updateINDI() < 0)
     405              :    {
     406            0 :       log<software_error>({__FILE__, __LINE__});
     407              :    }
     408              : 
     409            0 :    if(frameGrabberT::updateINDI() < 0)
     410              :    {
     411            0 :       log<software_error>({__FILE__, __LINE__});
     412              :    }
     413              : 
     414              : 
     415              : 
     416              : 
     417            0 :    return 0;
     418            0 : }
     419              : 
     420              : inline
     421            0 : int pwfsSlopeCalc::appShutdown()
     422              : {
     423            0 :    shmimMonitorT::appShutdown();
     424              : 
     425            0 :    darkMonitorT::appShutdown();
     426              : 
     427            0 :    frameGrabberT::appShutdown();
     428              : 
     429            0 :    telemeterT::appShutdown();
     430              : 
     431            0 :    return 0;
     432              : }
     433              : 
     434              : inline
     435            0 : int pwfsSlopeCalc::allocate(const dev::shmimT & dummy)
     436              : {
     437              :    static_cast<void>(dummy); //be unused
     438              : 
     439              :    //Initialize dark image if not correct size.
     440            0 :    if(darkMonitorT::m_width != shmimMonitorT::m_width || darkMonitorT::m_height != shmimMonitorT::m_height)
     441              :    {
     442            0 :       m_darkImage.resize(shmimMonitorT::m_width,shmimMonitorT::m_height);
     443            0 :       m_darkImage.setZero();
     444            0 :       m_darkSet = false;
     445              :    }
     446              : 
     447            0 :    m_reconfig = true;
     448              : 
     449            0 :    return 0;
     450              : }
     451              : 
     452              : inline
     453            0 : int pwfsSlopeCalc::processImage( void * curr_src,
     454              :                                        const dev::shmimT & dummy
     455              :                                      )
     456              : {
     457              :    static_cast<void>(dummy); //be unused
     458              : 
     459            0 :    m_curr_src = curr_src;
     460              : 
     461              :    //Now tell the f.g. to get going
     462            0 :    if(sem_post(&m_smSemaphore) < 0)
     463              :    {
     464            0 :       log<software_critical>({__FILE__, __LINE__, errno, 0, "Error posting to semaphore"});
     465            0 :        return -1;
     466              :    }
     467              : 
     468            0 :    return 0;
     469              : }
     470              : 
     471              : inline
     472            0 : int pwfsSlopeCalc::allocate(const darkShmimT & dummy)
     473              : {
     474              :    static_cast<void>(dummy); //be unused
     475              : 
     476            0 :    m_darkSet = false;
     477              : 
     478              : //    if(darkMonitorT::m_width != shmimMonitorT::m_width || darkMonitorT::m_height != shmimMonitorT::m_height)
     479              : //    {
     480              : //       darkMonitorT::m_restart = true;
     481              : //    }
     482              : 
     483            0 :    m_darkImage.resize(darkMonitorT::m_width, darkMonitorT::m_height);
     484            0 :    dark_pixget = getPixPointer<realT>(darkMonitorT::m_dataType);
     485              : 
     486            0 :    if(dark_pixget == nullptr)
     487              :    {
     488            0 :       log<software_error>({__FILE__, __LINE__, "bad data type"});
     489            0 :       return -1;
     490              :    }
     491              : 
     492            0 :    return 0;
     493              : }
     494              : 
     495              : inline
     496            0 : int pwfsSlopeCalc::processImage( void * curr_src,
     497              :                                        const darkShmimT & dummy
     498              :                                      )
     499              : {
     500              :    static_cast<void>(dummy); //be unused
     501              : 
     502            0 :    realT * data = m_darkImage.data();
     503              : 
     504            0 :    for(unsigned nn=0; nn < darkMonitorT::m_width*darkMonitorT::m_height; ++nn)
     505              :    {
     506              :       //data[nn] = *( (int16_t * ) (curr_src + nn*shmimMonitorT::m_typeSize));
     507            0 :       data[nn] = dark_pixget(curr_src, nn);
     508              :    }
     509              : 
     510            0 :    m_darkSet = true;
     511              : 
     512            0 :    return 0;
     513              : }
     514              : 
     515              : inline
     516            0 : int pwfsSlopeCalc::configureAcquisition()
     517              : {
     518            0 :    std::unique_lock<std::mutex> lock(m_indiMutex);
     519              : 
     520            0 :    if(shmimMonitorT::m_width==0 || shmimMonitorT::m_height==0 || shmimMonitorT::m_dataType == 0)
     521              :    {
     522              :       //This means we haven't connected to the stream to average. so wait.
     523            0 :       sleep(1);
     524            0 :       return -1;
     525              :    }
     526              : 
     527            0 :    m_quadSize = m_pupil_D + 2*m_pupil_buffer;
     528              : 
     529            0 :    m_pupil_sx_1 = m_pupil_cx_1 - 0.5*m_quadSize;
     530            0 :    m_pupil_sy_1 = m_pupil_cy_1 - 0.5*m_quadSize;
     531              : 
     532            0 :    m_pupil_sx_2 = m_pupil_cx_2 - 0.5*m_quadSize;
     533            0 :    m_pupil_sy_2 = m_pupil_cy_2 - 0.5*m_quadSize;
     534              : 
     535            0 :    m_pupil_sx_3 = m_pupil_cx_3 - 0.5*m_quadSize;
     536            0 :    m_pupil_sy_3 = m_pupil_cy_3 - 0.5*m_quadSize;
     537              : 
     538            0 :    m_pupil_sx_4 = m_pupil_cx_4 - 0.5*m_quadSize;
     539            0 :    m_pupil_sy_4 = m_pupil_cy_4 - 0.5*m_quadSize;
     540              : 
     541              :    //m_quadSize = shmimMonitorT::m_width/2;
     542            0 :    frameGrabberT::m_width = m_quadSize;
     543            0 :    frameGrabberT::m_height = 2*m_quadSize;
     544            0 :    frameGrabberT::m_dataType = _DATATYPE_FLOAT;
     545              : 
     546            0 :    return 0;
     547            0 : }
     548              : 
     549              : inline
     550            0 : int pwfsSlopeCalc::startAcquisition()
     551              : {
     552            0 :    return 0;
     553              : }
     554              : 
     555              : inline
     556            0 : int pwfsSlopeCalc::acquireAndCheckValid()
     557              : {
     558              :    timespec ts;
     559              : 
     560            0 :    if(clock_gettime(CLOCK_REALTIME, &ts) < 0)
     561              :    {
     562            0 :       log<software_critical>({__FILE__,__LINE__,errno,0,"clock_gettime"});
     563            0 :       return -1;
     564              :    }
     565              : 
     566            0 :    ts.tv_sec += 1;
     567              : 
     568            0 :    if(sem_timedwait(&m_smSemaphore, &ts) == 0)
     569              :    {
     570            0 :       clock_gettime(CLOCK_REALTIME, &m_currImageTimestamp);
     571            0 :       return 0;
     572              :    }
     573              :    else
     574              :    {
     575            0 :       return 1;
     576              :    }
     577              : }
     578              : 
     579              : inline
     580            0 : int pwfsSlopeCalc::loadImageIntoStream(void * dest)
     581              : {
     582              :    //Here is where we do it.
     583            0 :    Eigen::Map<eigenImage<unsigned short>> pwfsIm( static_cast<unsigned short *>(m_curr_src), shmimMonitorT::m_width, shmimMonitorT::m_height );
     584            0 :    Eigen::Map<eigenImage<float>> slopesIm(static_cast<float*>(dest), frameGrabberT::m_width, frameGrabberT::m_height );
     585              : 
     586              :    static float sqrt32 = sqrt(3.0)/2;
     587              : 
     588            0 :    float norm = 0;
     589            0 :    int N = 0;
     590            0 :    if(m_numPupils == 3)
     591              :    {
     592            0 :       for(int rr=0; rr< m_quadSize; ++rr)
     593              :       {
     594            0 :          for(int cc=0; cc< m_quadSize; ++cc)
     595              :          {
     596            0 :             float I2 = pwfsIm(rr+m_pupil_sx_1,cc+m_pupil_sy_1) - m_darkImage(rr+m_pupil_sx_1,cc+m_pupil_sy_1);
     597            0 :             float I3 = pwfsIm(rr+m_pupil_sx_2,cc+m_pupil_sy_2) - m_darkImage(rr+m_pupil_sx_2,cc+m_pupil_sy_2);
     598            0 :             float I1 = pwfsIm(rr+m_pupil_sx_3,cc+m_pupil_sy_3) - m_darkImage(rr+m_pupil_sx_3,cc+m_pupil_sy_3);
     599              : 
     600            0 :             norm += I1+I2+I3;
     601            0 :             ++N;
     602              : 
     603            0 :             slopesIm(rr,cc) = sqrt32*(I2-I3);///norm;
     604            0 :             slopesIm(rr,cc+m_quadSize) = (I1-0.5*(I2+I3));///norm;
     605              :          }
     606              :       }
     607              :    }
     608              :    else
     609              :    {
     610              : 
     611            0 :       for(int rr=0; rr< m_quadSize; ++rr)
     612              :       {
     613            0 :          for(int cc=0; cc< m_quadSize; ++cc)
     614              :          {
     615            0 :             float I1 = pwfsIm(rr+m_pupil_sx_1,cc+m_pupil_sy_1) - m_darkImage(rr+m_pupil_sx_1,cc+m_pupil_sy_1);
     616            0 :             float I2 = pwfsIm(rr+m_pupil_sx_2,cc+m_pupil_sy_2) - m_darkImage(rr+m_pupil_sx_2,cc+m_pupil_sy_2);
     617            0 :             float I3 = pwfsIm(rr+m_pupil_sx_3,cc+m_pupil_sy_3) - m_darkImage(rr+m_pupil_sx_3,cc+m_pupil_sy_3);
     618            0 :             float I4 = pwfsIm(rr+m_pupil_sx_4,cc+m_pupil_sy_4) - m_darkImage(rr+m_pupil_sx_4,cc+m_pupil_sy_4);
     619              : 
     620            0 :             norm += I1+I2+I3+I4;
     621            0 :             ++N;
     622              : 
     623            0 :             slopesIm(rr,cc) = ((I1+I3) - (I2+I4));///norm;
     624            0 :             slopesIm(rr,cc+m_quadSize) = ((I1+I2)-(I3+I4));///norm;
     625              :          }
     626              :       }
     627              :    }
     628              : 
     629            0 :    norm /= N;
     630            0 :    for(size_t ii=0; ii< frameGrabberT::m_height; ++ii)
     631              :    {
     632            0 :       for(size_t jj=0; jj < frameGrabberT::m_width; ++jj)
     633              :       {
     634            0 :          slopesIm(jj,ii)/=norm;
     635              :       }
     636              :    }
     637              : 
     638            0 :    return 0;
     639              : }
     640              : 
     641              : inline
     642            0 : int pwfsSlopeCalc::reconfig()
     643              : {
     644            0 :    return 0;
     645              : }
     646              : 
     647            0 : INDI_SETCALLBACK_DEFN(pwfsSlopeCalc, m_indiP_quad1)(const pcf::IndiProperty &ipRecv)
     648              : {
     649            0 :    if(ipRecv.getName() != m_indiP_quad1.getName())
     650              :    {
     651            0 :       log<software_error>({__FILE__,__LINE__,"wrong INDI property received"});
     652              : 
     653            0 :       return -1;
     654              :    }
     655              : 
     656            0 :    if(ipRecv.find("set-x"))
     657              :    {
     658            0 :       float newval = ipRecv["set-x"].get<float>();
     659            0 :       if(newval != m_pupil_cx_1)
     660              :       {
     661            0 :          m_pupil_cx_1 = newval;
     662            0 :          m_reconfig = true;
     663              :       }
     664              :    }
     665              : 
     666            0 :    if(ipRecv.find("set-y"))
     667              :    {
     668            0 :       float newval = ipRecv["set-y"].get<float>();
     669            0 :       if(newval != m_pupil_cy_1)
     670              :       {
     671            0 :          m_pupil_cy_1 = newval;
     672            0 :          m_reconfig = true;
     673              :       }
     674              :    }
     675              : 
     676            0 :    if(ipRecv.find("set-D"))
     677              :    {
     678            0 :       float newval = ipRecv["set-D"].get<float>();
     679            0 :       if(newval != m_pupil_D_1)
     680              :       {
     681            0 :          m_pupil_D_1 = newval;
     682            0 :          m_reconfig = true;
     683              :       }
     684              :    }
     685              : 
     686              : 
     687            0 :    return 0;
     688              : }
     689              : 
     690            0 : INDI_SETCALLBACK_DEFN(pwfsSlopeCalc, m_indiP_quad2)(const pcf::IndiProperty &ipRecv)
     691              : {
     692            0 :    if(ipRecv.getName() != m_indiP_quad2.getName())
     693              :    {
     694            0 :       log<software_error>({__FILE__,__LINE__,"wrong INDI property received"});
     695              : 
     696            0 :       return -2;
     697              :    }
     698              : 
     699            0 :    if(ipRecv.find("set-x"))
     700              :    {
     701            0 :       float newval = ipRecv["set-x"].get<float>();
     702            0 :       if(newval != m_pupil_cx_2)
     703              :       {
     704            0 :          m_pupil_cx_2 = newval;
     705            0 :          m_reconfig = true;
     706              :       }
     707              :    }
     708              : 
     709            0 :    if(ipRecv.find("set-y"))
     710              :    {
     711            0 :      float newval = ipRecv["set-y"].get<float>();
     712            0 :       if(newval != m_pupil_cy_2)
     713              :       {
     714            0 :          m_pupil_cy_2 = newval;
     715            0 :          m_reconfig = true;
     716              :       }
     717              :    }
     718            0 :    if(ipRecv.find("set-D"))
     719              :    {
     720            0 :       float newval = ipRecv["set-D"].get<float>();
     721            0 :       if(newval != m_pupil_D_2)
     722              :       {
     723            0 :          m_pupil_D_2 = newval;
     724            0 :          m_reconfig = true;
     725              :       }
     726              :    }
     727              : 
     728              : 
     729            0 :    return 0;
     730              : }
     731              : 
     732            0 : INDI_SETCALLBACK_DEFN(pwfsSlopeCalc, m_indiP_quad3)(const pcf::IndiProperty &ipRecv)
     733              : {
     734            0 :    if(ipRecv.getName() != m_indiP_quad3.getName())
     735              :    {
     736            0 :       log<software_error>({__FILE__,__LINE__,"wrong INDI property received"});
     737              : 
     738            0 :       return -3;
     739              :    }
     740              : 
     741            0 :    if(ipRecv.find("set-x"))
     742              :    {
     743            0 :       float newval = ipRecv["set-x"].get<float>();
     744            0 :       if(newval != m_pupil_cx_3)
     745              :       {
     746            0 :          m_pupil_cx_3 = newval;
     747            0 :          m_reconfig = true;
     748              :       }
     749              :    }
     750            0 :    if(ipRecv.find("set-y"))
     751              :    {
     752            0 :       float newval = ipRecv["set-y"].get<float>();
     753            0 :       if(newval != m_pupil_cy_3)
     754              :       {
     755            0 :          m_pupil_cy_3 = newval;
     756            0 :          m_reconfig = true;
     757              :       }
     758              :    }
     759            0 :    if(ipRecv.find("set-D"))
     760              :    {
     761            0 :       float newval = ipRecv["set-D"].get<float>();
     762            0 :       if(newval != m_pupil_D_3)
     763              :       {
     764            0 :          m_pupil_D_3 = newval;
     765            0 :          m_reconfig = true;
     766              :       }
     767              :    }
     768              : 
     769              : 
     770            0 :    return 0;
     771              : }
     772              : 
     773            0 : INDI_SETCALLBACK_DEFN(pwfsSlopeCalc, m_indiP_quad4)(const pcf::IndiProperty &ipRecv)
     774              : {
     775            0 :    if(ipRecv.getName() != m_indiP_quad4.getName())
     776              :    {
     777            0 :       log<software_error>({__FILE__,__LINE__,"wrong INDI property received"});
     778              : 
     779            0 :       return -4;
     780              :    }
     781              : 
     782            0 :    if(ipRecv.find("set-x"))
     783              :    {
     784            0 :       float newval = ipRecv["set-x"].get<float>();
     785            0 :       if(newval != m_pupil_cx_4)
     786              :       {
     787            0 :          m_pupil_cx_4 = newval;
     788            0 :          m_reconfig = true;
     789              :       }
     790              :    }
     791            0 :    if(ipRecv.find("set-y"))
     792              :    {
     793            0 :       float newval = ipRecv["set-y"].get<float>();
     794            0 :       if(newval != m_pupil_cy_4)
     795              :       {
     796            0 :          m_pupil_cy_4 = newval;
     797            0 :          m_reconfig = true;
     798              :       }
     799              :    }
     800            0 :    if(ipRecv.find("set-D"))
     801              :    {
     802            0 :       float newval = ipRecv["set-D"].get<float>();
     803            0 :       if(newval != m_pupil_D_4)
     804              :       {
     805            0 :          m_pupil_D_4 = newval;
     806            0 :          m_reconfig = true;
     807              :       }
     808              :    }
     809              : 
     810              : 
     811            0 :    return 0;
     812              : }
     813              : 
     814              : inline
     815            0 : int pwfsSlopeCalc::checkRecordTimes()
     816              : {
     817            0 :    return telemeterT::checkRecordTimes(telem_fgtimings());
     818              : }
     819              : 
     820              : inline
     821            0 : int pwfsSlopeCalc::recordTelem( const telem_fgtimings * )
     822              : {
     823            0 :    return recordFGTimings(true);
     824              : }
     825              : 
     826              : } //namespace app
     827              : } //namespace MagAOX
     828              : 
     829              : #endif //pwfsSlopeCalc_hpp
        

Generated by: LCOV version 2.0-1