File indexing completed on 2024-04-28 03:43:27

0001 /*
0002     SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "ui_focus.h"
0010 #include "focusfourierpower.h"
0011 #include "ekos/ekos.h"
0012 #include "parameters.h"
0013 #include "ekos/auxiliary/filtermanager.h"
0014 
0015 #include "indi/indicamera.h"
0016 #include "indi/indifocuser.h"
0017 #include "indi/indistd.h"
0018 #include "indi/indiweather.h"
0019 #include "indi/indimount.h"
0020 
0021 #include "opsfocussettings.h"
0022 #include "opsfocusprocess.h"
0023 #include "opsfocusmechanics.h"
0024 #include "ui_cfz.h"
0025 #include "ui_advisor.h"
0026 
0027 #include <parameters.h>
0028 
0029 class FocusProfilePlot;
0030 class FITSData;
0031 class FITSView;
0032 class FitsViewer;
0033 
0034 namespace Ekos
0035 {
0036 
0037 class DarkProcessor;
0038 class FocusAlgorithmInterface;
0039 class FocusFWHM;
0040 class PolynomialFit;
0041 class AdaptiveFocus;
0042 class StellarSolverProfileEditor;
0043 
0044 /**
0045  * @class Focus
0046  * @short Supports manual focusing and auto focusing using relative and absolute INDI focusers.
0047  *
0048  * @author Jasem Mutlaq
0049  * @version 1.5
0050  */
0051 class Focus : public QWidget, public Ui::Focus
0052 {
0053         Q_OBJECT
0054         Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Focus")
0055         Q_PROPERTY(Ekos::FocusState status READ status NOTIFY newStatus)
0056         Q_PROPERTY(QStringList logText READ logText NOTIFY newLog)
0057         Q_PROPERTY(QString opticalTrain READ opticalTrain WRITE setOpticalTrain)
0058         Q_PROPERTY(QString camera READ camera)
0059         Q_PROPERTY(QString focuser READ focuser)
0060         Q_PROPERTY(QString filterWheel READ filterWheel)
0061         Q_PROPERTY(QString filter READ filter WRITE setFilter)
0062         Q_PROPERTY(double HFR READ getHFR NOTIFY newHFR)
0063         Q_PROPERTY(double exposure READ exposure WRITE setExposure)
0064 
0065         // AdaptiveFocus is a friend class so it can access methods in Focus
0066         friend class AdaptiveFocus;
0067 
0068     public:
0069         Focus();
0070         ~Focus();
0071 
0072         typedef enum { FOCUS_NONE, FOCUS_IN, FOCUS_OUT } Direction;
0073         typedef enum { FOCUS_MANUAL, FOCUS_AUTO } Type;
0074         typedef enum { FOCUS_ITERATIVE, FOCUS_POLYNOMIAL, FOCUS_LINEAR, FOCUS_LINEAR1PASS } Algorithm;
0075         typedef enum { FOCUS_CFZ_CLASSIC, FOCUS_CFZ_WAVEFRONT, FOCUS_CFZ_GOLD } CFZAlgorithm;
0076         typedef enum { FOCUS_STAR_HFR, FOCUS_STAR_HFR_ADJ, FOCUS_STAR_FWHM, FOCUS_STAR_NUM_STARS, FOCUS_STAR_FOURIER_POWER } StarMeasure;
0077         typedef enum { FOCUS_STAR_GAUSSIAN, FOCUS_STAR_MOFFAT } StarPSF;
0078         typedef enum { FOCUS_UNITS_PIXEL, FOCUS_UNITS_ARCSEC } StarUnits;
0079         typedef enum { FOCUS_WALK_CLASSIC, FOCUS_WALK_FIXED_STEPS, FOCUS_WALK_CFZ_SHUFFLE } FocusWalk;
0080 
0081         typedef enum { FOCUS_MASK_NONE, FOCUS_MASK_RING, FOCUS_MASK_MOSAIC } ImageMaskType;
0082         //typedef enum { FOCUSER_TEMPERATURE, OBSERVATORY_TEMPERATURE, NO_TEMPERATURE } TemperatureSource;
0083 
0084         /** @defgroup FocusDBusInterface Ekos DBus Interface - Focus Module
0085              * Ekos::Focus interface provides advanced scripting capabilities to perform manual and automatic focusing operations.
0086             */
0087 
0088         /*@{*/
0089 
0090         /** DBUS interface function.
0091              * select the CCD device from the available CCD drivers.
0092              * @param device The CCD device name
0093              * @return Returns true if CCD device is found and set, false otherwise.
0094              */
0095         Q_SCRIPTABLE QString camera();
0096 
0097         /** DBUS interface function.
0098              * select the focuser device from the available focuser drivers. The focuser device can be the same as the CCD driver if the focuser functionality was embedded within the driver.
0099              * @param device The focuser device name
0100              * @return Returns true if focuser device is found and set, false otherwise.
0101              */
0102         Q_SCRIPTABLE QString focuser();
0103 
0104         /** DBUS interface function.
0105              * select the filter device from the available filter drivers. The filter device can be the same as the CCD driver if the filter functionality was embedded within the driver.
0106              * @param device The filter device name
0107              * @return Returns true if filter device is found and set, false otherwise.
0108              */
0109         Q_SCRIPTABLE QString filterWheel();
0110 
0111         /** DBUS interface function.
0112              * select the filter from the available filters.
0113              * @param filter The filter name
0114              * @return Returns true if filter is found and set, false otherwise.
0115              */
0116         Q_SCRIPTABLE bool setFilter(const QString &filter);
0117         Q_SCRIPTABLE QString filter();
0118 
0119         /** DBUS interface function.
0120              * @return Returns True if current focuser supports auto-focusing
0121              */
0122         Q_SCRIPTABLE bool canAutoFocus()
0123         {
0124             return (m_FocusType == FOCUS_AUTO);
0125         }
0126 
0127         /** DBUS interface function.
0128              * @return Returns Half-Flux-Radius in pixels.
0129              */
0130         Q_SCRIPTABLE double getHFR()
0131         {
0132             return currentHFR;
0133         }
0134 
0135         /** DBUS interface function.
0136              * Set CCD exposure value
0137              * @param value exposure value in seconds.
0138              */
0139         Q_SCRIPTABLE Q_NOREPLY void setExposure(double value);
0140         Q_SCRIPTABLE double exposure()
0141         {
0142             return focusExposure->value();
0143         }
0144 
0145         /** DBUS interface function.
0146              * Set CCD binning
0147              * @param binX horizontal binning
0148              * @param binY vertical binning
0149              */
0150         Q_SCRIPTABLE Q_NOREPLY void setBinning(int binX, int binY);
0151 
0152         /** DBUS interface function.
0153              * Set Auto Focus options. The options must be set before starting the autofocus operation. If no options are set, the options loaded from the user configuration are used.
0154              * @param enable If true, Ekos will attempt to automatically select the best focus star in the frame. If it fails to select a star, the user will be asked to select a star manually.
0155              */
0156         Q_SCRIPTABLE Q_NOREPLY void setAutoStarEnabled(bool enable);
0157 
0158         /** DBUS interface function.
0159              * Set Auto Focus options. The options must be set before starting the autofocus operation. If no options are set, the options loaded from the user configuration are used.
0160              * @param enable if true, Ekos will capture a subframe around the selected focus star. The subframe size is determined by the boxSize parameter.
0161              */
0162         Q_SCRIPTABLE Q_NOREPLY void setAutoSubFrameEnabled(bool enable);
0163 
0164         /** DBUS interface function.
0165              * Set Autofocus parameters
0166              * @param boxSize the box size around the focus star in pixels. The boxsize is used to subframe around the focus star.
0167              * @param stepSize the initial step size to be commanded to the focuser. If the focuser is absolute, the step size is in ticks. For relative focusers, the focuser will be commanded to focus inward for stepSize milliseconds initially.
0168              * @param maxTravel the maximum steps permitted before the autofocus operation aborts.
0169              * @param tolerance Measure of how accurate the autofocus algorithm is. If the difference between the current HFR and minimum measured HFR is less than %tolerance after the focuser traversed both ends of the V-curve, then the focusing operation
0170              * is deemed successful. Otherwise, the focusing operation will continue.
0171              */
0172         Q_SCRIPTABLE Q_NOREPLY void setAutoFocusParameters(int boxSize, int stepSize, int maxTravel, double tolerance);
0173 
0174         /** DBUS interface function.
0175             * resetFrame Resets the CCD frame to its full native resolution.
0176             */
0177         Q_SCRIPTABLE Q_NOREPLY void resetFrame();
0178 
0179         /** DBUS interface function.
0180             * Return state of Focuser module (Ekos::FocusState)
0181             */
0182 
0183         Q_SCRIPTABLE Ekos::FocusState status()
0184         {
0185             return m_state;
0186         }
0187 
0188         /** @}*/
0189 
0190         /**
0191              * @brief Add CCD to the list of available CCD.
0192              * @param newCCD pointer to CCD device.
0193              * @return True if added successfully, false if duplicate or failed to add.
0194              */
0195         bool setCamera(ISD::Camera *device);
0196 
0197         /**
0198              * @brief addFocuser Add focuser to the list of available focusers.
0199              * @param newFocuser pointer to focuser device.
0200              * @return True if added successfully, false if duplicate or failed to add.
0201              */
0202         bool setFocuser(ISD::Focuser *device);
0203 
0204         /**
0205              * @brief reconnectFocuser Add focuser to the list of available focusers.
0206              * @param focuser name of the focuser.
0207              */
0208         void reconnectFocuser(const QString &focuser);
0209 
0210         /**
0211              * @brief addFilter Add filter to the list of available filters.
0212              * @param newFilter pointer to filter device.
0213              * @return True if added successfully, false if duplicate or failed to add.
0214              */
0215         bool setFilterWheel(ISD::FilterWheel *device);
0216 
0217         /**
0218          * @brief setImageMask Select the currently active image mask filtering
0219          *        the stars relevant for focusing
0220          */
0221         void selectImageMask();
0222 
0223         /**
0224              * @brief addTemperatureSource Add temperature source to the list of available sources.
0225              * @param newSource Device with temperature reporting capability
0226              * @return True if added successfully, false if duplicate or failed to add.
0227              */
0228         bool addTemperatureSource(const QSharedPointer<ISD::GenericDevice> &device);
0229 
0230         /**
0231          * @brief removeDevice Remove device from Focus module
0232          * @param deviceRemoved pointer to device
0233          */
0234         void removeDevice(const QSharedPointer<ISD::GenericDevice> &deviceRemoved);
0235 
0236         const QSharedPointer<FilterManager> &filterManager() const
0237         {
0238             return m_FilterManager;
0239         }
0240         void setupFilterManager();
0241         void connectFilterManager();
0242 
0243         void clearLog();
0244         QStringList logText()
0245         {
0246             return m_LogText;
0247         }
0248         QString getLogText()
0249         {
0250             return m_LogText.join("\n");
0251         }
0252 
0253         // Settings
0254         QVariantMap getAllSettings() const;
0255         void setAllSettings(const QVariantMap &settings);
0256 
0257     public slots:
0258 
0259         /** \addtogroup FocusDBusInterface
0260              *  @{
0261              */
0262 
0263         /* Focus */
0264         /** DBUS interface function.
0265              * Start the autofocus operation.
0266              */
0267         Q_SCRIPTABLE Q_NOREPLY void start();
0268 
0269         /** DBUS interface function.
0270              * Abort the autofocus operation.
0271              */
0272         Q_SCRIPTABLE Q_NOREPLY void abort();
0273 
0274         /** DBUS interface function.
0275              * Capture a focus frame.
0276              * @param settleTime if > 0 wait for the given time in seconds before starting to capture
0277              */
0278         Q_SCRIPTABLE Q_NOREPLY void capture(double settleTime = 0.0);
0279 
0280         /** DBUS interface function.
0281              * Focus inward
0282              * @param ms If set, focus inward for ms ticks (Absolute Focuser), or ms milliseconds (Relative Focuser). If not set, it will use the value specified in the options.
0283              */
0284         Q_SCRIPTABLE bool focusIn(int ms = -1);
0285 
0286         /** DBUS interface function.
0287              * Focus outward
0288              * @param ms If set, focus outward for ms ticks (Absolute Focuser), or ms milliseconds (Relative Focuser). If not set, it will use the value specified in the options.
0289              */
0290         Q_SCRIPTABLE bool focusOut(int ms = -1);
0291 
0292         /**
0293              * @brief checkFocus Given the minimum required HFR, check focus and calculate HFR. If current HFR exceeds required HFR, start autofocus process, otherwise do nothing.
0294              * @param requiredHFR Minimum HFR to trigger autofocus process.
0295              */
0296         Q_SCRIPTABLE Q_NOREPLY void checkFocus(double requiredHFR);
0297 
0298         /**
0299              * @brief runAutoFocus Run the autofocus process for the currently selected filter
0300              * @param policy is the filter policy to use.
0301              */
0302         Q_SCRIPTABLE Q_NOREPLY void runAutoFocus(bool buildOffsets);
0303 
0304         /** @}*/
0305 
0306         /**
0307              * @brief startFraming Begins continuous capture of the CCD and calculates HFR every frame.
0308              */
0309         void startFraming();
0310 
0311         /**
0312          * @brief Move the focuser to the initial focus position.
0313          */
0314         void resetFocuser();
0315 
0316         /**
0317              * @brief checkStopFocus Perform checks before stopping the autofocus operation. Some checks are necessary for in-sequence focusing.
0318              * @param abort true iff focusing should be aborted, false if it should only be stopped and marked as failed
0319              */
0320         void checkStopFocus(bool abort);
0321 
0322         /**
0323          * @brief React when a meridian flip has been started
0324          */
0325         void meridianFlipStarted();
0326 
0327         /**
0328              * @brief Check CCD and make sure information is updated accordingly. This simply calls syncCameraInfo for the current CCD.
0329              * @param CCDNum By default, we check the already selected CCD in the dropdown menu. If CCDNum is specified, the check is made against this specific CCD in the dropdown menu.
0330              *  CCDNum is the index of the CCD in the dropdown menu.
0331              */
0332         void checkCamera();
0333 
0334         /**
0335              * @brief syncCameraInfo Read current CCD information and update settings accordingly.
0336              */
0337         void syncCameraInfo();
0338 
0339         /**
0340          * @brief Update camera controls like Gain, ISO, Offset...etc
0341          */
0342         void syncCCDControls();
0343 
0344         /**
0345              * @brief Check Focuser and make sure information is updated accordingly.
0346              * @param FocuserNum By default, we check the already selected focuser in the dropdown menu. If FocuserNum is specified, the check is made against this specific focuser in the dropdown menu.
0347              *  FocuserNum is the index of the focuser in the dropdown menu.
0348              */
0349         void checkFocuser();
0350 
0351         /**
0352              * @brief Check Filter and make sure information is updated accordingly.
0353              * @param filterNum By default, we check the already selected filter in the dropdown menu. If filterNum is specified, the check is made against this specific filter in the dropdown menu.
0354              *  filterNum is the index of the filter in the dropdown menu.
0355              */
0356         void checkFilter();
0357 
0358         /**
0359              * @brief Check temperature source and make sure information is updated accordingly.
0360              * @param name Name of temperature source, if empty then use current source.
0361              */
0362         void checkTemperatureSource(const QString &name = QString());
0363 
0364         /**
0365              * @brief clearDataPoints Remove all data points from HFR plots
0366              */
0367         void clearDataPoints();
0368 
0369         /**
0370              * @brief focusStarSelected The user selected a focus star, save its coordinates and subframe it if subframing is enabled.
0371              * @param x X coordinate
0372              * @param y Y coordinate
0373              */
0374         void focusStarSelected(int x, int y);
0375 
0376         /**
0377          * @brief selectFocusStarFraction Select the focus star based by fraction of the overall size.
0378          * It calls focusStarSelected after multiplying the fractions (0.0 to 1.0) with the focus view width and height.
0379          * @param x final x = x * focusview_width
0380          * @param y final y = y * focusview_height
0381          */
0382         void selectFocusStarFraction(double x, double y);
0383 
0384         /**
0385              * @brief newFITS A new FITS blob is received by the CCD driver.
0386              * @param bp pointer to blob data
0387              */
0388         void processData(const QSharedPointer<FITSData> &data);
0389 
0390         /**
0391              * @brief updateProperty Read focus number properties of interest as they arrive from the focuser driver and process them accordingly.
0392              * @param prop INDI Property
0393              */
0394         void updateProperty(INDI::Property prop);
0395 
0396         /**
0397              * @brief processTemperatureSource Updates focus temperature source.
0398              * @param nvp pointer to updated focuser number property.
0399              */
0400         void processTemperatureSource(INDI::Property prop);
0401 
0402         /**
0403              * @brief setFocusStatus Upon completion of the focusing process, set its status (fail or pass) and reset focus process to clean state.
0404              * @param status If true, the focus process finished successfully. Otherwise, it failed.
0405              */
0406         //void setAutoFocusResult(bool status);
0407 
0408         // Logging methods - one for INFO messages to the kstars log, and one for a CSV auto-focus log
0409         void appendLogText(const QString &);
0410         void appendFocusLogText(const QString &);
0411 
0412         // Adjust focuser offset, relative or absolute
0413         void adjustFocusOffset(int value, bool useAbsoluteOffset);
0414 
0415         // Update Mount module status
0416         void setMountStatus(ISD::Mount::Status newState);
0417 
0418         // Update Altitude From Mount
0419         void setMountCoords(const SkyPoint &position, ISD::Mount::PierSide pierSide, const dms &ha);
0420 
0421         /**
0422          * @brief toggleVideo Turn on and off video streaming if supported by the camera.
0423          * @param enabled Set to true to start video streaming, false to stop it if active.
0424          */
0425         void toggleVideo(bool enabled);
0426 
0427         /**
0428          * @brief setWeatherData Updates weather data that could be used to extract focus temperature from observatory
0429          * in case focus native temperature is not available.
0430          */
0431         //void setWeatherData(const std::vector<ISD::Weather::WeatherData> &data);
0432 
0433         /**
0434          * @brief loadOptionsProfiles Load StellarSolver Profile
0435          */
0436         void loadStellarSolverProfiles();
0437 
0438         /**
0439          * @brief getStellarSolverProfiles
0440          * @return list of StellarSolver profile names
0441          */
0442         QStringList getStellarSolverProfiles();
0443 
0444         QString opticalTrain() const
0445         {
0446             return opticalTrainCombo->currentText();
0447         }
0448         void setOpticalTrain(const QString &value)
0449         {
0450             opticalTrainCombo->setCurrentText(value);
0451         }
0452 
0453         /**
0454          * @brief adaptiveFocus moves the focuser between subframes to stay at focus
0455          */
0456         void adaptiveFocus();
0457 
0458     protected:
0459         void addPlotPosition(int pos, double hfr, bool plot = true);
0460 
0461     private slots:
0462         /**
0463              * @brief toggleSubframe Process enabling and disabling subfrag.
0464              * @param enable If true, subframing is enabled. If false, subframing is disabled. Even if subframing is enabled, it must be supported by the CCD driver.
0465              */
0466         void toggleSubframe(bool enable);
0467 
0468         void checkAutoStarTimeout();
0469 
0470         void setAbsoluteFocusTicks();
0471 
0472         void updateBoxSize(int value);
0473 
0474         void processCaptureTimeout();
0475 
0476         void processCaptureError(ISD::Camera::ErrorType type);
0477 
0478         void setCaptureComplete();
0479 
0480         void showFITSViewer();
0481 
0482         void toggleFocusingWidgetFullScreen();
0483 
0484         void setVideoStreamEnabled(bool enabled);
0485 
0486         void starDetectionFinished();
0487         void setCurrentMeasure();
0488         void startAbIns();
0489 
0490     signals:
0491         void newLog(const QString &text);
0492         void newStatus(Ekos::FocusState state);
0493         void newHFR(double hfr, int position, bool inAutofocus);
0494         void newFocusTemperatureDelta(double delta, double absTemperature);
0495 
0496         void absolutePositionChanged(int value);
0497         void focusPositionAdjusted();
0498         void focusAdaptiveComplete(bool success);
0499 
0500         void trainChanged();
0501 
0502         void suspendGuiding();
0503         void resumeGuiding();
0504         void newImage(const QSharedPointer<FITSView> &view);
0505         void newStarPixmap(QPixmap &);
0506         void settingsUpdated(const QVariantMap &settings);
0507 
0508         // Signals for Analyze.
0509         void autofocusStarting(double temperature, const QString &filter);
0510         void autofocusComplete(const QString &filter, const QString &points, const QString &curve = "", const QString &title = "");
0511         void autofocusAborted(const QString &filter, const QString &points);
0512 
0513         /**
0514          * @brief Signal Analyze that an Adaptive Focus iteration is complete
0515          * @param Active filter
0516          * @param temperature
0517          * @param tempTicks is the number of ticks movement due to temperature change
0518          * @param altitude
0519          * @param altTicks is the number of ticks movement due to altitude change
0520          * @param prevPosError is the position error at the previous adaptive focus iteration
0521          * @param thisPosError is the position error for the current adaptive focus iteration
0522          * @param totalTicks is the total tick movement for this adaptive focus iteration
0523          * @param position is the current focuser position
0524          * @param focuserMoved indicates whether totalTicks > minimum focuser movement
0525          */
0526         void adaptiveFocusComplete(const QString &filter, double temperature, double tempTicks, double altitude, double altTicks,
0527                                    int prevPosError, int thisPosError, int totalTicks, int position, bool focuserMoved);
0528 
0529         // HFR V curve plot events
0530         /**
0531          * @brief initialize the HFR V plot
0532          * @param showPosition show focuser position (true) or count focus iterations (false)
0533          * @param yAxisLabel is the label to display
0534          * @param starUnits the units multiplier to display the pixel data
0535          * @param minimum whether the curve shape is a minimum or maximum
0536          * @param useWeights whether or not to display weights on the graph
0537          * @param showPosition show focuser position (true) or show focusing iteration number (false)
0538          */
0539         void initHFRPlot(QString str, double starUnits, bool minimum, bool useWeights, bool showPosition);
0540 
0541         /**
0542           * @brief new HFR plot position with sigma
0543           * @param pos focuser position with associated error (sigma)
0544           * @param hfr measured star HFR value
0545           * @param sigma is the standard deviation of star HFRs
0546           * @param pulseDuration Pulse duration in ms for relative focusers that only support timers,
0547           *        or the number of ticks in a relative or absolute focuser
0548           * */
0549         void newHFRPlotPosition(double pos, double hfr, double sigma, bool outlier, int pulseDuration, bool plot = true);
0550 
0551         /**
0552          * @brief draw the approximating polynomial into the HFR V-graph
0553          * @param poly pointer to the polynomial approximation
0554          * @param isVShape has the solution a V shape?
0555          * @param activate make the graph visible?
0556          */
0557         void drawPolynomial(PolynomialFit *poly, bool isVShape, bool activate, bool plot = true);
0558 
0559         /**
0560          * @brief draw the curve into the HFR V-graph
0561          * @param poly pointer to the polynomial approximation
0562          * @param isVShape has the solution a V shape?
0563          * @param activate make the graph visible?
0564          */
0565         void drawCurve(CurveFitting *curve, bool isVShape, bool activate, bool plot = true);
0566 
0567         /**
0568          * @brief Focus solution with minimal HFR found
0569          * @param solutionPosition focuser position
0570          * @param solutionValue HFR value
0571          */
0572         void minimumFound(double solutionPosition, double solutionValue, bool plot = true);
0573 
0574         /**
0575          * @brief Draw Critical Focus Zone on graph
0576          * @param solutionPosition focuser position
0577          * @param solutionValue HFR value
0578          * @param m_cfzSteps the size of the CFZ
0579          * @param plt - whether to plot the CFZ
0580          */
0581         void drawCFZ(double minPosition, double minValue, int m_cfzSteps, bool plt);
0582 
0583         /**
0584          * @brief redraw the entire HFR plot
0585          * @param poly pointer to the polynomial approximation
0586          * @param solutionPosition solution focuser position
0587          * @param solutionValue solution HFR value
0588          */
0589         void redrawHFRPlot(PolynomialFit *poly, double solutionPosition, double solutionValue);
0590 
0591         /**
0592          * @brief draw a title on the focus plot
0593          * @param title the title
0594          */
0595         void setTitle(const QString &title, bool plot = true);
0596 
0597         /**
0598          * @brief final updates after focus run comopletes on the focus plot
0599          * @param title
0600          * @param plot
0601          */
0602         void finalUpdates(const QString &title, bool plot = true);
0603 
0604         /**
0605          * @brief focuserTimedout responding to requests
0606          * @param focuser
0607          */
0608         void focuserTimedout(const QString &focuser);
0609 
0610     private:
0611 
0612         QList<SSolver::Parameters> m_StellarSolverProfiles;
0613         QString savedOptionsProfiles;
0614         StellarSolverProfileEditor *optionsProfileEditor { nullptr };
0615 
0616         // Connections
0617         void initConnections();
0618 
0619         // Settings
0620 
0621         /**
0622          * @brief Connect GUI elements to sync settings once updated.
0623          */
0624         void connectSyncSettings();
0625         /**
0626          * @brief Stop updating settings when GUI elements are updated.
0627          */
0628         void disconnectSyncSettings();
0629         /**
0630          * @brief loadSettings Load setting from Options and set them accordingly.
0631          */
0632         void loadGlobalSettings();
0633 
0634         /**
0635          * @brief checkMosaicMaskLimits Check if the maximum values configured
0636          * for the aberration style mosaic tile sizes fit into the CCD frame size.
0637          */
0638         void checkMosaicMaskLimits();
0639 
0640         /**
0641          * @brief syncSettings When checkboxes, comboboxes, or spin boxes are updated, save their values in the
0642          * global and per-train settings.
0643          */
0644         void syncSettings();
0645 
0646         /**
0647          * @brief syncControl Sync setting to widget. The value depends on the widget type.
0648          * @param settings Map of all settings
0649          * @param key name of widget to sync
0650          * @param widget pointer of widget to set
0651          * @return True if sync successful, false otherwise
0652          */
0653         bool syncControl(const QVariantMap &settings, const QString &key, QWidget * widget);
0654 
0655         /**
0656          * @brief prepareGUI Perform once only GUI prep processing
0657          */
0658         void prepareGUI();
0659 
0660         /**
0661          * @brief setUseWeights sets the useWeights checkbox
0662          */
0663         void setUseWeights();
0664 
0665         /**
0666          * @brief setDonutBuster sets the donutBuster checkbox
0667          */
0668         void setDonutBuster();
0669 
0670         // HFR Plot
0671         void initPlots();
0672 
0673         // Positions
0674         void getAbsFocusPosition();
0675         bool autoFocusChecks();
0676         void autoFocusAbs();
0677         void autoFocusLinear();
0678         void autoFocusRel();
0679 
0680         // Linear does plotting differently from the rest.
0681         void plotLinearFocus();
0682 
0683         // Linear final updates to the curve
0684         void plotLinearFinalUpdates();
0685 
0686         // Launch the Aberation Inspector popup
0687         void startAberrationInspector();
0688 
0689         // Get the curve fitting goal based on how the algorithm is progressing
0690         CurveFitting::FittingGoal getGoal(int numSteps);
0691 
0692         /** @brief Helper function determining whether the focuser behaves like a position
0693          *         based one (vs. a timer based)
0694          */
0695         bool isPositionBased()
0696         {
0697             return (canAbsMove || canRelMove || (m_FocusAlgorithm == FOCUS_LINEAR) || (m_FocusAlgorithm == FOCUS_LINEAR1PASS));
0698         }
0699         void resetButtons();
0700 
0701         /**
0702          * @brief returns whether the Aberration Inspector can be used or not
0703          * @return can / cant be started
0704          */
0705         bool canAbInsStart();
0706         void stop(FocusState completionState = FOCUS_ABORTED);
0707 
0708         void initView();
0709 
0710         /** @brief Sets the plot vectors for Analyze after Autofocus. Used by Linear and Linear1Pass
0711          */
0712         void updatePlotPosition();
0713 
0714         /**
0715          * @brief prepareCapture Set common settings for capture for focus module
0716          * @param targetChip target Chip
0717          */
0718         void prepareCapture(ISD::CameraChip *targetChip);
0719 
0720         // HFR / FWHM
0721         void setHFRComplete();
0722 
0723         // Sets the star algorithm and enables/disables various UI inputs.
0724         void setFocusDetection(StarAlgorithm starAlgorithm);
0725 
0726         // Sets the algorithm and enables/disables various UI inputs.
0727         void setFocusAlgorithm(Algorithm algorithm);
0728 
0729         void setCurveFit(CurveFitting::CurveFit curvefit);
0730 
0731         void setStarMeasure(StarMeasure starMeasure);
0732         void setStarPSF(StarPSF starPSF);
0733         void setStarUnits(StarUnits starUnits);
0734         void setWalk(FocusWalk focusWalk);
0735         double calculateStarWeight(const bool useWeights, const std::vector<double> values);
0736         bool boxOverlap(const QPair<int, int> b1Start, const QPair<int, int> b1End, const QPair<int, int> b2Start,
0737                         const QPair<int, int> b2End);
0738         double getStarUnits(const StarMeasure starMeasure, const StarUnits starUnits);
0739         // Calculate the CFZ of the current focus camera
0740         double calcCameraCFZ();
0741 
0742         // Calculate the CFZ from the screen parameters
0743         void calcCFZ();
0744 
0745         // Static data for filter's midpoint wavelength changed so update CFZ
0746         void wavelengthChanged();
0747 
0748         // Reset the CFZ parameters from the current Optical Train
0749         void resetCFZToOT();
0750 
0751         // Setup the Focus Advisor recommendations
0752         void focusAdvisorSetup();
0753 
0754         // Update parameters based on Focus Advisor recommendations
0755         void focusAdvisorAction();
0756 
0757         // Update parameters based on Focus Advisor recommendations
0758         void focusAdvisorHelp();
0759 
0760         // Move the focuser in (negative) or out (positive amount).
0761         bool changeFocus(int amount, bool updateDir = true);
0762 
0763         // Start up capture, or occasionally move focuser again, after current focus-move accomplished.
0764         void autoFocusProcessPositionChange(IPState state);
0765 
0766         // For the Linear algorithm, which always scans in (from higher position to lower position)
0767         // if we notice the new position is higher than the current position (that is, it is the start
0768         // of a new scan), we adjust the new position to be several steps further out than requested
0769         // and set focuserAdditionalMovement to the extra motion, so that after this motion completes
0770         // we will then scan back in (back to the originally requested position). This "overscan dance" is done
0771         // to reduce backlash on such movement changes and so that we've always focused in before capture.
0772         int adjustLinearPosition(int position, int newPosition, int overscan, bool updateDir);
0773 
0774         // Process the image to get star FWHMs
0775         void getFWHM(const QList<Edge *> &stars, double *FWHM, double *weight);
0776 
0777         // Process the image to get the Fourier Transform Power
0778         // If tile = -1 use the whole image; if mosaicTile is specified use just that
0779         void getFourierPower(double *fourierPower, double *weight, const int mosaicTile = -1);
0780 
0781         /**
0782          * @brief syncTrackingBoxPosition Sync the tracking box to the current selected star center
0783          */
0784         void syncTrackingBoxPosition();
0785 
0786         /** @internal Search for stars using the method currently configured, and return the consolidated HFR.
0787          * @param image_data is the FITS frame to work with.
0788          * @return the HFR of the star or field of stars in the frame, depending on the consolidation method, or -1 if it cannot be estimated.
0789          */
0790         void analyzeSources();
0791 
0792         /** @internal Add a new star measure (HFR, FWHM, etc) for the current focuser position.
0793          * @param newMeasure is the new measure (e.g. HFR, FWHM, etc) to consider for the current focuser position.
0794          * @return true if a new sample is required, else false.
0795          */
0796         bool appendMeasure(double newMeasure);
0797 
0798         /**
0799          * @brief completeAutofocusProcedure finishes off autofocus and emits a message for other modules.
0800          */
0801         void completeFocusProcedure(FocusState completionState, bool plot = true);
0802 
0803         /**
0804          * @brief activities to be executed after the configured settling time
0805          * @param completionState state the focuser completed with
0806          * @param autoFocusUsed is autofocus running?
0807          * @param buildOffsetsUsed is autofocus running as a result of build offsets
0808          */
0809         void settle(const FocusState completionState, const bool autoFocusUsed, const bool buildOffsetsUsed);
0810 
0811         void setLastFocusTemperature();
0812         void setLastFocusAlt();
0813         bool findTemperatureElement(const QSharedPointer<ISD::GenericDevice> &device);
0814 
0815         /**
0816          * @brief reset Adaptive Focus parameters
0817          * @param Adaptive Focus enabled
0818          */
0819         void resetAdaptiveFocus(bool enabled);
0820 
0821         void setupOpticalTrainManager();
0822         void refreshOpticalTrain();
0823 
0824         /**
0825          * @brief handleFocusMotionTimeout When focuser is command to go to a target position, we expect to receive a notification
0826          * that it arrived at the desired destination. If not, we command it again.
0827          */
0828         void handleFocusMotionTimeout();
0829 
0830         /**
0831          * @brief returns axis label based on measure selected
0832          * @param starMeasure the star measure beuing used
0833          */
0834         QString getyAxisLabel(StarMeasure starMeasure);
0835 
0836         /**
0837          * @brief disable input widgets at the start of an AF run
0838          * @param the widget to disable
0839          * @param whether to disable at the widget level or disable all the children
0840          */
0841         void AFDisable(QWidget * widget, const bool children);
0842 
0843         /**
0844          * @brief returns whether the Gain input field is enabled outside of autofocus and
0845          * whether logically is should be enabled during AF even though all input widgets are disabled
0846          */
0847         bool isFocusGainEnabled();
0848 
0849         /**
0850          * @brief returns whether the ISO input field is enabled outside of autofocus and
0851          * whether logically is should be enabled during AF even though all input widgets are disabled
0852          */
0853         bool isFocusISOEnabled();
0854 
0855         /**
0856          * @brief returns whether the SubFrame input field is enabled outside of autofocus and
0857          * whether logically is should be enabled during AF even though all input widgets are disabled
0858          */
0859         bool isFocusSubFrameEnabled();
0860 
0861         /**
0862          * @brief returns whether the optical train telescope has a central obstruction
0863          * @param scopeType is the type of telescope
0864          * @return whether scope has an obstruction
0865          */
0866         bool scopeHasObstruction(QString scopeType);
0867 
0868         /**
0869          * @brief Save the focus frame for later dubugging
0870          */
0871         void saveFocusFrame();
0872 
0873         /**
0874          * @brief Initialise donut processing
0875          */
0876         void initDonutProcessing();
0877 
0878         /**
0879          * @brief Reset donut processing
0880          */
0881         void resetDonutProcessing();
0882 
0883         /**
0884          * @brief Adjust Autofocus capture exposure based on user settings when using Donut Buster
0885          */
0886         void donutTimeDilation();
0887 
0888         /// Focuser device needed for focus operation
0889         ISD::Focuser *m_Focuser { nullptr };
0890         /// CCD device needed for focus operation
0891         ISD::Camera *m_Camera { nullptr };
0892         /// Optional device filter
0893         ISD::FilterWheel *m_FilterWheel { nullptr };
0894         /// Optional temperature source element
0895         INumber *currentTemperatureSourceElement {nullptr};
0896 
0897         /// Current filter position
0898         int currentFilterPosition { -1 };
0899         int fallbackFilterPosition { -1 };
0900         /// True if we need to change filter position and wait for result before continuing capture
0901         bool filterPositionPending { false };
0902         bool fallbackFilterPending { false };
0903 
0904         /// They're generic GDInterface because they could be either ISD::Camera or ISD::FilterWheel or ISD::Weather
0905         QList<QSharedPointer<ISD::GenericDevice>> m_TemperatureSources;
0906 
0907         /// Last Focus direction. Used by Iterative and Polynomial. NOTE: this does not take account of overscan
0908         /// so, e.g. an outward move will always by FOCUS_OUT even though overscan will move back in
0909         Direction m_LastFocusDirection { FOCUS_NONE };
0910         /// Keep track of the last requested steps
0911         uint32_t m_LastFocusSteps {0};
0912         /// What type of focusing are we doing right now?
0913         Type m_FocusType { FOCUS_MANUAL };
0914         /// Focus HFR & Centeroid algorithms
0915         StarAlgorithm m_FocusDetection { ALGORITHM_SEP };
0916         /// Focus Process Algorithm
0917         Algorithm m_FocusAlgorithm { FOCUS_LINEAR1PASS };
0918         /// Curve fit, default to Quadratic
0919         CurveFitting::CurveFit m_CurveFit { CurveFitting::FOCUS_QUADRATIC };
0920         /// Star measure to use
0921         StarMeasure m_StarMeasure { FOCUS_STAR_HFR };
0922         /// PSF to use
0923         StarPSF m_StarPSF { FOCUS_STAR_GAUSSIAN };
0924         /// Units to use when displaying HFR or FWHM
0925         StarUnits m_StarUnits { FOCUS_UNITS_PIXEL };
0926         /// Units to use when displaying HFR or FWHM
0927         FocusWalk m_FocusWalk { FOCUS_WALK_CLASSIC };
0928         /// Are we minimising or maximising?
0929         CurveFitting::OptimisationDirection m_OptDir { CurveFitting::OPTIMISATION_MINIMISE };
0930         /// The type of statistics to use
0931         Mathematics::RobustStatistics::ScaleCalculation m_ScaleCalc { Mathematics::RobustStatistics::SCALE_VARIANCE };
0932 
0933         /******************************************
0934          * "Measure" variables, HFR, FWHM, numStars
0935          ******************************************/
0936 
0937         /// Current HFR value just fetched from FITS file
0938         double currentHFR { INVALID_STAR_MEASURE };
0939         double currentFWHM { INVALID_STAR_MEASURE };
0940         double currentNumStars { INVALID_STAR_MEASURE };
0941         double currentFourierPower { INVALID_STAR_MEASURE };
0942         double currentMeasure { INVALID_STAR_MEASURE };
0943         double currentWeight { 0 };
0944         /// Last HFR value recorded
0945         double lastHFR { 0 };
0946         /// If (currentHFR > deltaHFR) we start the autofocus process.
0947         double minimumRequiredHFR { INVALID_STAR_MEASURE };
0948         /// Maximum HFR recorded
0949         double maxHFR { 1 };
0950         /// Is HFR increasing? We're going away from the sweet spot! If HFRInc=1, we re-capture just to make sure HFR calculations are correct, if HFRInc > 1, we switch directions
0951         int HFRInc { 0 };
0952         /// If HFR decreasing? Well, good job. Once HFR start decreasing, we can start calculating HFR slope and estimating our next move.
0953         int HFRDec { 0 };
0954 
0955         /****************************
0956          * Absolute position focusers
0957          ****************************/
0958         /// Absolute focus position
0959         int currentPosition { 0 };
0960         /// Motion state of the absolute focuser
0961         IPState currentPositionState {IPS_IDLE};
0962         /// What was our position before we started the focus process?
0963         int initialFocuserAbsPosition { -1 };
0964         /// Pulse duration in ms for relative focusers that only support timers, or the number of ticks in a relative or absolute focuser
0965         int pulseDuration { 1000 };
0966         /// Does the focuser support absolute motion?
0967         bool canAbsMove { false };
0968         /// Does the focuser support relative motion?
0969         bool canRelMove { false };
0970         /// Does the focuser support timer-based motion?
0971         bool canTimerMove { false };
0972         /// Maximum range of motion for our lovely absolute focuser
0973         double absMotionMax { 0 };
0974         /// Minimum range of motion for our lovely absolute focuser
0975         double absMotionMin { 0 };
0976         /// How many iterations have we completed now in our absolute autofocus algorithm? We can't go forever
0977         int absIterations { 0 };
0978         /// Current image mask
0979         ImageMaskType m_currentImageMask = FOCUS_MASK_NONE;
0980 
0981         /****************************
0982          * Misc. variables
0983          ****************************/
0984 
0985         /// Are we in the process of capturing an image?
0986         bool captureInProgress { false };
0987         /// Are we in the process of calculating HFR?
0988         bool hfrInProgress { false };
0989         // Was the frame modified by us? Better keep track since we need to return it to its previous state once we are done with the focus operation.
0990         //bool frameModified;
0991         /// Was the modified frame subFramed?
0992         bool subFramed { false };
0993         /// If the autofocus process fails, let's not ruin the capture session probably taking place in the next tab. Instead, we should restart it and try again, but we keep count until we hit MAXIMUM_RESET_ITERATIONS
0994         /// and then we truly give up.
0995         int resetFocusIteration { 0 };
0996         /// Which filter must we use once the autofocus process kicks in?
0997         int lockedFilterIndex { -1 };
0998         /// Keep track of what we're doing right now
0999         bool inAutoFocus { false };
1000         bool inFocusLoop { false };
1001         //bool inSequenceFocus { false };
1002         /// Keep track of request to retry or abort an AutoFocus run after focus position has been reset
1003         /// RESTART_NONE = normal operation, no restart
1004         /// RESTART_NOW = restart the autofocus routine
1005         /// RESTART_ABORT = when autofocus has been tried MAXIMUM_RESET_ITERATIONS times, abort the routine
1006         typedef enum { RESTART_NONE = 0, RESTART_NOW, RESTART_ABORT } FocusRestartState;
1007         FocusRestartState m_RestartState { RESTART_NONE };
1008         /// Did we reverse direction?
1009         bool reverseDir { false };
1010         /// Did the user or the auto selection process finish selecting our focus star?
1011         bool starSelected { false };
1012         /// Adjust the focus position to a target value
1013         bool inAdjustFocus { false };
1014         /// Build offsets is a special case of the Autofocus run
1015         bool inBuildOffsets { false };
1016         // Target frame dimensions
1017         //int fx,fy,fw,fh;
1018         /// If HFR=-1 which means no stars detected, we need to decide how many times should the re-capture process take place before we give up or reverse direction.
1019         int noStarCount { 0 };
1020         /// Track which upload mode the CCD is set to. If set to UPLOAD_LOCAL, then we need to switch it to UPLOAD_CLIENT in order to do focusing, and then switch it back to UPLOAD_LOCAL
1021         ISD::Camera::UploadMode rememberUploadMode { ISD::Camera::UPLOAD_CLIENT };
1022         /// Star measure (e.g. HFR, FWHM, etc) values for captured frames before averages
1023         QVector<double> starMeasureFrames;
1024         // Camera Fast Exposure
1025         bool m_RememberCameraFastExposure = { false };
1026         // Future Watch
1027         QFutureWatcher<bool> m_StarFinderWatcher;
1028         // R2 as a measure of how well the curve fits the datapoints. Passed to the V-curve graph for display
1029         double R2 = 0;
1030         // Counter to retry the auto focus run if the R2Limit has not been reached
1031         int R2Retries = 0;
1032         // Counter to retry starting auto focus if the focuser is still active
1033         int AFStartRetries = 0;
1034         // Autofocus run number - to help with debugging logs
1035         int m_AFRun = 0;
1036         /// Autofocus log file info.
1037         QStringList m_LogText;
1038         QFile m_FocusLogFile;
1039         QString m_FocusLogFileName;
1040         bool m_FocusLogEnabled { false };
1041 
1042         ITextVectorProperty *filterName { nullptr };
1043         INumberVectorProperty *filterSlot { nullptr };
1044 
1045         // Holds the superset of text values in combo-boxes that can have restricted options
1046         QStringList m_StarMeasureText;
1047         QStringList m_CurveFitText;
1048         QStringList m_FocusWalkText;
1049 
1050         // Holds the enabled state of widgets that is used to active functionality in focus
1051         // during Autofocus when the input interface is disabled
1052         bool m_FocusGainAFEnabled { false };
1053         bool m_FocusISOAFEnabled { false };
1054         bool m_FocusSubFrameAFEnabled { false };
1055 
1056         /****************************
1057          * Plot variables
1058          ****************************/
1059 
1060         /// Plot minimum positions
1061         double minPos { 1e6 };
1062         /// Plot maximum positions
1063         double maxPos { 0 };
1064         /// V curve plot points
1065         QVector<double> plot_position, plot_value;
1066         bool isVShapeSolution = false;
1067 
1068         /// State
1069         FocusState m_state { Ekos::FOCUS_IDLE };
1070         FocusState state() const
1071         {
1072             return m_state;
1073         }
1074         void setState(FocusState newState);
1075 
1076         /// CCD Chip frame settings
1077         QMap<ISD::CameraChip *, QVariantMap> frameSettings;
1078 
1079         /// Selected star coordinates
1080         QVector3D starCenter;
1081 
1082         // Remember last star center coordinates in case of timeout in manual select mode
1083         QVector3D rememberStarCenter;
1084 
1085         /// Focus Frame
1086         QSharedPointer<FITSView> m_FocusView;
1087 
1088         /// Star Select Timer
1089         QTimer waitStarSelectTimer;
1090 
1091         /// FITS Viewer in case user want to display in it instead of internal view
1092         QSharedPointer<FITSViewer> fv;
1093 
1094         /// Track star position and HFR to know if we're detecting bogus stars due to detection algorithm false positive results
1095         QVector<QVector3D> starsHFR;
1096 
1097         /// Relative Profile
1098         FocusProfilePlot *profilePlot { nullptr };
1099         QDialog *profileDialog { nullptr };
1100 
1101         /// Polynomial fitting.
1102         std::unique_ptr<PolynomialFit> polynomialFit;
1103 
1104         // Curve fitting for focuser movement.
1105         std::unique_ptr<CurveFitting> curveFitting;
1106 
1107         // Curve fitting for stars.
1108         std::unique_ptr<CurveFitting> starFitting;
1109 
1110         // FWHM processing.
1111         std::unique_ptr<FocusFWHM> focusFWHM;
1112 
1113         // Fourier Transform power processing.
1114         std::unique_ptr<FocusFourierPower> focusFourierPower;
1115 
1116         // Adaptive Focus processing.
1117         std::unique_ptr<AdaptiveFocus> adaptFocus;
1118 
1119         // Capture timers
1120         QTimer captureTimer;
1121         QTimer captureTimeout;
1122         uint8_t captureTimeoutCounter { 0 };
1123         uint8_t captureFailureCounter { 0 };
1124 
1125         // Gain Control
1126         double GainSpinSpecialValue { INVALID_VALUE };
1127 
1128         // Focus motion timer.
1129         QTimer m_FocusMotionTimer;
1130         uint8_t m_FocusMotionTimerCounter { 0 };
1131 
1132         // Focuser reconnect counter
1133         uint8_t m_FocuserReconnectCounter { 0 };
1134 
1135         // Set m_DebugFocuser = true to simulate a focuser failure
1136         bool m_DebugFocuser { false };
1137         uint16_t m_DebugFocuserCounter { 0 };
1138 
1139         // Guide Suspend
1140         bool m_GuidingSuspended { false };
1141 
1142         // Data
1143         QSharedPointer<FITSData> m_ImageData;
1144 
1145         // Linear focuser.
1146         std::unique_ptr<FocusAlgorithmInterface> linearFocuser;
1147         int focuserAdditionalMovement { 0 };
1148         bool focuserAdditionalMovementUpdateDir { true };
1149         int linearRequestedPosition { 0 };
1150 
1151         bool hasDeviation { false };
1152 
1153         //double observatoryTemperature { INVALID_VALUE };
1154         double m_LastSourceAutofocusTemperature { INVALID_VALUE };
1155         QSharedPointer<ISD::GenericDevice> m_LastSourceDeviceAutofocusTemperature;
1156         //TemperatureSource lastFocusTemperatureSource { NO_TEMPERATURE };
1157         double m_LastSourceAutofocusAlt { INVALID_VALUE };
1158 
1159         // Mount altitude value for logging
1160         double mountAlt { INVALID_VALUE };
1161 
1162         static constexpr uint8_t MAXIMUM_FLUCTUATIONS {10};
1163 
1164         QVariantMap m_Settings;
1165         QVariantMap m_GlobalSettings;
1166 
1167         // Dark Processor
1168         QPointer<DarkProcessor> m_DarkProcessor;
1169 
1170         QSharedPointer<FilterManager> m_FilterManager;
1171 
1172         // Maintain a list of disabled widgets when Autofocus is running that can be restored at the end of the run
1173         QVector <QWidget *> disabledWidgets;
1174 
1175         // Scope parameters of the active optical train
1176         double m_Aperture = 0.0f;
1177         double m_FocalLength = 0.0f;
1178         double m_FocalRatio = 0.0f;
1179         double m_Reducer = 0.0f;
1180         double m_CcdPixelSizeX = 0.0f;
1181         int m_CcdWidth = 0;
1182         int m_CcdHeight = 0;
1183         QString m_ScopeType;
1184 
1185         // Settings popup
1186         //std::unique_ptr<Ui::Settings> m_SettingsUI;
1187         //QPointer<QDialog> m_SettingsDialog;
1188         OpsFocusSettings *m_OpsFocusSettings { nullptr };
1189 
1190         // Process popup
1191         //std::unique_ptr<Ui::Process> m_ProcessUI;
1192         //QPointer<QDialog> m_ProcessDialog;
1193         OpsFocusProcess *m_OpsFocusProcess { nullptr };
1194 
1195         // Mechanics popup
1196         //std::unique_ptr<Ui::Mechanics> m_MechanicsUI;
1197         //QPointer<QDialog> m_MechanicsDialog;
1198         OpsFocusMechanics *m_OpsFocusMechanics { nullptr };
1199 
1200         // CFZ popup
1201         std::unique_ptr<Ui::focusCFZDialog> m_CFZUI;
1202         QPointer<QDialog> m_CFZDialog;
1203 
1204         // Focus Advisor popup
1205         std::unique_ptr<Ui::focusAdvisorDialog> m_AdvisorUI;
1206         QPointer<QDialog> m_AdvisorDialog;
1207 
1208         // CFZ
1209         double m_cfzSteps = 0.0f;
1210 
1211         // Focus Advisor
1212         // Camera
1213         double FAExposure = 0.0f;
1214         QString FABinning;
1215 
1216         // Settings tab
1217         bool FAAutoSelectStar = true;
1218         bool FADarkFrame = false;
1219         double FAFullFieldInnerRadius = 0.0;
1220         double FAFullFieldOuterRadius = 80.0;
1221         bool FAAdaptiveFocus = false;
1222         bool FAAdaptStartPos = false;
1223 
1224         // Process tab
1225         StarAlgorithm FAFocusDetection = ALGORITHM_SEP;
1226         QString FAFocusSEPProfile;
1227         Algorithm FAFocusAlgorithm = FOCUS_LINEAR1PASS;
1228         CurveFitting::CurveFit FACurveFit = CurveFitting::FOCUS_HYPERBOLA;
1229         StarMeasure FAStarMeasure = FOCUS_STAR_HFR;
1230         bool FAUseWeights = true;
1231         double FAFocusR2Limit = 0.8;
1232         bool FAFocusRefineCurveFit = false;
1233         int FAFocusFramesCount = 1;
1234 
1235         // Mechanics tab
1236         FocusWalk FAFocusWalk = FOCUS_WALK_CLASSIC;
1237         double FAFocusSettleTime = 1.0;
1238         double FAFocusMaxTravel = 0;
1239         int FAFocusCaptureTimeout = 30;
1240         int FAFocusMotionTimeout = 30;
1241 
1242         // Aberration Inspector
1243         void calculateAbInsData();
1244         bool m_abInsOn = false;
1245         int m_abInsRun = 0;
1246         QVector<int> m_abInsPosition;
1247         QVector<QVector<double>> m_abInsMeasure;
1248         QVector<QVector<double>> m_abInsWeight;
1249         QVector<QVector<int>> m_abInsNumStars;
1250         QVector<QPoint> m_abInsTileCenterOffset;
1251 
1252         // Donut Buster
1253         double m_donutOrigExposure = 0.0;
1254 };
1255 }