7#include "adaptivefocus.h" 
    8#include "focusadvisor.h" 
    9#include "focusadaptor.h" 
   10#include "focusalgorithms.h" 
   12#if defined(HAVE_OPENCV) 
   13#include "focusblurriness.h" 
   15#include "aberrationinspector.h" 
   16#include "aberrationinspectorutils.h" 
   18#include "kstarsdata.h" 
   20#include "stellarsolver.h" 
   23#include "ekos/guide/guide.h" 
   24#include "ekos/manager.h" 
   27#include "auxiliary/kspaths.h" 
   28#include "auxiliary/ksmessagebox.h" 
   31#include "ekos/auxiliary/darklibrary.h" 
   32#include "ekos/auxiliary/darkprocessor.h" 
   33#include "ekos/auxiliary/profilesettings.h" 
   34#include "ekos/auxiliary/opticaltrainmanager.h" 
   35#include "ekos/auxiliary/opticaltrainsettings.h" 
   36#include "ekos/auxiliary/filtermanager.h" 
   37#include "ekos/auxiliary/stellarsolverprofileeditor.h" 
   40#include "fitsviewer/fitsdata.h" 
   41#include "fitsviewer/fitsview.h" 
   42#include "fitsviewer/fitsviewer.h" 
   45#include "indi/indifilterwheel.h" 
   46#include "ksnotification.h" 
   47#include "kconfigdialog.h" 
   49#include <basedevice.h> 
   50#include <gsl/gsl_fit.h> 
   51#include <gsl/gsl_vector.h> 
   52#include <gsl/gsl_min.h> 
   54#include <ekos_focus_debug.h> 
   55#include <config-kstars.h> 
   59#ifdef HAVE_DATAVISUALIZATION 
   60#include "aberrationinspector.h" 
   61#include "aberrationinspectorutils.h" 
   64#define MAXIMUM_ABS_ITERATIONS     51 
   65#define MAXIMUM_RESET_ITERATIONS   3 
   66#define MAXIMUM_RESTART_ITERATIONS 3 
   67#define AUTO_STAR_TIMEOUT          45000 
   68#define MINIMUM_PULSE_TIMER        32 
   69#define MAX_RECAPTURE_RETRIES      3 
   70#define MINIMUM_POLY_SOLUTIONS     2 
   74Focus::Focus(
int id) : QWidget()
 
   80    m_opsDialogName = 
QString(
"focussettings %1").
arg(
id);
 
  101    loadGlobalSettings();
 
  104    connectSyncSettings();
 
  106    connect(focusAdvisor.get(), &FocusAdvisor::newStage, 
this, &Focus::newFocusAdvisorStage);
 
  107    connect(focusAdvisor.get(), &FocusAdvisor::newMessage, 
this, &Focus::newFocusAdvisorMessage);
 
  114    for (
auto &button : qButtons)
 
  115        button->setAutoDefault(
false);
 
  117    appendLogText(
i18n(
"Idle."));
 
  120    m_FocusMotionTimer.setInterval(m_OpsFocusMechanics->focusMotionTimeout->value() * 1000);
 
  121    m_FocusMotionTimer.setSingleShot(
true);
 
  124    m_OpsFocusProcess->editFocusProfile->setIcon(
QIcon::fromTheme(
"document-edit"));
 
  129        KConfigDialog *optionsEditor = new KConfigDialog(this, 
"OptionsProfileEditor", Options::self());
 
  130        optionsProfileEditor = new StellarSolverProfileEditor(this, Ekos::FocusProfiles, optionsEditor);
 
  132        optionsEditor->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
 
  134        KPageWidgetItem *mainPage = optionsEditor->addPage(optionsProfileEditor, i18n(
"Focus Options Profile Editor"));
 
  135        mainPage->setIcon(QIcon::fromTheme(
"configure"));
 
  136        connect(optionsProfileEditor, &StellarSolverProfileEditor::optionsProfilesUpdated, this, &Focus::loadStellarSolverProfiles);
 
  137        optionsProfileEditor->loadProfile(m_OpsFocusProcess->focusSEPProfile->currentText());
 
  138        optionsEditor->show();
 
  141    loadStellarSolverProfiles();
 
  155    m_DarkProcessor = 
new DarkProcessor(
this);
 
  157    connect(m_DarkProcessor, &DarkProcessor::darkFrameCompleted, 
this, [
this](
bool completed)
 
  159        m_OpsFocusSettings->useFocusDarkFrame->setChecked(completed);
 
  160        m_FocusView->setProperty(
"suspended", 
false);
 
  163            m_FocusView->rescale(ZOOM_KEEP_LEVEL);
 
  164            m_FocusView->updateFrame();
 
  166        setCaptureComplete();
 
  170    setupOpticalTrainManager();
 
  174    connectFilterManager();
 
  178void Focus::prepareGUI()
 
  188    m_OpsFocusSettings = 
new OpsFocusSettings(opsDialogName());
 
  196    m_OpsFocusProcess = 
new OpsFocusProcess(opsDialogName());
 
  197    page = dialog->
addPage(m_OpsFocusProcess, 
i18n(
"Process"), 
nullptr, 
i18n(
"Focus Process"), 
false);
 
  200    m_OpsFocusMechanics = 
new OpsFocusMechanics(opsDialogName());
 
  201    page = dialog->
addPage(m_OpsFocusMechanics, 
i18n(
"Mechanics"), 
nullptr, 
i18n(
"Focus Mechanics"), 
false);
 
  205    m_CFZDialog = 
new QDialog(
this);
 
  206    m_CFZUI.reset(
new Ui::focusCFZDialog());
 
  207    m_CFZUI->setupUi(m_CFZDialog);
 
  213    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
 
  214    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
 
  215    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
 
  216    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
 
  217    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
 
  218    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusThreshold);
 
  219    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
 
  220    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
 
  221    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
 
  222    m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusTolerance);
 
  223    delete m_OpsFocusProcess->gridLayoutProcessBucket;
 
  226    m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutStepsLabel,
 
  227            m_OpsFocusMechanics->focusNumStepsLabel);
 
  228    m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutSteps,
 
  229            m_OpsFocusMechanics->focusNumSteps);
 
  233    for (
int i = 0; i < m_OpsFocusProcess->focusStarMeasure->count(); i++)
 
  234        m_StarMeasureText.append(m_OpsFocusProcess->focusStarMeasure->itemText(i));
 
  235    for (
int i = 0; i < m_OpsFocusProcess->focusCurveFit->count(); i++)
 
  236        m_CurveFitText.append(m_OpsFocusProcess->focusCurveFit->itemText(i));
 
  237    for (
int i = 0; i < m_OpsFocusMechanics->focusWalk->count(); i++)
 
  238        m_FocusWalkText.append(m_OpsFocusMechanics->focusWalk->itemText(i));
 
  243    QString savedOptionsProfiles = 
QDir(KSPaths::writableLocation(
 
  247        m_StellarSolverProfiles = StellarSolver::loadSavedOptionsProfiles(savedOptionsProfiles);
 
  248        addMissingStellarSolverProfile(savedOptionsProfiles, FOCUS_DEFAULT_NAME);
 
  249        addMissingStellarSolverProfile(savedOptionsProfiles, FOCUS_DEFAULT_DONUT_NAME);
 
  252        m_StellarSolverProfiles = getDefaultFocusOptionsProfiles();
 
  253    m_OpsFocusProcess->focusSEPProfile->clear();
 
  254    for(
auto ¶m : m_StellarSolverProfiles)
 
  255        m_OpsFocusProcess->focusSEPProfile->addItem(param.listName);
 
  256    auto profile = m_Settings[
"focusSEPProfile"];
 
  257    if (profile.isValid())
 
  258        m_OpsFocusProcess->focusSEPProfile->setCurrentText(profile.toString());
 
 
  261void Focus::addMissingStellarSolverProfile(
const QString profilePath, 
const QString profile)
 
  263    for(
auto params : m_StellarSolverProfiles)
 
  265        if (params.listName == profile)
 
  271    SSolver::Parameters params;
 
  272    if (profile == FOCUS_DEFAULT_DONUT_NAME)
 
  273        params = getFocusOptionsProfileDefaultDonut();
 
  274    else if (profile == FOCUS_DEFAULT_NAME)
 
  275        params = getFocusOptionsProfileDefault();
 
  279    settings.beginGroup(params.listName);
 
  285        settings.setValue(it.key(), it.value());
 
  289    m_StellarSolverProfiles.append(params);
 
  295    for (
auto param : m_StellarSolverProfiles)
 
  296        profiles << param.listName;
 
 
  304    if (focusingWidget->parent() == 
nullptr)
 
  305        toggleFocusingWidgetFullScreen();
 
  310    if (m_Camera && m_Camera->isConnected())
 
  312        ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
  317            targetChip->resetFrame();
 
  320            targetChip->getFrame(&
x, &
y, &w, &h);
 
  322            qCDebug(KSTARS_EKOS_FOCUS) << 
"Frame is reset. X:" << 
x << 
"Y:" << 
y << 
"W:" << w << 
"H:" << h << 
"binX:" << 1 << 
"binY:" <<
 
  325            QVariantMap settings;
 
  330            settings[
"binx"]          = 1;
 
  331            settings[
"biny"]          = 1;
 
  332            frameSettings[targetChip] = settings;
 
  334            starSelected = 
false;
 
  338            m_FocusView->setTrackingBox(
QRect());
 
  339            checkMosaicMaskLimits();
 
 
  347        return m_Camera->getDeviceName();
 
 
  372        case FOCUS_CHANGING_FILTER:
 
  377    ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
  378    if (targetChip && targetChip->isCapturing())
 
  383        focusBinning->setEnabled(targetChip->canBin());
 
  384        m_OpsFocusSettings->focusSubFrame->setEnabled(targetChip->canSubframe());
 
  385        if (targetChip->canBin())
 
  387            int subBinX = 1, subBinY = 1;
 
  388            focusBinning->clear();
 
  389            targetChip->getMaxBin(&subBinX, &subBinY);
 
  390            for (
int i = 1; i <= subBinX; i++)
 
  391                focusBinning->addItem(
QString(
"%1x%2").arg(i).arg(i));
 
  393            auto binning = m_Settings[
"focusBinning"];
 
  394            if (binning.isValid())
 
  395                focusBinning->setCurrentText(binning.toString());
 
  399        liveVideoB->setEnabled(m_Camera->hasVideoStream());
 
  400        if (m_Camera->hasVideoStream())
 
  401            setVideoStreamEnabled(m_Camera->isStreamingEnabled());
 
 
  413    if (m_Camera == 
nullptr)
 
  416    auto targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
  417    if (targetChip == 
nullptr || (targetChip && targetChip->isCapturing()))
 
  420    auto isoList = targetChip->getISOList();
 
  423    if (isoList.isEmpty())
 
  425        focusISO->setEnabled(
false);
 
  426        ISOLabel->setEnabled(
false);
 
  430        focusISO->setEnabled(
true);
 
  431        ISOLabel->setEnabled(
true);
 
  432        focusISO->addItems(isoList);
 
  433        focusISO->setCurrentIndex(targetChip->getISOIndex());
 
  436    bool hasGain = m_Camera->hasGain();
 
  437    gainLabel->setEnabled(hasGain);
 
  438    focusGain->setEnabled(hasGain && m_Camera->getGainPermission() != IP_RO);
 
  441        double gain = 0, min = 0, max = 0, step = 1;
 
  442        m_Camera->getGainMinMaxStep(&min, &max, &step);
 
  443        if (m_Camera->getGain(&gain))
 
  446            GainSpinSpecialValue = min - step;
 
  447            focusGain->setRange(GainSpinSpecialValue, max);
 
  448            focusGain->setSpecialValueText(
i18n(
"--"));
 
  450                focusGain->setSingleStep(step);
 
  452            auto defaultGain = m_Settings[
"focusGain"];
 
  453            if (defaultGain.isValid())
 
  454                focusGain->setValue(defaultGain.toDouble());
 
  456                focusGain->setValue(GainSpinSpecialValue);
 
 
  465    if (m_Camera == 
nullptr)
 
  468    auto targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
  469    if (targetChip == 
nullptr || (targetChip && targetChip->isCapturing()))
 
  472    m_OpsFocusSettings->focusSubFrame->setEnabled(targetChip->canSubframe());
 
  474    if (frameSettings.contains(targetChip) == 
false)
 
  477        if (targetChip->getFrame(&
x, &
y, &w, &h))
 
  479            int binx = 1, biny = 1;
 
  480            targetChip->getBinning(&binx, &biny);
 
  483                int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
 
  484                targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
 
  486                QVariantMap settings;
 
  488                settings[
"x"]    = m_OpsFocusSettings->focusSubFrame->isChecked() ? 
x : minX;
 
  489                settings[
"y"]    = m_OpsFocusSettings->focusSubFrame->isChecked() ? 
y : minY;
 
  490                settings[
"w"]    = m_OpsFocusSettings->focusSubFrame->isChecked() ? w : maxW;
 
  491                settings[
"h"]    = m_OpsFocusSettings->focusSubFrame->isChecked() ? h : maxH;
 
  492                settings[
"binx"] = binx;
 
  493                settings[
"biny"] = biny;
 
  495                frameSettings[targetChip] = settings;
 
 
  503    if (m_FilterWheel && m_FilterWheel == device)
 
  510        m_FilterWheel->disconnect(
this);
 
  512    m_FilterWheel = device;
 
  516        connect(m_FilterWheel, &ISD::ConcreteDevice::Connected, 
this, [
this]()
 
  518            FilterPosLabel->setEnabled(
true);
 
  519            focusFilter->setEnabled(
true);
 
  520            filterManagerB->setEnabled(
true);
 
  522        connect(m_FilterWheel, &ISD::ConcreteDevice::Disconnected, 
this, [
this]()
 
  524            FilterPosLabel->setEnabled(
false);
 
  525            focusFilter->setEnabled(
false);
 
  526            filterManagerB->setEnabled(
false);
 
  530    auto isConnected = m_FilterWheel && m_FilterWheel->isConnected();
 
  531    FilterPosLabel->setEnabled(isConnected);
 
  532    focusFilter->setEnabled(isConnected);
 
  533    filterManagerB->setEnabled(isConnected);
 
  535    FilterPosLabel->setEnabled(
true);
 
  536    focusFilter->setEnabled(
true);
 
 
  544    defaultFocusTemperatureSource->blockSignals(
true);
 
  545    m_TemperatureSources = temperatureSources;
 
  547    defaultFocusTemperatureSource->clear();
 
  548    for (
auto device : temperatureSources)
 
  552        defaultFocusTemperatureSource->addItem(device->getDeviceName());
 
  554    defaultFocusTemperatureSource->blockSignals(
false);
 
  556    auto targetSource = m_Settings[
"defaultFocusTemperatureSource"];
 
  557    if (targetSource.isValid())
 
 
  566        source = defaultFocusTemperatureSource->currentText();
 
  567        if (source.isEmpty())
 
  573    for (
auto &oneSource : m_TemperatureSources)
 
  575        if (oneSource->getDeviceName() == source)
 
  577            currentSource = oneSource;
 
  582    m_LastSourceDeviceAutofocusTemperature = currentSource;
 
  589    for (
const auto &oneSource : m_TemperatureSources)
 
  593    if (findTemperatureElement(currentSource))
 
  595        defaultFocusTemperatureSource->setCurrentText(name);
 
  596        m_LastSourceAutofocusTemperature = currentTemperatureSourceElement->value;
 
  597        absoluteTemperatureLabel->setText(
QString(
"%1 °C").arg(currentTemperatureSourceElement->value, 0, 
'f', 2));
 
  598        deltaTemperatureLabel->setText(
QString(
"%1 °C").arg(0.0, 0, 
'f', 2));
 
  602        m_LastSourceAutofocusTemperature = INVALID_VALUE;
 
 
  615    auto temperatureProperty = device->getProperty(
"FOCUS_TEMPERATURE");
 
  616    if (!temperatureProperty)
 
  617        temperatureProperty = device->getProperty(
"CCD_TEMPERATURE");
 
  618    if (temperatureProperty)
 
  620        currentTemperatureSourceElement = temperatureProperty.getNumber()->at(0);
 
  624    temperatureProperty = device->getProperty(
"WEATHER_PARAMETERS");
 
  625    if (temperatureProperty)
 
  627        for (
int i = 0; i < temperatureProperty.getNumber()->count(); i++)
 
  629            if (strstr(temperatureProperty.getNumber()->at(i)->getName(), 
"_TEMPERATURE"))
 
  631                currentTemperatureSourceElement = temperatureProperty.getNumber()->at(i);
 
  643        return m_FilterWheel->getDeviceName();
 
 
  653        focusFilter->setCurrentText(filter);
 
 
  662    return focusFilter->currentText();
 
  667    focusFilter->clear();
 
  671        FilterPosLabel->setEnabled(
false);
 
  672        focusFilter->setEnabled(
false);
 
  673        filterManagerB->setEnabled(
false);
 
  677            m_FilterManager->disconnect(
this);
 
  679            m_FilterManager.reset();
 
  684    FilterPosLabel->setEnabled(
true);
 
  685    focusFilter->setEnabled(
true);
 
  686    filterManagerB->setEnabled(
true);
 
  688    setupFilterManager();
 
  690    focusFilter->addItems(m_FilterManager->getFilterLabels());
 
  692    currentFilterPosition = m_FilterManager->getFilterPosition();
 
  694    focusFilter->setCurrentIndex(currentFilterPosition - 1);
 
  696    focusExposure->setValue(m_FilterManager->getFilterExposure());
 
 
  701    if (m_Focuser && m_Focuser == device)
 
  708        m_Focuser->disconnect(
this);
 
  714        connect(m_Focuser, &ISD::ConcreteDevice::Connected, 
this, [
this]()
 
  718        connect(m_Focuser, &ISD::ConcreteDevice::Disconnected, 
this, [
this]()
 
  725    emit focuserChanged(m_focuserId, device != 
nullptr);
 
 
  732        return m_Focuser->getDeviceName();
 
 
  742            m_FilterManager->setFocusReady(
false);
 
  743        canAbsMove = canRelMove = canTimerMove = 
false;
 
  745        setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
 
  750        m_FilterManager->setFocusReady(m_Focuser->isConnected());
 
  752    hasDeviation = m_Focuser->hasDeviation();
 
  754    canAbsMove = m_Focuser->canAbsMove();
 
  758        getAbsFocusPosition();
 
  761            m_FilterManager->setFocusAbsolutePosition(currentPosition);
 
  763        absTicksSpin->setEnabled(
true);
 
  764        absTicksLabel->setEnabled(
true);
 
  765        startGotoB->setEnabled(
true);
 
  768        if (absTicksSpin->value() <= 0)
 
  769            absTicksSpin->setValue(currentPosition);
 
  773        absTicksSpin->setEnabled(
false);
 
  774        absTicksLabel->setEnabled(
false);
 
  775        startGotoB->setEnabled(
false);
 
  778    canRelMove = m_Focuser->canRelMove();
 
  783    if (canAbsMove == 
false && canRelMove == 
true)
 
  785        currentPosition = 50000;
 
  786        absMotionMax    = 100000;
 
  790    canTimerMove = m_Focuser->canTimerMove();
 
  796    if (!canAbsMove && !canRelMove && canTimerMove)
 
  798        currentPosition = 50000;
 
  799        absMotionMax    = 100000;
 
  803    m_FocusType = (canRelMove || canAbsMove || canTimerMove) ? FOCUS_AUTO : FOCUS_MANUAL;
 
  804    profilePlot->setFocusAuto(m_FocusType == FOCUS_AUTO);
 
  806    bool hasBacklash = m_Focuser->hasBacklash();
 
  807    m_OpsFocusMechanics->focusBacklash->setEnabled(hasBacklash);
 
  808    m_OpsFocusMechanics->focusBacklash->disconnect(
this);
 
  811        double min = 0, max = 0, step = 0;
 
  812        m_Focuser->getMinMaxStep(
"FOCUS_BACKLASH_STEPS", 
"FOCUS_BACKLASH_VALUE", &min, &max, &step);
 
  813        m_OpsFocusMechanics->focusBacklash->setMinimum(min);
 
  814        m_OpsFocusMechanics->focusBacklash->setMaximum(max);
 
  815        m_OpsFocusMechanics->focusBacklash->setSingleStep(step);
 
  816        m_OpsFocusMechanics->focusBacklash->setValue(m_Focuser->getBacklash());
 
  818                this, [
this](
int value)
 
  822                if (m_Focuser->getBacklash() == value)
 
  828                m_Focuser->setBacklash(value);
 
  837        m_OpsFocusMechanics->focusBacklash->setValue(0);
 
  843    setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
 
 
  848    if (m_Camera && m_Camera == device)
 
  854    m_captureInProgress = 
false;
 
  857        m_Camera->disconnect(
this);
 
  863        connect(m_Camera, &ISD::ConcreteDevice::Connected, 
this, [
this]()
 
  867        connect(m_Camera, &ISD::ConcreteDevice::Disconnected, 
this, [
this]()
 
  873    auto isConnected = m_Camera && m_Camera->isConnected();
 
  874    focuserGroup->setEnabled(isConnected || (m_Focuser && m_Focuser->isConnected()));
 
  875    ccdGroup->setEnabled(isConnected);
 
  876    toolsGroup->setEnabled(isConnected);
 
  884    checkMosaicMaskLimits();
 
 
  888void Focus::getAbsFocusPosition()
 
  893    auto absMove = m_Focuser->getNumber(
"ABS_FOCUS_POSITION");
 
  897        const auto &it = absMove->at(0);
 
  898        currentPosition = 
static_cast<int>(it->getValue());
 
  899        absMotionMax    = it->getMax();
 
  900        absMotionMin    = it->getMin();
 
  902        absTicksSpin->setMinimum(it->getMin());
 
  903        absTicksSpin->setMaximum(it->getMax());
 
  904        absTicksSpin->setSingleStep(it->getStep());
 
  907        double const travel = std::abs(it->getMax() - it->getMin());
 
  908        m_OpsFocusMechanics->focusMaxTravel->setMaximum(travel);;
 
  912        m_OpsFocusMechanics->focusTicks->setMaximum(it->getMax() / 2);
 
  918    if (m_LastSourceAutofocusTemperature == INVALID_VALUE && m_LastSourceDeviceAutofocusTemperature
 
  919            && !currentTemperatureSourceElement )
 
  921        if( findTemperatureElement( m_LastSourceDeviceAutofocusTemperature ) )
 
  924            m_LastSourceAutofocusTemperature = currentTemperatureSourceElement->value;
 
  929    if (currentTemperatureSourceElement && currentTemperatureSourceElement->nvp->name == prop.getName())
 
  931        if (m_LastSourceAutofocusTemperature != INVALID_VALUE)
 
  933            delta = currentTemperatureSourceElement->value - m_LastSourceAutofocusTemperature;
 
  934            emit newFocusTemperatureDelta(abs(delta), currentTemperatureSourceElement->value, opticalTrain());
 
  938            emit newFocusTemperatureDelta(0, currentTemperatureSourceElement->value, opticalTrain());
 
  941        absoluteTemperatureLabel->setText(
QString(
"%1 °C").arg(currentTemperatureSourceElement->value, 0, 
'f', 2));
 
  942        deltaTemperatureLabel->setText(
QString(
"%1%2 °C").arg((delta > 0.0 ? 
"+" : 
"")).arg(delta, 0, 
'f', 2));
 
  944            deltaTemperatureLabel->setStyleSheet(
"color: lightgreen");
 
  946            deltaTemperatureLabel->setStyleSheet(
"color: lightcoral");
 
  948            deltaTemperatureLabel->setStyleSheet(
"color: lightblue");
 
 
  952void Focus::setLastFocusTemperature()
 
  954    m_LastSourceAutofocusTemperature = currentTemperatureSourceElement ? currentTemperatureSourceElement->value : INVALID_VALUE;
 
  957    deltaTemperatureLabel->setText(
QString(
"0 °C"));
 
  958    deltaTemperatureLabel->setStyleSheet(
"color: lightgreen");
 
  960    emit newFocusTemperatureDelta(0, -1e6, opticalTrain());
 
  963void Focus::setLastFocusAlt()
 
  965    if (mountAlt < 0.0 || mountAlt > 90.0)
 
  966        m_LastSourceAutofocusAlt = INVALID_VALUE;
 
  968        m_LastSourceAutofocusAlt = mountAlt;
 
  972void Focus::resetAdaptiveFocus(
bool enabled)
 
  975    Options::setFocusAdaptive(enabled);
 
  978        adaptFocus.reset(
new AdaptiveFocus(
this));
 
  979    adaptFocus->resetAdaptiveFocusCounters();
 
  986    adaptFocus->runAdaptiveFocus(currentPosition, filter());
 
 
  990void Focus::startAbIns()
 
  992    m_abInsOn = canAbInsStart();
 
  993    runAutoFocus(AutofocusReason::FOCUS_ABERRATION_INSPECTOR, 
"");
 
  997void Focus::manualStart()
 
  999    runAutoFocus(AutofocusReason::FOCUS_MANUAL, 
"");
 
 1011    m_AutofocusReason = autofocusReason;
 
 1012    m_AutofocusReasonInfo = reasonInfo;
 
 1013    if (m_Focuser == 
nullptr)
 
 1016        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_FOCUSER);
 
 1020    if (m_Camera == 
nullptr)
 
 1023        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_CAMERA);
 
 1027    if (!canAbsMove && !canRelMove && m_OpsFocusMechanics->focusTicks->value() <= MINIMUM_PULSE_TIMER)
 
 1029        appendLogText(
i18n(
"Starting pulse step is too low. Increase the step size to %1 or higher...",
 
 1030                           MINIMUM_PULSE_TIMER * 5));
 
 1031        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_LOW_PULSE);
 
 1048        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
 
 1056        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
 
 1060    if (inAdjustFocus || adaptFocus->inAdaptiveFocus())
 
 1062        QString str = inAdjustFocus ? 
i18n(
"Adjust Focus") : 
i18n(
"Adaptive Focus");
 
 1063        if (++m_StartRetries < MAXIMUM_RESTART_ITERATIONS)
 
 1065            appendLogText(
i18n(
"Autofocus start request - Waiting 10sec for %1 to complete.", str));
 
 1068                runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
 
 1073        appendLogText(
i18n(
"Discarding Autofocus start request - %1 in progress.", str));
 
 1074        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
 
 1078    inBuildOffsets = (autofocusReason == AutofocusReason::FOCUS_FILTER_OFFSETS);
 
 1079    if (autofocusReason == AutofocusReason::FOCUS_USER_REQUEST)
 
 1081        forceInSeqAF->setChecked(
false);
 
 1082        emit inSequenceAF(
false, opticalTrain());
 
 1091    if ((m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS) && checkAFOptimisation(autofocusReason))
 
 1095            completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_OPTIMISED_OUT);
 
 1101    m_LastFocusDirection = FOCUS_NONE;
 
 1103    waitStarSelectTimer.stop();
 
 1106    m_FocusMotionTimerCounter = 0;
 
 1107    m_FocusMotionTimer.stop();
 
 1108    m_FocusMotionTimer.setInterval(m_OpsFocusMechanics->focusMotionTimeout->value() * 1000);
 
 1111    m_FocuserReconnectCounter = 0;
 
 1114    m_FocuserReconnectCounter = 0;
 
 1115    m_DebugFocuserCounter = 0;
 
 1122    m_RestartState = RESTART_NONE;
 
 1130        getAbsFocusPosition();
 
 1131        pulseDuration = m_OpsFocusMechanics->focusTicks->value();
 
 1133    else if (canRelMove)
 
 1137        pulseDuration   = m_OpsFocusMechanics->focusTicks->value();
 
 1139        absMotionMax    = 100000;
 
 1144        pulseDuration   = m_OpsFocusMechanics->focusTicks->value();
 
 1146        absMotionMax    = 100000;
 
 1150    focuserAdditionalMovement = 0;
 
 1151    starMeasureFrames.clear();
 
 1163    profilePlot->clear();
 
 1164    FWHMOut->setText(
"");
 
 1166    qCInfo(KSTARS_EKOS_FOCUS)  << 
"Starting Autofocus " << m_AFRun
 
 1167                               << 
" on" << opticalTrain()
 
 1168                               << 
" Reason: " << AutofocusReasonStr[m_AutofocusReason]
 
 1169                               << 
" Reason Info: " << m_AutofocusReasonInfo
 
 1170                               << 
" CanAbsMove: " << (canAbsMove ? 
"yes" : 
"no" )
 
 1171                               << 
" CanRelMove: " << (canRelMove ? 
"yes" : 
"no" )
 
 1172                               << 
" CanTimerMove: " << (canTimerMove ? 
"yes" : 
"no" )
 
 1173                               << 
" Position:" << currentPosition
 
 1174                               << 
" Filter:" << filter()
 
 1175                               << 
" Exp:" << focusExposure->value()
 
 1176                               << 
" Bin:" << focusBinning->currentText()
 
 1177                               << 
" Gain:" << focusGain->value()
 
 1178                               << 
" ISO:" << focusISO->currentText();
 
 1179    qCInfo(KSTARS_EKOS_FOCUS)  << 
"Settings Tab." 
 1180                               << 
" Auto Select Star:" << ( m_OpsFocusSettings->focusAutoStarEnabled->isChecked() ? 
"yes" : 
"no" )
 
 1181                               << 
" Dark Frame:" << ( m_OpsFocusSettings->useFocusDarkFrame->isChecked() ? 
"yes" : 
"no" )
 
 1182                               << 
" Sub Frame:" << ( m_OpsFocusSettings->focusSubFrame->isChecked() ? 
"yes" : 
"no" )
 
 1183                               << 
" Box:" << m_OpsFocusSettings->focusBoxSize->value()
 
 1184                               << 
" Full frame:" << ( m_OpsFocusSettings->focusUseFullField->isChecked() ? 
"yes" : 
"no " )
 
 1185                               << 
" Focus Mask: " << (m_OpsFocusSettings->focusNoMaskRB->isChecked() ? 
"Use all stars" :
 
 1186                                       (m_OpsFocusSettings->focusRingMaskRB->isChecked() ? 
QString(
"Ring Mask: [%1%, %2%]").
 
 1187                                        arg(m_OpsFocusSettings->focusFullFieldInnerRadius->value()).
arg(m_OpsFocusSettings->focusFullFieldOuterRadius->value()) :
 
 1188                                        QString(
"Mosaic Mask: [%1%, space=%2px]").
 
 1189                                        arg(m_OpsFocusSettings->focusMosaicTileWidth->value()).
arg(m_OpsFocusSettings->focusMosaicSpace->value())))
 
 1190                               << 
" Suspend Guiding:" << ( m_OpsFocusSettings->focusSuspendGuiding->isChecked() ? 
"yes" : 
"no " )
 
 1191                               << 
" Guide Settle:" << m_OpsFocusSettings->focusGuideSettleTime->value()
 
 1192                               << 
" Display Units:" << m_OpsFocusSettings->focusUnits->currentText()
 
 1193                               << 
" AF Optimize:" << m_OpsFocusSettings->focusAFOptimize->value()
 
 1194                               << 
" Adaptive Focus:" << ( m_OpsFocusSettings->focusAdaptive->isChecked() ? 
"yes" : 
"no" )
 
 1195                               << 
" Min Move:" << m_OpsFocusSettings->focusAdaptiveMinMove->value()
 
 1196                               << 
" Adapt Start:" << ( m_OpsFocusSettings->focusAdaptStart->isChecked() ? 
"yes" : 
"no" )
 
 1197                               << 
" Max Total Move:" << m_OpsFocusSettings->focusAdaptiveMaxMove->value();
 
 1198    qCInfo(KSTARS_EKOS_FOCUS)  << 
"Process Tab." 
 1199                               << 
" Detection:" << m_OpsFocusProcess->focusDetection->currentText()
 
 1200                               << 
" SEP Profile:" << m_OpsFocusProcess->focusSEPProfile->currentText()
 
 1201                               << 
" Algorithm:" << m_OpsFocusProcess->focusAlgorithm->currentText()
 
 1202                               << 
" Curve Fit:" << m_OpsFocusProcess->focusCurveFit->currentText()
 
 1203                               << 
" Measure:" << m_OpsFocusProcess->focusStarMeasure->currentText()
 
 1204                               << 
" PSF:" << m_OpsFocusProcess->focusStarPSF->currentText()
 
 1205                               << 
" Use Weights:" << ( m_OpsFocusProcess->focusUseWeights->isChecked() ? 
"yes" : 
"no" )
 
 1206                               << 
" R2 Limit:" << m_OpsFocusProcess->focusR2Limit->value()
 
 1207                               << 
" Refine Curve Fit:" << ( m_OpsFocusProcess->focusRefineCurveFit->isChecked() ? 
"yes" : 
"no" )
 
 1208                               << 
" Average Over:" << m_OpsFocusProcess->focusFramesCount->value()
 
 1209                               << 
" Average HFR Check Over:" << m_OpsFocusProcess->focusHFRFramesCount->value()
 
 1210                               << 
" Num.of Rows:" << m_OpsFocusProcess->focusMultiRowAverage->value()
 
 1211                               << 
" Sigma:" << m_OpsFocusProcess->focusGaussianSigma->value()
 
 1212                               << 
" Threshold:" << m_OpsFocusProcess->focusThreshold->value()
 
 1213                               << 
" Kernel size:" << m_OpsFocusProcess->focusGaussianKernelSize->value()
 
 1214                               << 
" Tolerance:" << m_OpsFocusProcess->focusTolerance->value()
 
 1215                               << 
" Denoise:" << ( m_OpsFocusProcess->focusDenoise->isChecked() ? 
"yes" : 
"no" )
 
 1216                               << 
" Donut Buster:" << ( m_OpsFocusProcess->focusDonut->isChecked() ? 
"yes" : 
"no" )
 
 1217                               << 
" Donut Time Dilation:" << m_OpsFocusProcess->focusTimeDilation->value()
 
 1218                               << 
" Outlier Rejection:" << m_OpsFocusProcess->focusOutlierRejection->value()
 
 1219                               << 
" Scan Start Pos:" << ( m_OpsFocusProcess->focusScanStartPos->isChecked() ? 
"yes" : 
"no" )
 
 1220                               << 
" Scan Always On:" << ( m_OpsFocusProcess->focusScanAlwaysOn->isChecked() ? 
"yes" : 
"no" )
 
 1221                               << 
" Num Datapoints:" << m_OpsFocusProcess->focusScanDatapoints->value()
 
 1222                               << 
" Scan Step Factor:" << m_OpsFocusProcess->focusScanStepSizeFactor->value();
 
 1223    qCInfo(KSTARS_EKOS_FOCUS)  << 
"Mechanics Tab." 
 1224                               << 
" Initial Step Size:" << m_OpsFocusMechanics->focusTicks->value()
 
 1225                               << 
" Out Step Multiple:" << m_OpsFocusMechanics->focusOutSteps->value()
 
 1226                               << 
" Number Steps:" << m_OpsFocusMechanics->focusNumSteps->value()
 
 1227                               << 
" Max Travel:" << m_OpsFocusMechanics->focusMaxTravel->value()
 
 1228                               << 
" Max Step Size:" << m_OpsFocusMechanics->focusMaxSingleStep->value()
 
 1229                               << 
" Driver Backlash:" << m_OpsFocusMechanics->focusBacklash->value()
 
 1230                               << 
" AF Overscan:" << m_OpsFocusMechanics->focusAFOverscan->value()
 
 1231                               << 
" Overscan Delay:" << m_OpsFocusMechanics->focusOverscanDelay->value()
 
 1232                               << 
" Focuser Settle:" << m_OpsFocusMechanics->focusSettleTime->value()
 
 1233                               << 
" Walk:" << m_OpsFocusMechanics->focusWalk->currentText()
 
 1234                               << 
" Capture Timeout:" << m_OpsFocusMechanics->focusCaptureTimeout->value()
 
 1235                               << 
" Motion Timeout:" << m_OpsFocusMechanics->focusMotionTimeout->value();
 
 1236    qCInfo(KSTARS_EKOS_FOCUS)  << 
"CFZ Tab." 
 1237                               << 
" Algorithm:" << m_CFZUI->focusCFZAlgorithm->currentText()
 
 1238                               << 
" Tolerance:" << m_CFZUI->focusCFZTolerance->value()
 
 1239                               << 
" Tolerance (Ï„):" << m_CFZUI->focusCFZTau->value()
 
 1240                               << 
" Display:" << ( m_CFZUI->focusCFZDisplayVCurve->isChecked() ? 
"yes" : 
"no" )
 
 1241                               << 
" Wavelength (λ):" << m_CFZUI->focusCFZWavelength->value()
 
 1242                               << 
" Aperture (A):" << m_CFZUI->focusCFZAperture->value()
 
 1243                               << 
" Focal Ratio (f):" << m_CFZUI->focusCFZFNumber->value()
 
 1244                               << 
" Step Size:" << m_CFZUI->focusCFZStepSize->value()
 
 1245                               << 
" FWHM (θ):" << m_CFZUI->focusCFZSeeing->value();
 
 1247    const double temperature = (currentTemperatureSourceElement) ? currentTemperatureSourceElement->value : INVALID_VALUE;
 
 1248    emit autofocusStarting(temperature, filter(), m_AutofocusReason, m_AutofocusReasonInfo);
 
 1255    if (m_GuidingSuspended == 
false && m_OpsFocusSettings->focusSuspendGuiding->isChecked())
 
 1257        m_GuidingSuspended = 
true;
 
 1258        emit suspendGuiding();
 
 1262    setState(Ekos::FOCUS_PROGRESS);
 
 1264    KSNotification::event(
QLatin1String(
"FocusStarted"), 
i18n(
"Autofocus operation started"), KSNotification::Focus);
 
 1267    if (m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
 
 1269        m_AFfilter = filter();
 
 1270        int position = adaptFocus->adaptStartPosition(currentPosition, m_AFfilter);
 
 1272        curveFitting.reset(
new CurveFitting());
 
 1274        if (m_FocusAlgorithm == FOCUS_LINEAR1PASS)
 
 1277            starFitting.reset(
new CurveFitting());
 
 1278            focusFWHM.reset(
new FocusFWHM(m_ScaleCalc));
 
 1279            focusFourierPower.reset(
new FocusFourierPower(m_ScaleCalc));
 
 1280#if defined(HAVE_OPENCV) 
 1281            focusBlurriness.reset(
new FocusBlurriness());
 
 1284            initDonutProcessing();
 
 1286            if (initScanStartPos(
false, currentPosition))
 
 1289            if (m_AutofocusReason == FOCUS_FOCUS_ADVISOR)
 
 1291                focusAdvisor->initControl();
 
 1297        setupLinearFocuser(position);
 
 1298        if (!changeFocus(linearRequestedPosition - currentPosition))
 
 1299            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
 
 
 1307bool Focus::checkAFOptimisation(
const AutofocusReason autofocusReason)
 
 1309    bool dontRunAF = 
false;
 
 1310    inAFOptimise = 
false;
 
 1313    if (!m_FilterManager || m_OpsFocusSettings->focusAFOptimize->value() <= 0)
 
 1318    if (autofocusReason != FOCUS_FILTER &&
 
 1319            autofocusReason != FOCUS_TIME &&
 
 1320            autofocusReason != FOCUS_TEMPERATURE &&
 
 1321            autofocusReason != FOCUS_HFR_CHECK &&
 
 1322            autofocusReason != FOCUS_SCHEDULER)
 
 1326    QString filterToUse = filter();
 
 1327    QString lockFilter = m_FilterManager->getFilterLock(filterToUse);
 
 1328    if (lockFilter != NULL_FILTER && lockFilter != filterToUse)
 
 1329        filterToUse = lockFilter;
 
 1333    if (!m_FilterManager->getAFDatetime(filterToUse, lastAFDatetime))
 
 1335        qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"%1 unable to get last Autofocus run timestamp on %2")
 
 1336                                   .
arg(__FUNCTION__).
arg(filterToUse);
 
 1341    QDateTime now = KStarsData::Instance()->lt();
 
 1342    auto lastAFDelta = lastAFDatetime.
secsTo(now);
 
 1343    if (lastAFDelta > m_OpsFocusSettings->focusAFOptimize->value())
 
 1347    int position = currentPosition;
 
 1348    if (m_OpsFocusSettings->focusAdaptStart->isChecked())
 
 1349        position = adaptFocus->adaptStartPosition(currentPosition, filterToUse);
 
 1353        double lastTemp, lastAlt;
 
 1354        if(!m_FilterManager->getFilterAbsoluteFocusDetails(filterToUse, position, lastTemp, lastAlt))
 
 1357            qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"%1 unable to get last Autofocus info on %2")
 
 1358                                       .
arg(__FUNCTION__).
arg(filterToUse);
 
 1362        int minTravelLimit = qMax(0.0, currentPosition - m_OpsFocusMechanics->focusMaxTravel->value());
 
 1363        int maxTravelLimit = qMin(absMotionMax, currentPosition + m_OpsFocusMechanics->focusMaxTravel->value());
 
 1364        if (position < minTravelLimit || position > maxTravelLimit)
 
 1366            qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"%1 Bad last Autofocus solution found on %2")
 
 1367                                       .
arg(__FUNCTION__).
arg(position);
 
 1374    if (filterToUse != 
filter())
 
 1376        int filterOffset = m_FilterManager->getFilterOffset(
filter());
 
 1377        int filterToUseOffset = m_FilterManager->getFilterOffset(filterToUse);
 
 1378        if (filterOffset != INVALID_VALUE && filterToUseOffset != INVALID_VALUE)
 
 1379            position += filterOffset - filterToUseOffset;
 
 1382            qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"%1 unable to calculate filter offsets").
arg(__FUNCTION__);
 
 1388    if (abs(position - currentPosition) <= 1)
 
 1392        qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"Autofocus (%1) on %2 optimised out by Autofocus at %3")
 
 1393                                   .
arg(AutofocusReasonStr[autofocusReason]).
arg(filterToUse).
arg(lastAFDatetime.
toString());
 
 1398        if (changeFocus(position - currentPosition))
 
 1400            inAFOptimise = dontRunAF = 
true;
 
 1401            qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"Autofocus (%1) on %2 optimised out by Autofocus at %3." 
 1402                                                  " Current Position %4, Target Position %5")
 
 1403                                       .
arg(AutofocusReasonStr[autofocusReason]).
arg(filterToUse)
 
 1407            qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"%1 unable to move focuser... trying full Autofocus").
arg(__FUNCTION__);
 
 1412void Focus::setupLinearFocuser(
int initialPosition)
 
 1414    FocusAlgorithmInterface::FocusParams params(curveFitting.get(),
 
 1415            m_OpsFocusMechanics->focusMaxTravel->value(), m_OpsFocusMechanics->focusTicks->value(), initialPosition, absMotionMin,
 
 1416            absMotionMax, MAXIMUM_ABS_ITERATIONS, m_OpsFocusProcess->focusTolerance->value() / 100.0, m_AFfilter,
 
 1417            currentTemperatureSourceElement ? currentTemperatureSourceElement->value : INVALID_VALUE,
 
 1418            m_OpsFocusMechanics->focusOutSteps->value(), m_OpsFocusMechanics->focusNumSteps->value(),
 
 1419            m_FocusAlgorithm, m_OpsFocusMechanics->focusBacklash->value(), m_CurveFit, m_OpsFocusProcess->focusUseWeights->isChecked(),
 
 1420            m_StarMeasure, m_StarPSF, m_OpsFocusProcess->focusRefineCurveFit->isChecked(), m_FocusWalk,
 
 1421            m_OpsFocusProcess->focusDonut->isChecked(), m_OpsFocusProcess->focusOutlierRejection->value(), m_OptDir, m_ScaleCalc);
 
 1424        initialFocuserAbsPosition = initialPosition;
 
 1425    linearFocuser.reset(MakeLinearFocuser(params));
 
 1426    linearRequestedPosition = linearFocuser->initialPosition();
 
 1430void Focus::initDonutProcessing()
 
 1432    if (!m_OpsFocusProcess->focusDonut->isChecked())
 
 1435    m_donutOrigExposure = focusExposure->value();
 
 1439void Focus::resetDonutProcessing()
 
 1442    if (m_OpsFocusProcess->focusDonut->isChecked() && inAutoFocus)
 
 1443        focusExposure->setValue(m_donutOrigExposure);
 
 1446int Focus::adjustLinearPosition(
int position, 
int newPosition, 
int overscan, 
bool updateDir)
 
 1448    if (overscan > 0 && newPosition > position)
 
 1451        int adjustment = overscan;
 
 1452        qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"Linear: extending outward movement by overscan %1").
arg(adjustment);
 
 1454        if (newPosition + adjustment > absMotionMax)
 
 1455            adjustment = 
static_cast<int>(absMotionMax) - newPosition;
 
 1457        focuserAdditionalMovement = adjustment;
 
 1458        focuserAdditionalMovementUpdateDir = updateDir;
 
 1460        return newPosition + adjustment;
 
 1470    m_abortInProgress = 
true;
 
 1473        resetFocusIteration = MAXIMUM_RESET_ITERATIONS + 1;
 
 1475    if (captureTimer.isActive())
 
 1477        captureTimer.stop();
 
 1479    if (m_captureInProgress)
 
 1481        if (inAutoFocus == 
false && inFocusLoop == 
false)
 
 1483            captureB->setEnabled(
true);
 
 1484            stopFocusB->setEnabled(
false);
 
 1488        else if (inAutoFocus)
 
 1490            stopFocusB->setEnabled(
false);
 
 1500    if (m_starDetectInProgress)
 
 1502        stopFocusB->setEnabled(
false);
 
 1511    completeFocusProcedure(
abort ? Ekos::FOCUS_ABORTED : Ekos::FOCUS_FAILED, Ekos::FOCUS_FAIL_ABORT);
 
 
 1517    if (state() == FOCUS_IDLE || state() == FOCUS_COMPLETE || state() == FOCUS_FAILED || state() == FOCUS_ABORTED)
 
 1521    int old = resetFocusIteration;
 
 1525    resetFocusIteration = old;
 
 
 1531    if (state() <= FOCUS_ABORTED)
 
 1535    if (focusAdvisor->inFocusAdvisor())
 
 1537        focusAdvisor->stop();
 
 
 1543void Focus::processAbort()
 
 1545    bool focusLoop = inFocusLoop;
 
 1546    checkStopFocus(
true);
 
 1547    appendLogText(
i18n(
"Autofocus aborted."));
 
 1554void Focus::stop(Ekos::FocusState completionState)
 
 1556    Q_UNUSED(completionState);
 
 1557    qCDebug(KSTARS_EKOS_FOCUS) << 
"Stopping Focus";
 
 1559    captureTimeout.stop();
 
 1560    m_FocusMotionTimer.stop();
 
 1561    m_FocusMotionTimerCounter = 0;
 
 1562    m_FocuserReconnectCounter = 0;
 
 1564    opticalTrainCombo->setEnabled(
true);
 
 1565    trainB->setEnabled(
true);
 
 1566    resetDonutProcessing();
 
 1567    inAutoFocus = 
false;
 
 1568    inAdjustFocus = 
false;
 
 1569    adaptFocus->setInAdaptiveFocus(
false);
 
 1570    inBuildOffsets = 
false;
 
 1571    inAFOptimise = 
false;
 
 1572    inScanStartPos = 
false;
 
 1573    focusAdvisor->reset();
 
 1574    m_AutofocusReason = AutofocusReason::FOCUS_NONE;
 
 1575    m_AutofocusReasonInfo = 
"";
 
 1576    focuserAdditionalMovement = 0;
 
 1577    focuserAdditionalMovementUpdateDir = 
true;
 
 1578    inFocusLoop = 
false;
 
 1579    m_captureInProgress = 
false;
 
 1580    m_abortInProgress = 
false;
 
 1581    m_starDetectInProgress = 
false;
 
 1582    isVShapeSolution = 
false;
 
 1583    captureFailureCounter = 0;
 
 1584    minimumRequiredHFR = INVALID_STAR_MEASURE;
 
 1586    starMeasureFrames.clear();
 
 1596        disconnect(m_Camera, &ISD::Camera::error, 
this, &Ekos::Focus::processCaptureError);
 
 1598        if (rememberUploadMode != m_Camera->getUploadMode())
 
 1599            m_Camera->setUploadMode(rememberUploadMode);
 
 1602        if (m_RememberCameraFastExposure)
 
 1604            m_RememberCameraFastExposure = 
false;
 
 1605            m_Camera->setFastExposureEnabled(
true);
 
 1608        ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 1609        targetChip->abortExposure();
 
 1618    if (m_GuidingSuspended)
 
 1620        emit resumeGuiding();
 
 1621        m_GuidingSuspended = 
false;
 
 1627    if (m_abortInProgress)
 
 1630        m_captureInProgress = 
false;
 
 1631        qCDebug(KSTARS_EKOS_FOCUS) << 
"Abort AF: discarding capture request.";
 
 1637    if (settleTime > 0 && m_captureInProgress == 
false)
 
 1639        captureTimer.start(
static_cast<int>(settleTime * 1000));
 
 1643    if (m_captureInProgress)
 
 1645        qCWarning(KSTARS_EKOS_FOCUS) << 
"Capture called while already in progress. Capture is ignored.";
 
 1649    if (m_Camera == 
nullptr)
 
 1656    if (m_Camera->isConnected() == 
false)
 
 1664    captureTimeout.stop();
 
 1666    waitStarSelectTimer.stop();
 
 1668    ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 1670    if (m_Camera->isBLOBEnabled() == 
false)
 
 1672        m_Camera->setBLOBEnabled(
true);
 
 1675    if (focusFilter->currentIndex() != -1)
 
 1677        if (m_FilterWheel == 
nullptr)
 
 1683        if (m_FilterWheel->isConnected() == 
false)
 
 1693        int targetPosition = focusFilter->currentIndex() + 1;
 
 1694        if (!inBuildOffsets)
 
 1696            QString lockedFilter = m_FilterManager->getFilterLock(filter());
 
 1701            if (lockedFilter != 
"--" && lockedFilter != filter())
 
 1703                int lockedFilterIndex = focusFilter->findText(lockedFilter);
 
 1704                if (lockedFilterIndex >= 0)
 
 1707                    fallbackFilterPending = 
true;
 
 1708                    fallbackFilterPosition = targetPosition;
 
 1709                    targetPosition = lockedFilterIndex + 1;
 
 1714        filterPositionPending = (targetPosition != currentFilterPosition);
 
 1715        if (filterPositionPending)
 
 1720            FilterManager::FilterPolicy policy = (inAutoFocus) ?
 
 1721                                                 static_cast<FilterManager::FilterPolicy
>(FilterManager::CHANGE_POLICY) :
 
 1722                                                 static_cast<FilterManager::FilterPolicy
>(FilterManager::CHANGE_POLICY | FilterManager::OFFSET_POLICY);
 
 1723            m_FilterManager->setFilterPosition(targetPosition, policy);
 
 1726        else if (targetPosition != focusFilter->currentIndex() + 1)
 
 1727            focusFilter->setCurrentIndex(targetPosition - 1);
 
 1730    m_FocusView->setProperty(
"suspended", m_OpsFocusSettings->useFocusDarkFrame->isChecked());
 
 1731    prepareCapture(targetChip);
 
 1736    if (frameSettings.contains(targetChip))
 
 1738        QVariantMap settings = frameSettings[targetChip];
 
 1739        targetChip->setFrame(settings[
"x"].toInt(), settings[
"y"].toInt(), settings[
"w"].toInt(),
 
 1740                             settings[
"h"].toInt());
 
 1741        settings[
"binx"]          = (focusBinning->currentIndex() + 1);
 
 1742        settings[
"biny"]          = (focusBinning->currentIndex() + 1);
 
 1743        frameSettings[targetChip] = settings;
 
 1746    m_captureInProgress = 
true;
 
 1747    if (state() != FOCUS_PROGRESS)
 
 1748        setState(FOCUS_PROGRESS);
 
 1750    m_FocusView->setBaseSize(focusingWidget->size());
 
 1752    if (targetChip->capture(focusExposure->value()))
 
 1756        captureTimeout.start( (focusExposure->value() + m_OpsFocusMechanics->focusCaptureTimeout->value()) * 1000);
 
 1758        if (inFocusLoop == 
false)
 
 1763    else if (inAutoFocus)
 
 1765        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
 
 
 1771    if (m_Camera->getUploadMode() == ISD::Camera::UPLOAD_REMOTE)
 
 1773        rememberUploadMode = ISD::Camera::UPLOAD_REMOTE;
 
 1774        m_Camera->setUploadMode(ISD::Camera::UPLOAD_CLIENT);
 
 1778    if (m_Camera->isFastExposureEnabled())
 
 1780        m_RememberCameraFastExposure = 
true;
 
 1781        m_Camera->setFastExposureEnabled(
false);
 
 1784    m_Camera->setEncodingFormat(
"FITS");
 
 1785    targetChip->setBatchMode(
false);
 
 1786    targetChip->setBinning((focusBinning->currentIndex() + 1), (focusBinning->currentIndex() + 1));
 
 1787    targetChip->setCaptureMode(FITS_FOCUS);
 
 1788    targetChip->setFrameType(FRAME_LIGHT);
 
 1789    targetChip->setCaptureFilter(FITS_NONE);
 
 1791    if (isFocusISOEnabled() && focusISO->currentIndex() != -1 &&
 
 1792            targetChip->getISOIndex() != focusISO->currentIndex())
 
 1793        targetChip->setISOIndex(focusISO->currentIndex());
 
 1795    if (isFocusGainEnabled() && focusGain->value() != GainSpinSpecialValue)
 
 1796        m_Camera->setGain(focusGain->value());
 
 1801    if (currentPosition == absMotionMin)
 
 1806    focusInB->setEnabled(
false);
 
 1807    focusOutB->setEnabled(
false);
 
 1808    startGotoB->setEnabled(
false);
 
 1810        ms = m_OpsFocusMechanics->focusTicks->value();
 
 1815    if (currentPosition - ms <= absMotionMin)
 
 1817        ms = currentPosition - absMotionMin;
 
 1820    return changeFocus(-ms);
 
 
 1825    if (currentPosition == absMotionMax)
 
 1830    focusInB->setEnabled(
false);
 
 1831    focusOutB->setEnabled(
false);
 
 1832    startGotoB->setEnabled(
false);
 
 1834        ms = m_OpsFocusMechanics->focusTicks->value();
 
 1835    ms = m_OpsFocusMechanics->focusTicks->value();
 
 1840    if (currentPosition + ms >= absMotionMax)
 
 1842        ms = absMotionMax - currentPosition;
 
 1845    return changeFocus(ms);
 
 
 1850bool Focus::changeFocus(
int amount, 
bool updateDir)
 
 1854    if (inAutoFocus && abs(amount) <= 1)
 
 1856        if (m_RestartState == RESTART_NOW)
 
 1863            capture(m_OpsFocusMechanics->focusSettleTime->value());
 
 1868    if (m_Focuser == 
nullptr)
 
 1870        appendLogText(
i18n(
"Error: No Focuser detected."));
 
 1871        checkStopFocus(
true);
 
 1875    if (m_Focuser->isConnected() == 
false)
 
 1877        appendLogText(
i18n(
"Error: Lost connection to Focuser."));
 
 1878        checkStopFocus(
true);
 
 1882    const int newPosition = adjustLinearPosition(currentPosition, currentPosition + amount,
 
 1883                            m_OpsFocusMechanics->focusAFOverscan->value(),
 
 1885    if (newPosition == currentPosition)
 
 1888    const int newAmount = newPosition - currentPosition;
 
 1889    const int absNewAmount = abs(newAmount);
 
 1890    const bool focusingOut = newAmount > 0;
 
 1891    const QString dirStr = focusingOut ? 
i18n(
"outward") : 
i18n(
"inward");
 
 1894        m_LastFocusDirection = (focusingOut) ? FOCUS_OUT : FOCUS_IN;
 
 1897        m_Focuser->focusOut();
 
 1899        m_Focuser->focusIn();
 
 1902    m_FocusMotionTimer.start();
 
 1906        m_LastFocusSteps = newPosition;
 
 1907        m_Focuser->moveAbs(newPosition);
 
 1908        appendLogText(
i18n(
"Focusing %2 by %1 steps...", abs(absNewAmount), dirStr));
 
 1910    else if (canRelMove)
 
 1912        m_LastFocusSteps = absNewAmount;
 
 1913        m_Focuser->moveRel(absNewAmount);
 
 1914        appendLogText(
i18np(
"Focusing %2 by %1 step...", 
"Focusing %2 by %1 steps...", absNewAmount, dirStr));
 
 1918        m_LastFocusSteps = absNewAmount;
 
 1919        m_Focuser->moveByTimer(absNewAmount);
 
 1920        appendLogText(
i18n(
"Focusing %2 by %1 ms...", absNewAmount, dirStr));
 
 1926void Focus::handleFocusMotionTimeout()
 
 1946        qCDebug(KSTARS_EKOS_FOCUS) << 
"handleFocusMotionTimeout() called while not in AutoFocus";
 
 1950    m_FocusMotionTimerCounter++;
 
 1952    if (m_FocusMotionTimerCounter > 4)
 
 1955        appendLogText(
i18n(
"Focuser is still timing out. Aborting..."));
 
 1956        stop(Ekos::FOCUS_ABORTED);
 
 1959    else if (m_FocusMotionTimerCounter > 2)
 
 1961        QString focuser = m_Focuser->getDeviceName();
 
 1962        appendLogText(
i18n(
"Focus motion timed out (%1). Restarting focus driver %2", m_FocusMotionTimerCounter, focuser));
 
 1963        emit focuserTimedout(focuser);
 
 1967            Focus::reconnectFocuser(focuser);
 
 1972    if (!changeFocus(m_LastFocusSteps - currentPosition))
 
 1973        appendLogText(
i18n(
"Focus motion timed out (%1). Focusing to %2 steps...", m_FocusMotionTimerCounter, m_LastFocusSteps));
 
 1978    const bool useFullField = m_OpsFocusSettings->focusUseFullField->isChecked();
 
 1979    ImageMaskType masktype;
 
 1980    if (m_OpsFocusSettings->focusRingMaskRB->isChecked())
 
 1981        masktype = FOCUS_MASK_RING;
 
 1982    else if (m_OpsFocusSettings->focusMosaicMaskRB->isChecked())
 
 1983        masktype = FOCUS_MASK_MOSAIC;
 
 1985        masktype = FOCUS_MASK_NONE;
 
 1988    m_OpsFocusSettings->focusRingMaskRB->setEnabled(
useFullField);
 
 1989    m_OpsFocusSettings->focusMosaicMaskRB->setEnabled(
useFullField);
 
 1991    m_OpsFocusSettings->focusFullFieldInnerRadius->setEnabled(
useFullField && masktype == FOCUS_MASK_RING);
 
 1992    m_OpsFocusSettings->focusFullFieldOuterRadius->setEnabled(
useFullField && masktype == FOCUS_MASK_RING);
 
 1994    m_OpsFocusSettings->focusMosaicTileWidth->setEnabled(
useFullField && masktype == FOCUS_MASK_MOSAIC);
 
 1995    m_OpsFocusSettings->focusSpacerLabel->setEnabled(
useFullField && masktype == FOCUS_MASK_MOSAIC);
 
 1996    m_OpsFocusSettings->focusMosaicSpace->setEnabled(
useFullField && masktype == FOCUS_MASK_MOSAIC);
 
 1999    if (masktype == FOCUS_MASK_RING)
 
 2000        m_FocusView->setImageMask(
new ImageRingMask(m_OpsFocusSettings->focusFullFieldInnerRadius->value() / 100.0,
 
 2001                                  m_OpsFocusSettings->focusFullFieldOuterRadius->value() / 100.0));
 
 2002    else if (masktype == FOCUS_MASK_MOSAIC)
 
 2003        m_FocusView->setImageMask(
new ImageMosaicMask(m_OpsFocusSettings->focusMosaicTileWidth->value(),
 
 2004                                  m_OpsFocusSettings->focusMosaicSpace->value()));
 
 2006        m_FocusView->setImageMask(
nullptr);
 
 2008    checkMosaicMaskLimits();
 
 2009    m_currentImageMask = masktype;
 
 2010    startAbInsB->setEnabled(canAbInsStart());
 
 
 2015    m_FocuserReconnectCounter++;
 
 2017    if (m_Focuser && m_Focuser->getDeviceName() == 
focuser)
 
 2021        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_ERROR);
 
 2025    if (m_FocuserReconnectCounter > 12)
 
 2029        stop(Ekos::FOCUS_ABORTED);
 
 
 2042    if (data->property(
"chip").toInt() == ISD::CameraChip::GUIDE_CCD)
 
 2047        m_FocusView->loadData(data);
 
 2051        m_ImageData.reset();
 
 2053    captureTimeout.stop();
 
 2054    captureTimeoutCounter = 0;
 
 2055    m_MissingCameraCounter = 0;
 
 2057    ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 2059    disconnect(m_Camera, &ISD::Camera::error, 
this, &Ekos::Focus::processCaptureError);
 
 2061    if (m_ImageData && m_OpsFocusSettings->useFocusDarkFrame->isChecked())
 
 2063        QVariantMap settings = frameSettings[targetChip];
 
 2064        uint16_t offsetX     = settings[
"x"].toInt() / settings[
"binx"].toInt();
 
 2065        uint16_t offsetY     = settings[
"y"].toInt() / settings[
"biny"].toInt();
 
 2067        m_DarkProcessor->denoise(OpticalTrainManager::Instance()->
id(opticalTrainCombo->currentText()),
 
 2068                                 targetChip, m_ImageData, focusExposure->value(), offsetX, offsetY);
 
 2072    setCaptureComplete();
 
 
 2076void Focus::starDetectionFinished()
 
 2078    m_starDetectInProgress = 
false;
 
 2079    if (m_abortInProgress)
 
 2082        qCDebug(KSTARS_EKOS_FOCUS) << 
"Abort AF: discarding results from " << __FUNCTION__;
 
 2086    appendLogText(
i18n(
"Detection complete."));
 
 2089    double hfr = INVALID_STAR_MEASURE;
 
 2091    if (isStarMeasureStarBased())
 
 2093        appendLogText(
i18n(
"Detection complete."));
 
 2095        if (m_StarFinderWatcher.result() == 
false)
 
 2097            qCWarning(KSTARS_EKOS_FOCUS) << 
"Failed to extract any stars.";
 
 2101            if (m_OpsFocusSettings->focusUseFullField->isChecked())
 
 2103                m_FocusView->filterStars();
 
 2106                hfr = m_ImageData->getHFR(m_StarMeasure == FOCUS_STAR_HFR_ADJ ? HFR_ADJ_AVERAGE : HFR_AVERAGE);
 
 2110                m_FocusView->setTrackingBoxEnabled(
true);
 
 2115                if (starCenter.isNull() == 
false)
 
 2116                    hfr = m_ImageData->getHFR(starCenter.x(), starCenter.y());
 
 2120                    hfr = m_ImageData->getHFR(m_FocusDetection == ALGORITHM_SEP ? HFR_HIGH : HFR_MAX);
 
 2126    currentNumStars = m_ImageData->getDetectedStars();
 
 2129    if (m_StarMeasure == FOCUS_STAR_NUM_STARS)
 
 2131        currentMeasure = currentNumStars;
 
 2132        currentWeight = 1.0;
 
 2134    else if (m_StarMeasure == FOCUS_STAR_FWHM)
 
 2136        getFWHM(m_ImageData->getStarCenters(), ¤tFWHM, ¤tWeight);
 
 2137        currentMeasure = currentFWHM;
 
 2139    else if (m_StarMeasure == FOCUS_STAR_FOURIER_POWER)
 
 2141        getFourierPower(¤tFourierPower, ¤tWeight);
 
 2142        currentMeasure = currentFourierPower;
 
 2144    else if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
 
 2145             m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
 
 2148        if (m_OpsFocusSettings->focusSubFrame->isChecked())
 
 2149            roi = m_FocusView->isTrackingBoxEnabled() ? m_FocusView->getTrackingBox() : 
QRect();
 
 2150        getBlurriness(m_StarMeasure, m_OpsFocusProcess->focusDenoise->isChecked(), ¤tBlurriness, ¤tWeight, roi);
 
 2151        currentMeasure = currentBlurriness;
 
 2155        currentMeasure = currentHFR;
 
 2157        std::vector<double> hfrs(stars.
size());
 
 2162        currentWeight = calculateStarWeight(m_OpsFocusProcess->focusUseWeights->isChecked(), hfrs);
 
 2164    setCurrentMeasure();
 
 2170bool Focus::isStarMeasureStarBased()
 
 2172    if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL || m_StarMeasure == FOCUS_STAR_LAPLASSIAN
 
 2173            || m_StarMeasure == FOCUS_STAR_CANNY)
 
 2179void Focus::getFWHM(
const QList<Edge *> &stars, 
double *FWHM, 
double *weight)
 
 2181    *FWHM = INVALID_STAR_MEASURE;
 
 2184    auto imageBuffer = m_ImageData->getImageBuffer();
 
 2186    switch (m_ImageData->getStatistics().dataType)
 
 2189            focusFWHM->processFWHM(
reinterpret_cast<uint8_t 
const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
 
 2193            focusFWHM->processFWHM(
reinterpret_cast<short const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
 
 2197            focusFWHM->processFWHM(
reinterpret_cast<unsigned short const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM,
 
 2202            focusFWHM->processFWHM(
reinterpret_cast<long const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
 
 2206            focusFWHM->processFWHM(
reinterpret_cast<unsigned long const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
 
 2210            focusFWHM->processFWHM(
reinterpret_cast<float const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
 
 2214            focusFWHM->processFWHM(
reinterpret_cast<long long const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
 
 2218            focusFWHM->processFWHM(
reinterpret_cast<double const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
 
 2222            qCDebug(KSTARS_EKOS_FOCUS) << 
"Unknown image buffer datatype " << m_ImageData->getStatistics().dataType <<
 
 2223                                       " Cannot calc FWHM";
 
 2229void Focus::getFourierPower(
double *fourierPower, 
double *weight, 
const int mosaicTile)
 
 2231    *fourierPower = INVALID_STAR_MEASURE;
 
 2234    auto imageBuffer = m_ImageData->getImageBuffer();
 
 2236    switch (m_ImageData->getStatistics().dataType)
 
 2239            focusFourierPower->processFourierPower(
reinterpret_cast<uint8_t 
const *
>(imageBuffer), m_ImageData,
 
 2240                                                   m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
 
 2244            focusFourierPower->processFourierPower(
reinterpret_cast<short const *
>(imageBuffer), m_ImageData,
 
 2245                                                   m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
 
 2249            focusFourierPower->processFourierPower(
reinterpret_cast<unsigned short const *
>(imageBuffer), m_ImageData,
 
 2250                                                   m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
 
 2254            focusFourierPower->processFourierPower(
reinterpret_cast<long const *
>(imageBuffer), m_ImageData,
 
 2255                                                   m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
 
 2259            focusFourierPower->processFourierPower(
reinterpret_cast<unsigned long const *
>(imageBuffer), m_ImageData,
 
 2260                                                   m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
 
 2264            focusFourierPower->processFourierPower(
reinterpret_cast<float const *
>(imageBuffer), m_ImageData,
 
 2265                                                   m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
 
 2269            focusFourierPower->processFourierPower(
reinterpret_cast<long long const *
>(imageBuffer), m_ImageData,
 
 2270                                                   m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
 
 2274            focusFourierPower->processFourierPower(
reinterpret_cast<double const *
>(imageBuffer), m_ImageData,
 
 2275                                                   m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
 
 2279            qCDebug(KSTARS_EKOS_FOCUS) << 
"Unknown image buffer datatype " << m_ImageData->getStatistics().dataType <<
 
 2280                                       " Cannot calc Fourier Power";
 
 2286void Focus::getBlurriness(
const StarMeasure starMeasure, 
const bool denoise, 
double *blurriness, 
double *weight,
 
 2287                          const QRect &roi, 
const int mosaicTile)
 
 2289    *blurriness = INVALID_STAR_MEASURE;
 
 2292#if defined(HAVE_OPENCV) 
 2294    auto imageBuffer = m_ImageData->getImageBuffer();
 
 2296    switch (m_ImageData->getStatistics().dataType)
 
 2299            focusBlurriness->processBlurriness(
reinterpret_cast<uint8_t 
const *
>(imageBuffer), m_ImageData, denoise,
 
 2300                                               m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
 
 2304            focusBlurriness->processBlurriness(
reinterpret_cast<short const *
>(imageBuffer), m_ImageData, denoise,
 
 2305                                               m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
 
 2309            focusBlurriness->processBlurriness(
reinterpret_cast<unsigned short const *
>(imageBuffer), m_ImageData, denoise,
 
 2310                                               m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
 
 2314            focusBlurriness->processBlurriness(
reinterpret_cast<long const *
>(imageBuffer), m_ImageData, denoise,
 
 2315                                               m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
 
 2319            focusBlurriness->processBlurriness(
reinterpret_cast<unsigned long const *
>(imageBuffer), m_ImageData, denoise,
 
 2320                                               m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
 
 2324            focusBlurriness->processBlurriness(
reinterpret_cast<float const *
>(imageBuffer), m_ImageData, denoise,
 
 2325                                               m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
 
 2329            focusBlurriness->processBlurriness(
reinterpret_cast<long long const *
>(imageBuffer), m_ImageData, denoise,
 
 2330                                               m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
 
 2334            focusBlurriness->processBlurriness(
reinterpret_cast<double const *
>(imageBuffer), m_ImageData, denoise,
 
 2335                                               m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
 
 2339            qCDebug(KSTARS_EKOS_FOCUS) << 
"Unknown image buffer datatype " << m_ImageData->getStatistics().dataType <<
 
 2340                                       " Cannot calc Blurriness";
 
 2344    Q_UNUSED(starMeasure);
 
 2347    Q_UNUSED(mosaicTile);
 
 2349    qCDebug(KSTARS_EKOS_FOCUS) << 
"getBlurriness called when openCV not installed";
 
 2353double Focus::calculateStarWeight(
const bool useWeights, 
const std::vector<double> values)
 
 2355    if (!useWeights || values.size() <= 0)
 
 2360    return Mathematics::RobustStatistics::ComputeWeight(m_ScaleCalc, values);
 
 2363void Focus::analyzeSources()
 
 2365    appendLogText(
i18n(
"Detecting sources..."));
 
 2366    m_starDetectInProgress = 
true;
 
 2368    QVariantMap extractionSettings;
 
 2369    extractionSettings[
"optionsProfileIndex"] = m_OpsFocusProcess->focusSEPProfile->currentIndex();
 
 2370    extractionSettings[
"optionsProfileGroup"] =  
static_cast<int>(Ekos::FocusProfiles);
 
 2371    m_ImageData->setSourceExtractorSettings(extractionSettings);
 
 2375    if (m_OpsFocusSettings->focusUseFullField->isChecked())
 
 2377        m_FocusView->setTrackingBoxEnabled(
false);
 
 2379        if (m_FocusDetection != ALGORITHM_CENTROID && m_FocusDetection != ALGORITHM_SEP)
 
 2380            m_StarFinderWatcher.setFuture(m_ImageData->findStars(ALGORITHM_CENTROID));
 
 2382            m_StarFinderWatcher.setFuture(m_ImageData->findStars(m_FocusDetection));
 
 2386        QRect searchBox = m_FocusView->isTrackingBoxEnabled() ? m_FocusView->getTrackingBox() : 
QRect();
 
 2390            m_StarFinderWatcher.setFuture(m_ImageData->findStars(m_FocusDetection, searchBox));
 
 2395            m_FocusView->setTrackingBoxEnabled(
false);
 
 2399            if (m_FocusDetection != ALGORITHM_CENTROID && m_FocusDetection != ALGORITHM_SEP)
 
 2400                m_StarFinderWatcher.setFuture(m_ImageData->findStars(ALGORITHM_CENTROID));
 
 2403                m_StarFinderWatcher.setFuture(m_ImageData->findStars(m_FocusDetection, searchBox));
 
 2408bool Focus::appendMeasure(
double newMeasure)
 
 2411    starMeasureFrames.append(newMeasure);
 
 2414    QVector <double> samples(starMeasureFrames);
 
 2415    samples.erase(std::remove_if(samples.begin(), samples.end(), [](
const double measure)
 
 2417        return measure == INVALID_STAR_MEASURE;
 
 2421    if (!samples.isEmpty())
 
 2423        currentMeasure = Mathematics::RobustStatistics::ComputeLocation(
 
 2424                             Mathematics::RobustStatistics::LOCATION_SIGMACLIPPING, std::vector<double>(samples.begin(), samples.end()));
 
 2426        switch(m_StarMeasure)
 
 2428            case FOCUS_STAR_HFR:
 
 2429            case FOCUS_STAR_HFR_ADJ:
 
 2430                currentHFR = currentMeasure;
 
 2432            case FOCUS_STAR_FWHM:
 
 2433                currentFWHM = currentMeasure;
 
 2435            case FOCUS_STAR_NUM_STARS:
 
 2436                currentNumStars = currentMeasure;
 
 2438            case FOCUS_STAR_FOURIER_POWER:
 
 2439                currentFourierPower = currentMeasure;
 
 2441            case FOCUS_STAR_STDDEV:
 
 2442            case FOCUS_STAR_SOBEL:
 
 2443            case FOCUS_STAR_LAPLASSIAN:
 
 2444            case FOCUS_STAR_CANNY:
 
 2445                currentBlurriness = currentMeasure;
 
 2456    int framesCount = m_OpsFocusProcess->focusFramesCount->value();
 
 2457    if ((minimumRequiredHFR > 0) || (inAutoFocus && !inBuildOffsets && !inScanStartPos && !focusAdvisor->inFocusAdvisor()
 
 2458                                     && m_FocusAlgorithm == FOCUS_LINEAR1PASS
 
 2459                                     && linearFocuser && !linearFocuser->isInFirstPass()))
 
 2461        framesCount = m_OpsFocusProcess->focusHFRFramesCount->value();
 
 2463    return starMeasureFrames.count() < framesCount;
 
 2466void Focus::settle(
const FocusState completionState, 
const bool autoFocusUsed, 
const bool buildOffsetsUsed,
 
 2467                   const AutofocusFailReason failCode, 
const QString failCodeInfo)
 
 2469    if (autoFocusUsed && failCode != FOCUS_FAIL_OPTIMISED_OUT)
 
 2471        if (completionState == Ekos::FOCUS_COMPLETE)
 
 2473            if (failCode != FOCUS_FAIL_ADVISOR_COMPLETE)
 
 2474                KSNotification::event(
QLatin1String(
"FocusSuccessful"), 
i18n(
"Autofocus operation completed successfully"),
 
 2475                                      KSNotification::Focus);
 
 2477            if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && curveFitting != 
nullptr)
 
 2478                emit autofocusComplete(m_LastSourceAutofocusTemperature, 
filter(), getAnalyzeData(),
 
 2479                                       m_OpsFocusProcess->focusUseWeights->isChecked(),
 
 2480                                       curveFitting->serialize(), linearFocuser->getTextStatus(R2));
 
 2482                emit autofocusComplete(m_LastSourceAutofocusTemperature, 
filter(), getAnalyzeData(),
 
 2483                                       m_OpsFocusProcess->focusUseWeights->isChecked());
 
 2487            if (failCode != FOCUS_FAIL_ADVISOR_COMPLETE)
 
 2488                KSNotification::event(
QLatin1String(
"FocusFailed"), 
i18n(
"Autofocus operation failed"),
 
 2489                                      KSNotification::Focus, KSNotification::Alert);
 
 2490            emit autofocusAborted(
filter(), getAnalyzeData(), m_OpsFocusProcess->focusUseWeights->isChecked(), failCode, failCodeInfo);
 
 2494    if (completionState == Ekos::FOCUS_COMPLETE)
 
 2496        if (autoFocusUsed && fallbackFilterPending)
 
 2501            m_FilterManager->setFilterAbsoluteFocusDetails(focusFilter->currentIndex(), currentPosition,
 
 2502                    m_LastSourceAutofocusTemperature, m_LastSourceAutofocusAlt);
 
 2507    if (fallbackFilterPending)
 
 2509        m_pendingState = completionState;
 
 2510        FilterManager::FilterPolicy policy = 
static_cast<FilterManager::FilterPolicy
>(FilterManager::CHANGE_POLICY |
 
 2511                                             FilterManager::OFFSET_POLICY);
 
 2512        m_FilterManager->setFilterPosition(fallbackFilterPosition, policy);
 
 2515        setState(completionState, failCode != FOCUS_FAIL_OPTIMISED_OUT);
 
 2517    if (autoFocusUsed && buildOffsetsUsed)
 
 2519        m_FilterManager->autoFocusComplete(completionState, currentPosition, m_LastSourceAutofocusTemperature,
 
 2520                                           m_LastSourceAutofocusAlt);
 
 2525QString Focus::getAnalyzeData()
 
 2527    QString analysis_results = 
"";
 
 2529    for (
int i = 0; i < plot_position.size(); ++i)
 
 2532                                .arg(i == 0 ? 
"" : 
"|" )
 
 2538    return analysis_results;
 
 2541void Focus::completeFocusProcedure(FocusState completionState, AutofocusFailReason failCode, 
QString failCodeInfo,
 
 2545    if (inAutoFocus && failCode != FOCUS_FAIL_ADVISOR_COMPLETE && failCode != FOCUS_FAIL_OPTIMISED_OUT)
 
 2548        updatePlotPosition();
 
 2550        if (completionState == Ekos::FOCUS_COMPLETE)
 
 2554                emit redrawHFRPlot(polynomialFit.get(), currentPosition, currentHFR);
 
 2556            appendLogText(
i18np(
"Focus procedure completed after %1 iteration.",
 
 2557                                "Focus procedure completed after %1 iterations.", plot_position.count()));
 
 2559            setLastFocusTemperature();
 
 2561            resetAdaptiveFocus(m_OpsFocusSettings->focusAdaptive->isChecked());
 
 2565            qCInfo(KSTARS_EKOS_FOCUS) << 
"Autofocus values: position," << currentPosition << 
", temperature," 
 2566                                      << m_LastSourceAutofocusTemperature << 
", filter," << 
filter()
 
 2567                                      << 
", HFR," << currentHFR << 
", altitude," << m_LastSourceAutofocusAlt;
 
 2569            if (m_FocusAlgorithm == FOCUS_POLYNOMIAL)
 
 2572                plot_position.append(currentPosition);
 
 2573                plot_value.append(currentHFR);
 
 2574                plot_weight.append(1.0);
 
 2575                plot_outlier.append(
false);
 
 2578            appendFocusLogText(
QString(
"%1, %2, %3, %4, %5\n")
 
 2585            absTicksSpin->setValue(currentPosition);
 
 2588        else if (canAbsMove && initialFocuserAbsPosition >= 0 && resetFocusIteration <= MAXIMUM_RESET_ITERATIONS &&
 
 2589                 m_RestartState != RESTART_ABORT)
 
 2592            bool const retry_focusing = m_RestartState == RESTART_NONE &&
 
 2593                                        (failCode == Ekos::FOCUS_FAIL_ADVISOR_RERUN || ++resetFocusIteration < MAXIMUM_RESET_ITERATIONS);
 
 2598                m_RestartState = RESTART_NOW;
 
 2607                emit autofocusAborted(
filter(), getAnalyzeData(), m_OpsFocusProcess->focusUseWeights->isChecked(), failCode, failCodeInfo);
 
 2619                m_RestartState = RESTART_ABORT;
 
 2625        resetFocusIteration = 0;
 
 2628    const bool autoFocusUsed = inAutoFocus;
 
 2629    const bool inBuildOffsetsUsed = inBuildOffsets;
 
 2632    if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && plot)
 
 2633        emit drawPolynomial(polynomialFit.get(), isVShapeSolution, 
true);
 
 2636    int const settleTime = m_GuidingSuspended ? m_OpsFocusSettings->focusGuideSettleTime->value() : 0;
 
 2639    stop(completionState);
 
 2642        appendLogText(
i18n(
"Settling for %1s...", settleTime));
 
 2644    QTimer::singleShot(settleTime * 1000, 
this, [ &, settleTime, completionState, autoFocusUsed, inBuildOffsetsUsed, failCode,
 
 2647        settle(completionState, autoFocusUsed, inBuildOffsetsUsed, failCode, failCodeInfo);
 
 2650            appendLogText(
i18n(
"Settling complete."));
 
 2657    if (m_Focuser && m_Focuser->isConnected() && initialFocuserAbsPosition >= 0)
 
 2660        if (currentPosition == initialFocuserAbsPosition)
 
 2663        appendLogText(
i18n(
"Autofocus failed, moving back to initial focus position %1.", initialFocuserAbsPosition));
 
 2664        changeFocus(initialFocuserAbsPosition - currentPosition);
 
 
 2669void Focus::setCurrentMeasure()
 
 2672    qCDebug(KSTARS_EKOS_FOCUS) << 
"Focus newFITS #" << starMeasureFrames.count() + 1 << 
": Current HFR " << currentHFR <<
 
 2674                               << (starSelected ? 1 : currentNumStars);
 
 2677    if (appendMeasure(currentMeasure))
 
 2682    else starMeasureFrames.clear();
 
 2687        emit newHFR(currentHFR, currentPosition, inAutoFocus, opticalTrain());
 
 2689        emit newHFR(currentHFR, -1, inAutoFocus, opticalTrain());
 
 2692    HFROut->setText(
QString(
"%1").arg(currentHFR * getStarUnits(m_StarMeasure, m_StarUnits), 0, 
'f', 2));
 
 2693    if (m_StarMeasure == FOCUS_STAR_FWHM)
 
 2694        FWHMOut->setText(
QString(
"%1").arg(currentFWHM * getStarUnits(m_StarMeasure, m_StarUnits), 0, 
'f', 2));
 
 2695    starsOut->setText(
QString(
"%1").arg(m_ImageData->getDetectedStars()));
 
 2696    iterOut->setText(
QString(
"%1").arg(absIterations + 1));
 
 2699    if (lastHFR == INVALID_STAR_MEASURE)
 
 2700        appendLogText(
i18n(
"FITS received. No stars detected."));
 
 2703    if (!isStarMeasureStarBased() || currentHFR > 0)
 
 2706        if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && isVShapeSolution)
 
 2708            completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
 
 2712        Edge selectedHFRStarHFR = m_ImageData->getSelectedHFRStar();
 
 2719        if (starCenter.isNull() == 
false && (inAutoFocus || minimumRequiredHFR >= 0))
 
 2722            starSelected = 
true;
 
 2723            starCenter.setX(qMax(0, 
static_cast<int>(selectedHFRStarHFR.x)));
 
 2724            starCenter.setY(qMax(0, 
static_cast<int>(selectedHFRStarHFR.y)));
 
 2726            syncTrackingBoxPosition();
 
 2730            oneStar.
setZ(currentHFR);
 
 2731            starsHFR.append(oneStar);
 
 2736            QVector3D oneStar(starCenter.x(), starCenter.y(), currentHFR);
 
 2737            starsHFR.append(oneStar);
 
 2740        if (currentHFR > maxHFR)
 
 2741            maxHFR = currentHFR;
 
 2749        if (inFocusLoop || (inAutoFocus && ! isPositionBased()))
 
 2751            int pos = plot_position.empty() ? 1 : plot_position.last() + 1;
 
 2752            addPlotPosition(pos, currentMeasure);
 
 2758        QVector3D oneStar(starCenter.x(), starCenter.y(), INVALID_STAR_MEASURE);
 
 2759        starsHFR.append(oneStar);
 
 2764    m_FocusView->updateFrame();
 
 2768    if (m_abInsOn && !inScanStartPos && !focusAdvisor->inFocusAdvisor())
 
 2769        calculateAbInsData();
 
 2773void Focus::saveFocusFrame()
 
 2775    if (inAutoFocus && Options::focusLogging() && Options::saveFocusImages())
 
 2778        QDateTime now = KStarsData::Instance()->lt();
 
 2786        if (focusAdvisor->inFocusAdvisor())
 
 2787            prefix = focusAdvisor->getFocusFramePrefix();
 
 2788        else if (inScanStartPos)
 
 2789            prefix = 
QString(
"_ssp_%1_%2").
arg(m_AFRun).
arg(absIterations + 1);
 
 2790        else if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && linearFocuser)
 
 2792            const int currentStep = linearFocuser->currentStep() + 1;
 
 2798            prefix.
append(
QString(
"_%1").arg(starMeasureFrames.count()));
 
 2804        m_ImageData->saveImage(filename);
 
 2808void Focus::calculateAbInsData()
 
 2810    ImageMosaicMask *mosaicmask = 
dynamic_cast<ImageMosaicMask *
>(m_FocusView->imageMask().
get());
 
 2812    auto stars = m_ImageData->getStarCenters();
 
 2815    for (
int star = 0; star < stars.
count(); star++)
 
 2817        const int x = stars[star]->x;
 
 2818        const int y = stars[star]->y;
 
 2819        for (
int tile = 0; tile < NUM_TILES; tile++)
 
 2821            QRect thisTile = tiles[tile];
 
 2824                tileStars[tile].append(stars[star]);
 
 2831    for (
int tile = 0; tile < tileStars.count(); tile++)
 
 2833        double measure, weight;
 
 2834        std::vector<double> HFRs;
 
 2836        switch (m_StarMeasure)
 
 2838            case FOCUS_STAR_HFR:
 
 2839            case FOCUS_STAR_HFR_ADJ:
 
 2840                for (
int star = 0; star < tileStars[tile].count(); star++)
 
 2842                    HFRs.push_back(tileStars[tile][star]->HFR);
 
 2844                measure = Mathematics::RobustStatistics::ComputeLocation(Mathematics::RobustStatistics::LOCATION_SIGMACLIPPING, HFRs, 2);
 
 2845                weight = calculateStarWeight(m_OpsFocusProcess->focusUseWeights->isChecked(), HFRs);
 
 2847            case FOCUS_STAR_FWHM:
 
 2848                getFWHM(tileStars[tile], &measure, &weight);
 
 2850            case FOCUS_STAR_NUM_STARS:
 
 2851                measure = tileStars[tile].count();
 
 2854            case FOCUS_STAR_FOURIER_POWER:
 
 2855                getFourierPower(&measure, &weight, tile);
 
 2857            case FOCUS_STAR_STDDEV:
 
 2858            case FOCUS_STAR_SOBEL:
 
 2859            case FOCUS_STAR_LAPLASSIAN:
 
 2860            case FOCUS_STAR_CANNY:
 
 2861                getBlurriness(m_StarMeasure, m_OpsFocusProcess->focusDenoise->isChecked(), &measure, &weight, 
QRect(), tile);
 
 2864                qCDebug(KSTARS_EKOS_FOCUS) << 
"Unable to calculate Aberration Inspector data";
 
 2868        m_abInsMeasure[tile].append(measure);
 
 2869        m_abInsWeight[tile].append(weight);
 
 2870        m_abInsNumStars[tile].append(tileStars[tile].count());
 
 2872        if (!linearFocuser->isInFirstPass())
 
 2877            int xAv = 0, yAv = 0;
 
 2878            if (m_StarMeasure != FOCUS_STAR_FOURIER_POWER)
 
 2880                QPoint tileCenter = tiles[tile].center();
 
 2881                int xSum = 0.0, ySum = 0.0;
 
 2882                for (
int star = 0; star < tileStars[tile].count(); star++)
 
 2884                    xSum += tileStars[tile][star]->x - tileCenter.
x();
 
 2885                    ySum += tileStars[tile][star]->y - tileCenter.
y();
 
 2888                xAv = (tileStars[tile].count() <= 0) ? 0 : xSum / tileStars[tile].count();
 
 2889                yAv = (tileStars[tile].count() <= 0) ? 0 : ySum / tileStars[tile].count();
 
 2891            m_abInsTileCenterOffset.append(
QPoint(xAv, yAv));
 
 2894    m_abInsPosition.append(currentPosition);
 
 2897void Focus::setCaptureComplete()
 
 2899    DarkLibrary::Instance()->disconnect(
this);
 
 2902    syncTrackingBoxPosition();
 
 2905    if (inFocusLoop == 
false)
 
 2906        appendLogText(
i18n(
"Image received."));
 
 2908    if (m_captureInProgress && inFocusLoop == 
false && inAutoFocus == 
false)
 
 2909        m_Camera->setUploadMode(rememberUploadMode);
 
 2911    if (m_RememberCameraFastExposure && inFocusLoop == 
false && inAutoFocus == 
false)
 
 2913        m_RememberCameraFastExposure = 
false;
 
 2914        m_Camera->setFastExposureEnabled(
true);
 
 2917    m_captureInProgress = 
false;
 
 2918    if (m_abortInProgress)
 
 2922        qCDebug(KSTARS_EKOS_FOCUS) << 
"Abort AF: discarding frame results in " << __FUNCTION__;
 
 2927    checkMosaicMaskLimits();
 
 2930    emit newImage(m_FocusView);
 
 2932    emit newStarPixmap(m_FocusView->getTrackingBoxPixmap(10));
 
 2940    if (!isStarMeasureStarBased())
 
 2941        starDetectionFinished();
 
 2942    else if (inFocusLoop == 
false || (inFocusLoop && (m_FocusView->isTrackingBoxEnabled()
 
 2943                                      || m_OpsFocusSettings->focusUseFullField->isChecked())))
 
 2949void Focus::setHFRComplete()
 
 2959    ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 2962    int subBinX = 1, subBinY = 1;
 
 2963    if (!targetChip->getBinning(&subBinX, &subBinY))
 
 2964        qCDebug(KSTARS_EKOS_FOCUS) << 
"Warning: target chip is reporting no binning property, using 1x1.";
 
 2966    if (m_OpsFocusSettings->focusSubFrame->isChecked() && !isStarMeasureStarBased() && !starSelected)
 
 2968        appendLogText(
i18n(
"Capture complete. Select a region of interest."));
 
 2970        syncTrackingBoxPosition();
 
 2973        setState(Ekos::FOCUS_WAITING);
 
 2976        waitStarSelectTimer.start();
 
 2979    else if (m_OpsFocusSettings->focusSubFrame->isChecked() && isStarMeasureStarBased() && starCenter.isNull())
 
 2986        int x = 0, y = 0, w = 0, h = 0;
 
 2989        if (frameSettings.contains(targetChip))
 
 2991            QVariantMap settings = frameSettings[targetChip];
 
 2992            x                    = settings[
"x"].toInt();
 
 2993            y                    = settings[
"y"].toInt();
 
 2994            w                    = settings[
"w"].toInt();
 
 2995            h                    = settings[
"h"].toInt();
 
 2999            targetChip->getFrame(&x, &y, &w, &h);
 
 3002        if (m_OpsFocusSettings->focusAutoStarEnabled->isChecked())
 
 3005            const Edge selectedHFRStar = m_ImageData->getSelectedHFRStar();
 
 3007            if (selectedHFRStar.x == -1)
 
 3009                appendLogText(
i18n(
"Failed to automatically select a star. Please select a star manually."));
 
 3012                m_FocusView->setTrackingBox(
QRect(w - m_OpsFocusSettings->focusBoxSize->value() / (subBinX * 2),
 
 3013                                                  h - m_OpsFocusSettings->focusBoxSize->value() / (subBinY * 2),
 
 3014                                                  m_OpsFocusSettings->focusBoxSize->value() / subBinX, m_OpsFocusSettings->focusBoxSize->value() / subBinY));
 
 3015                m_FocusView->setTrackingBoxEnabled(
true);
 
 3018                setState(Ekos::FOCUS_WAITING);
 
 3021                waitStarSelectTimer.start();
 
 3027            starCenter.setX(selectedHFRStar.x);
 
 3028            starCenter.setY(selectedHFRStar.y);
 
 3029            starCenter.setZ(subBinX);
 
 3030            starSelected = 
true;
 
 3031            syncTrackingBoxPosition();
 
 3034            if (subFramed == 
false && isFocusSubFrameEnabled() && m_OpsFocusSettings->focusSubFrame->isChecked())
 
 3036                int offset = (
static_cast<double>(m_OpsFocusSettings->focusBoxSize->value()) / subBinX) * 1.5;
 
 3037                int subX   = (selectedHFRStar.x - offset) * subBinX;
 
 3038                int subY   = (selectedHFRStar.y - offset) * subBinY;
 
 3039                int subW   = offset * 2 * subBinX;
 
 3040                int subH   = offset * 2 * subBinY;
 
 3042                int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
 
 3043                targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
 
 3050                if ((subW + subX) > maxW)
 
 3052                if ((subH + subY) > maxH)
 
 3057                QVariantMap settings = frameSettings[targetChip];
 
 3058                settings[
"x"]        = subX;
 
 3059                settings[
"y"]        = subY;
 
 3060                settings[
"w"]        = subW;
 
 3061                settings[
"h"]        = subH;
 
 3062                settings[
"binx"]     = subBinX;
 
 3063                settings[
"biny"]     = subBinY;
 
 3065                qCDebug(KSTARS_EKOS_FOCUS) << 
"Frame is subframed. X:" << subX << 
"Y:" << subY << 
"W:" << subW << 
"H:" << subH << 
"binX:" <<
 
 3066                                           subBinX << 
"binY:" << subBinY;
 
 3070                frameSettings[targetChip] = settings;
 
 3073                starCenter.setX(subW / (2 * subBinX));
 
 3074                starCenter.setY(subH / (2 * subBinY));
 
 3075                starCenter.setZ(subBinX);
 
 3079                m_FocusView->setFirstLoad(
true);
 
 3088                starCenter.setX(selectedHFRStar.x);
 
 3089                starCenter.setY(selectedHFRStar.y);
 
 3090                starCenter.setZ(subBinX);
 
 3103            appendLogText(
i18n(
"Capture complete. Select a star to focus."));
 
 3105            starSelected = 
false;
 
 3109            int subBinX = 1, subBinY = 1;
 
 3110            targetChip->getBinning(&subBinX, &subBinY);
 
 3112            m_FocusView->setTrackingBox(
QRect((w - m_OpsFocusSettings->focusBoxSize->value()) / (subBinX * 2),
 
 3113                                              (h - m_OpsFocusSettings->focusBoxSize->value()) / (2 * subBinY),
 
 3114                                              m_OpsFocusSettings->focusBoxSize->value() / subBinX, m_OpsFocusSettings->focusBoxSize->value() / subBinY));
 
 3115            m_FocusView->setTrackingBoxEnabled(
true);
 
 3118            setState(Ekos::FOCUS_WAITING);
 
 3121            waitStarSelectTimer.start();
 
 3127    if (minimumRequiredHFR >= 0)
 
 3130        if (currentHFR == INVALID_STAR_MEASURE)
 
 3132            if (noStarCount++ < MAX_RECAPTURE_RETRIES)
 
 3134                appendLogText(
i18n(
"No stars detected while testing HFR, capturing again..."));
 
 3136                if (noStarCount == MAX_RECAPTURE_RETRIES)
 
 3145                completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
 
 3150        else if (currentHFR > minimumRequiredHFR)
 
 3152            qCDebug(KSTARS_EKOS_FOCUS) << 
"Current HFR:" << currentHFR << 
"is above required minimum HFR:" << minimumRequiredHFR <<
 
 3153                                       ". Starting AutoFocus...";
 
 3156            minimumRequiredHFR = INVALID_STAR_MEASURE;
 
 3157            runAutoFocus(AutofocusReason::FOCUS_HFR_CHECK, reasonInfo);
 
 3162            qCDebug(KSTARS_EKOS_FOCUS) << 
"Current HFR:" << currentHFR << 
"is below required minimum HFR:" << minimumRequiredHFR <<
 
 3163                                       ". Autofocus successful.";
 
 3164            completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
 
 3172    if (inAutoFocus == 
false)
 
 3176        if (state() != Ekos::FOCUS_IDLE)
 
 3177            setState(Ekos::FOCUS_IDLE);
 
 3184    if (state() != Ekos::FOCUS_PROGRESS)
 
 3185        setState(Ekos::FOCUS_PROGRESS);
 
 3190    else if(focusAdvisor->inFocusAdvisor())
 
 3191        focusAdvisor->control();
 
 3192    else if(m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
 
 3194    else if (canAbsMove || canRelMove)
 
 3202QString Focus::getyAxisLabel(StarMeasure starMeasure)
 
 3205    m_StarUnits == FOCUS_UNITS_ARCSEC ? str += 
" (\")" : str += 
" (pix)";
 
 3207    switch (starMeasure)
 
 3209        case FOCUS_STAR_HFR:
 
 3211        case FOCUS_STAR_HFR_ADJ:
 
 3213            m_StarUnits == FOCUS_UNITS_ARCSEC ? str += 
" (\")" : str += 
" (pix)";
 
 3215        case FOCUS_STAR_FWHM:
 
 3217            m_StarUnits == FOCUS_UNITS_ARCSEC ? str += 
" (\")" : str += 
" (pix)";
 
 3219        case FOCUS_STAR_NUM_STARS:
 
 3222        case FOCUS_STAR_FOURIER_POWER:
 
 3223            str = 
"Fourier Power";
 
 3225        case FOCUS_STAR_STDDEV:
 
 3228        case FOCUS_STAR_SOBEL:
 
 3229            str = 
"Sobel Factor";
 
 3231        case FOCUS_STAR_LAPLASSIAN:
 
 3232            str = 
"Laplassian Factor";
 
 3234        case FOCUS_STAR_CANNY:
 
 3235            str = 
"Canny Factor";
 
 3246    polynomialFit.reset();
 
 3247    plot_position.clear();
 
 3249    plot_weight.clear();
 
 3250    plot_outlier.clear();
 
 3251    isVShapeSolution = 
false;
 
 3252    m_abInsPosition.clear();
 
 3253    m_abInsTileCenterOffset.clear();
 
 3254    if (m_abInsMeasure.count() != NUM_TILES)
 
 3256        m_abInsMeasure.resize(NUM_TILES);
 
 3257        m_abInsWeight.resize(NUM_TILES);
 
 3258        m_abInsNumStars.resize(NUM_TILES);
 
 3262        for (
int i = 0; i < m_abInsMeasure.count(); i++)
 
 3264            m_abInsMeasure[i].clear();
 
 3265            m_abInsWeight[i].clear();
 
 3266            m_abInsNumStars[i].clear();
 
 3270    emit 
initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits),
 
 3271                     m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, m_OpsFocusProcess->focusUseWeights->isChecked(),
 
 3272                     inFocusLoop == 
false && isPositionBased());
 
 
 3275bool Focus::autoFocusChecks()
 
 3277    if (++absIterations > MAXIMUM_ABS_ITERATIONS)
 
 3279        appendLogText(
i18n(
"Autofocus failed: exceeded max iterations %1", MAXIMUM_ABS_ITERATIONS));
 
 3280        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_MAX_ITERS);
 
 3285    if (isStarMeasureStarBased() && currentHFR == INVALID_STAR_MEASURE)
 
 3287        if (noStarCount < MAX_RECAPTURE_RETRIES)
 
 3290            appendLogText(
i18n(
"No stars detected, capturing again..."));
 
 3294        else if (m_FocusAlgorithm == FOCUS_LINEAR)
 
 3296            appendLogText(
i18n(
"Failed to detect any stars at position %1. Continuing...", currentPosition));
 
 3299        else if(!m_OpsFocusProcess->focusDonut->isChecked())
 
 3302            appendLogText(
i18n(
"Failed to detect any stars. Reset frame and try again."));
 
 3303            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
 
 3313void Focus::plotLinearFocus()
 
 3322    linearFocuser->getMeasurements(&positions, &values, &weights);
 
 3323    const FocusAlgorithmInterface::FocusParams ¶ms = linearFocuser->getParams();
 
 3330    bool incrementalChange = 
false;
 
 3331    if (positions.
size() > 1 && positions.
size() == lastPositions.
size() + 1)
 
 3334        for (
int i = 0; i < positions.
size() - 1; ++i)
 
 3335            if (positions[i] != lastPositions[i] || values[i] != lastValues[i])
 
 3340        incrementalChange = 
ok;
 
 3342    lastPositions = positions;
 
 3343    lastValues = values;
 
 3345    const bool outlier = 
false;
 
 3346    if (incrementalChange)
 
 3347        emit newHFRPlotPosition(
static_cast<double>(positions.
last()), values.
last(), (pow(weights.
last(), -0.5)),
 
 3348                                outlier, params.initialStepSize, plt);
 
 3351        emit initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits),
 
 3352                         m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, params.useWeights, plt);
 
 3353        for (
int i = 0; i < positions.
size(); ++i)
 
 3354            emit newHFRPlotPosition(
static_cast<double>(positions[i]), values[i], (pow(weights.
last(), -0.5)),
 
 3355                                    outlier, params.initialStepSize, plt);
 
 3359    if (values.
size() > 3)
 
 3365        double minPosition, minValue;
 
 3366        double searchMin = std::max(params.minPositionAllowed, params.startPosition - params.maxTravel);
 
 3367        double searchMax = std::min(params.maxPositionAllowed, params.startPosition + params.maxTravel);
 
 3369        linearFocuser->getPass1Measurements(&pass1Positions, &pass1Values, &pass1Weights, &pass1Outliers);
 
 3370        if (m_FocusAlgorithm == FOCUS_LINEAR || m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
 
 3374            polynomialFit.reset(
new PolynomialFit(2, pass1Positions, pass1Values));
 
 3376            if (polynomialFit->findMinimum(params.startPosition, searchMin, searchMax, &minPosition, &minValue))
 
 3378                emit drawPolynomial(polynomialFit.get(), 
true, 
true, plt);
 
 3382                if (linearFocuser->isDone())
 
 3383                    emit minimumFound(-1, -1, plt);
 
 3385                    emit minimumFound(minPosition, minValue, plt);
 
 3390                emit drawPolynomial(polynomialFit.get(), 
false, 
false, plt);
 
 3391                emit minimumFound(-1, -1, plt);
 
 3397            if (curveFitting->findMinMax(params.startPosition, searchMin, searchMax, &minPosition, &minValue, params.curveFit,
 
 3398                                         params.optimisationDirection))
 
 3400                R2 = curveFitting->calculateR2(
static_cast<CurveFitting::CurveFit
>(params.curveFit));
 
 3401                emit drawCurve(curveFitting.get(), 
true, 
true, plt);
 
 3404                emit minimumFound(minPosition, minValue, plt);
 
 3409                emit drawCurve(curveFitting.get(), 
false, 
false, plt);
 
 3410                emit minimumFound(-1, -1, plt);
 
 3416    HFROut->setText(
QString(
"%1").arg(currentHFR * getStarUnits(m_StarMeasure, m_StarUnits), 0, 
'f', 2));
 
 3418    emit setTitle(linearFocuser->getTextStatus(R2));
 
 3420    if (!plt) HFRPlot->replot();
 
 3424CurveFitting::FittingGoal Focus::getGoal(
int numSteps)
 
 3427    if (m_FocusWalk == FOCUS_WALK_CLASSIC)
 
 3428        return CurveFitting::FittingGoal::STANDARD;
 
 3431    return (numSteps >= m_OpsFocusMechanics->focusNumSteps->value()) ? CurveFitting::FittingGoal::BEST :
 
 3432           CurveFitting::FittingGoal::STANDARD;
 
 3438void Focus::plotLinearFinalUpdates()
 
 3441    if (!m_OpsFocusProcess->focusRefineCurveFit->isChecked())
 
 3444        emit drawCFZ(linearFocuser->solution(), linearFocuser->solutionValue(), m_cfzSteps,
 
 3445                     m_CFZUI->focusCFZDisplayVCurve->isChecked());
 
 3447        emit finalUpdates(linearFocuser->getTextStatus(R2), plt);
 
 3457        linearFocuser->getPass1Measurements(&pass1Positions, &pass1Values, &pass1Weights, &pass1Outliers);
 
 3458        const FocusAlgorithmInterface::FocusParams ¶ms = linearFocuser->getParams();
 
 3460        emit initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits),
 
 3461                         m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, m_OpsFocusProcess->focusUseWeights->isChecked(), plt);
 
 3463        for (
int i = 0; i < pass1Positions.
size(); ++i)
 
 3464            emit newHFRPlotPosition(
static_cast<double>(pass1Positions[i]), pass1Values[i], (pow(pass1Weights[i], -0.5)),
 
 3465                                    pass1Outliers[i], params.initialStepSize, plt);
 
 3467        R2 = curveFitting->calculateR2(
static_cast<CurveFitting::CurveFit
>(params.curveFit));
 
 3468        emit drawCurve(curveFitting.get(), 
true, 
true, 
false);
 
 3471        emit minimumFound(linearFocuser->solution(), linearFocuser->solutionValue(), plt);
 
 3473        emit drawCFZ(linearFocuser->solution(), linearFocuser->solutionValue(), m_cfzSteps,
 
 3474                     m_CFZUI->focusCFZDisplayVCurve->isChecked());
 
 3476        emit setTitle(linearFocuser->getTextStatus(R2), plt);
 
 3480void Focus::startAberrationInspector()
 
 3482#ifdef HAVE_DATAVISUALIZATION 
 3484    AberrationInspector::abInsData data;
 
 3486    ImageMosaicMask *mosaicmask = 
dynamic_cast<ImageMosaicMask *
>(m_FocusView->imageMask().
get());
 
 3489        appendLogText(
i18n(
"Unable to launch Aberration Inspector run %1...", m_abInsRun));
 
 3494    data.run = ++m_abInsRun;
 
 3495    data.curveFit = m_CurveFit;
 
 3496    data.useWeights = m_OpsFocusProcess->focusUseWeights->isChecked();
 
 3497    data.optDir = m_OptDir;
 
 3498    data.sensorWidth = m_CcdWidth;
 
 3499    data.sensorHeight = m_CcdHeight;
 
 3500    data.pixelSize = m_CcdPixelSizeX;
 
 3501    data.tileWidth = mosaicmask->tiles()[0].width();
 
 3502    data.focuserStepMicrons = m_CFZUI->focusCFZStepSize->value();
 
 3503    data.yAxisLabel = getyAxisLabel(m_StarMeasure);
 
 3504    data.starUnits = getStarUnits(m_StarMeasure, m_StarUnits);
 
 3505    data.cfzSteps = m_cfzSteps;
 
 3506    data.isPositionBased = isPositionBased();
 
 3509    appendLogText(
i18n(
"Launching Aberration Inspector run %1...", m_abInsRun));
 
 3511                                        m_abInsNumStars, m_abInsTileCenterOffset));
 
 3518bool Focus::initScanStartPos(
const bool force, 
const int initialPosition)
 
 3522        if (!m_OpsFocusProcess->focusScanStartPos->isChecked())
 
 3525        if (!m_OpsFocusProcess->focusScanAlwaysOn->isChecked() && !m_AFRerun)
 
 3530    inScanStartPos = 
true;
 
 3531    initialFocuserAbsPosition = initialPosition;
 
 3532    m_scanMeasure.clear();
 
 3533    m_scanPosition.clear();
 
 3535    appendLogText(
i18n(
"Starting scan for initial focuser position."));
 
 3536    emit setTitle(
QString(
i18n(
"Scanning for starting position...")), 
true);
 
 3538    if (!changeFocus(initialPosition - currentPosition))
 
 3539        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
 
 3544void Focus::scanStartPos()
 
 3547    if (currentHFR == INVALID_STAR_MEASURE)
 
 3549        if (noStarCount < MAX_RECAPTURE_RETRIES)
 
 3552            appendLogText(
i18n(
"No stars detected, capturing again..."));
 
 3558            appendLogText(
i18n(
"Failed to detect any stars. Aborting..."));
 
 3559            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
 
 3565    if (++absIterations > MAXIMUM_ABS_ITERATIONS)
 
 3567        appendLogText(
i18n(
"Scan Start Pos: exceeded max iterations %1", MAXIMUM_ABS_ITERATIONS));
 
 3568        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_MAX_ITERS);
 
 3573    m_scanPosition.push_back(currentPosition);
 
 3574    m_scanMeasure.push_back(currentMeasure);
 
 3577    const int step = m_scanPosition.size();
 
 3578    const int maxSteps = m_OpsFocusProcess->focusScanDatapoints->value();
 
 3579    const int stepSize = m_OpsFocusMechanics->focusTicks->value() * m_OpsFocusProcess->focusScanStepSizeFactor->value();
 
 3580    emit newHFRPlotPosition(
static_cast<double>(currentPosition), currentMeasure, pow(currentWeight, -0.5), 
false, stepSize,
 
 3582    if (step < maxSteps)
 
 3585        emit setTitle(
QString(
i18n(
"Scanning for starting position %1/%2", step, maxSteps)), 
true);
 
 3586        deltaPos = step * stepSize * std::pow(-1, step + 1);
 
 3591        auto it = std::min_element(std::begin(m_scanMeasure), std::end(m_scanMeasure));
 
 3592        auto min = std::distance(std::begin(m_scanMeasure), it);
 
 3593        if (min >= m_OpsFocusProcess->focusScanDatapoints->value() - 2)
 
 3596            deltaPos = m_scanPosition[min] - currentPosition;
 
 3597            m_scanPosition.clear();
 
 3598            m_scanMeasure.clear();
 
 3599            emit setTitle(
QString(
i18n(
"No scan minimum - widening search...")), 
true);
 
 3604            if (m_AutofocusReason == FOCUS_FOCUS_ADVISOR)
 
 3605                focusAdvisor->setInFocusAdvisor(
false);
 
 3607            const int initialPosition = m_scanPosition[min];
 
 3608            setupLinearFocuser(initialPosition);
 
 3609            inScanStartPos = 
false;
 
 3611            deltaPos = linearRequestedPosition - currentPosition;
 
 3612            emit setTitle(
QString(
i18n(
"Scan Start Position %1 Found", initialPosition)), 
true);
 
 3613            appendLogText(
i18n(
"Scan Start Position %1 found", initialPosition));
 
 3616    if (!changeFocus(deltaPos))
 
 3617        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
 
 3620void Focus::autoFocusLinear()
 
 3622    if (!autoFocusChecks())
 
 3625    if (!canAbsMove && !canRelMove && canTimerMove)
 
 3628        if (linearRequestedPosition != currentPosition)
 
 3631            qCDebug(KSTARS_EKOS_FOCUS) << 
"Linear: warning, changing position " << currentPosition << 
" to " 
 3632                                       << linearRequestedPosition;
 
 3634            currentPosition = linearRequestedPosition;
 
 3639    bool useFocusStarsHFR = m_OpsFocusSettings->focusUseFullField->isChecked()
 
 3640                            && m_OpsFocusProcess->focusFramesCount->value() == 1;
 
 3641    auto focusStars = useFocusStarsHFR || (m_FocusAlgorithm == FOCUS_LINEAR1PASS) ? &(m_ImageData->getStarCenters()) : 
nullptr;
 
 3643    linearRequestedPosition = linearFocuser->newMeasurement(currentPosition, currentMeasure, currentWeight, focusStars);
 
 3644    if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && linearFocuser->isDone() && linearFocuser->solution() != -1)
 
 3647        plotLinearFinalUpdates();
 
 3649            startAberrationInspector();
 
 3655    if (linearFocuser->isDone())
 
 3657        if (linearFocuser->solution() != -1)
 
 3660            if (m_AutofocusReason == FOCUS_FOCUS_ADVISOR)
 
 3662                if (focusAdvisor->analyseAF())
 
 3663                    completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_ADVISOR_RERUN, 
"", 
false);
 
 3665                    completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE, 
"", 
false);
 
 3667            else if (m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
 
 3669                completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE, 
"", 
false);
 
 3670            else if (R2 >= m_OpsFocusProcess->focusR2Limit->value())
 
 3674                qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"Linear Curve Fit check passed R2=%1 focusR2Limit=%2").
arg(R2).
arg(
 
 3675                                               m_OpsFocusProcess->focusR2Limit->value());
 
 3676                completeFocusProcedure(Ekos::FOCUS_COMPLETE, FOCUS_FAIL_NONE, 
"", 
false);
 
 3679            else if (m_R2Retries == 0)
 
 3682                appendLogText(
i18n(
"Curve Fit check failed R2=%1 focusR2Limit=%2 retrying...", R2,
 
 3683                                   m_OpsFocusProcess->focusR2Limit->value()));
 
 3686                completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_R2, failCodeInfo, 
false);
 
 3692                appendLogText(
i18n(
"Curve Fit check failed again R2=%1 focusR2Limit=%2 but continuing...", R2,
 
 3693                                   m_OpsFocusProcess->focusR2Limit->value()));
 
 3694                completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE, 
"", 
false);
 
 3700            qCDebug(KSTARS_EKOS_FOCUS) << linearFocuser->doneReason();
 
 3701            AutofocusFailReason failCode = linearFocuser->getFailCode();
 
 3702            appendLogText(
i18n(
"Linear autofocus algorithm aborted: %1", AutofocusFailReasonStr[failCode]));
 
 3703            completeFocusProcedure(Ekos::FOCUS_ABORTED, failCode, 
"", 
false);
 
 3709        const int delta = linearRequestedPosition - currentPosition;
 
 3711        if (!changeFocus(delta))
 
 3712            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE, 
"", 
false);
 
 3718void Focus::autoFocusAbs()
 
 3722    static int minHFRPos = 0, focusOutLimit = 0, focusInLimit = 0, lastHFRPos = 0, fluctuations = 0;
 
 3723    static double minHFR = 0, lastDelta = 0;
 
 3724    double targetPosition = 0;
 
 3725    bool ignoreLimitedDelta = 
false;
 
 3727    QString deltaTxt = 
QString(
"%1").
arg(fabs(currentHFR - minHFR) * 100.0, 0, 
'g', 3);
 
 3730    qCDebug(KSTARS_EKOS_FOCUS) << 
"===============================";
 
 3731    qCDebug(KSTARS_EKOS_FOCUS) << 
"Current HFR: " << currentHFR << 
" Current Position: " << currentPosition;
 
 3732    qCDebug(KSTARS_EKOS_FOCUS) << 
"Last minHFR: " << minHFR << 
" Last MinHFR Pos: " << minHFRPos;
 
 3733    qCDebug(KSTARS_EKOS_FOCUS) << 
"Delta: " << deltaTxt << 
"%";
 
 3734    qCDebug(KSTARS_EKOS_FOCUS) << 
"========================================";
 
 3737        appendLogText(
i18n(
"FITS received. HFR %1 @ %2. Delta (%3%)", HFRText, currentPosition, deltaTxt));
 
 3739        appendLogText(
i18n(
"FITS received. HFR %1 @ %2.", HFRText, currentPosition));
 
 3741    if (!autoFocusChecks())
 
 3744    addPlotPosition(currentPosition, currentHFR);
 
 3746    switch (m_LastFocusDirection)
 
 3749            lastHFR                   = currentHFR;
 
 3750            initialFocuserAbsPosition = currentPosition;
 
 3751            minHFR                    = currentHFR;
 
 3752            minHFRPos                 = currentPosition;
 
 3762            if (absMotionMax < currentPosition + pulseDuration)
 
 3764                if (currentPosition < absMotionMax)
 
 3766                    pulseDuration = absMotionMax - currentPosition;
 
 3771                    m_LastFocusDirection = FOCUS_IN;
 
 3774            else if (currentPosition + pulseDuration < absMotionMin)
 
 3776                if (absMotionMin < currentPosition)
 
 3778                    pulseDuration = currentPosition - absMotionMin;
 
 3783                    m_LastFocusDirection = FOCUS_OUT;
 
 3787            m_LastFocusDirection = (pulseDuration > 0) ? FOCUS_OUT : FOCUS_IN;
 
 3788            if (!changeFocus(pulseDuration, 
false))
 
 3789                completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
 
 3795            if (reverseDir && focusInLimit && focusOutLimit &&
 
 3796                    fabs(currentHFR - minHFR) < (m_OpsFocusProcess->focusTolerance->value() / 100.0) && HFRInc == 0)
 
 3798                if (absIterations <= 2)
 
 3800                    QString message = 
i18n(
"Change in HFR is too small. Try increasing the step size or decreasing the tolerance.");
 
 3801                    appendLogText(message);
 
 3802                    KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
 
 3803                    completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_SMALL_HFR);
 
 3805                else if (noStarCount > 0)
 
 3807                    QString message = 
i18n(
"Failed to detect focus star in frame. Capture and select a focus star.");
 
 3808                    appendLogText(message);
 
 3809                    KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
 
 3810                    completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
 
 3814                    completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
 
 3818            else if (currentHFR < lastHFR)
 
 3821                if (HFRInc >= 1 && m_LastFocusDirection == FOCUS_OUT && lastHFRPos < focusInLimit && fabs(currentHFR - lastHFR) > 0.1)
 
 3823                    focusInLimit = lastHFRPos;
 
 3824                    qCDebug(KSTARS_EKOS_FOCUS) << 
"New FocusInLimit " << focusInLimit;
 
 3826                else if (HFRInc >= 1 && m_LastFocusDirection == FOCUS_IN && lastHFRPos > focusOutLimit &&
 
 3827                         fabs(currentHFR - lastHFR) > 0.1)
 
 3829                    focusOutLimit = lastHFRPos;
 
 3830                    qCDebug(KSTARS_EKOS_FOCUS) << 
"New FocusOutLimit " << focusOutLimit;
 
 3833                double factor = std::max(1.0, HFRDec / 2.0);
 
 3834                if (m_LastFocusDirection == FOCUS_IN)
 
 3835                    targetPosition = currentPosition - (pulseDuration * factor);
 
 3837                    targetPosition = currentPosition + (pulseDuration * factor);
 
 3839                qCDebug(KSTARS_EKOS_FOCUS) << 
"current Position" << currentPosition << 
" targetPosition " << targetPosition;
 
 3841                lastHFR = currentHFR;
 
 3844                if (lastHFR < minHFR)
 
 3847                    minHFRPos = currentPosition;
 
 3848                    qCDebug(KSTARS_EKOS_FOCUS) << 
"new minHFR " << minHFR << 
" @ position " << minHFRPos;
 
 3851                lastHFRPos = currentPosition;
 
 3858                    if (plot_position.count() >= 2)
 
 3860                        plot_position.remove(plot_position.count() - 2);
 
 3861                        plot_value.remove(plot_value.count() - 2);
 
 3875                lastHFR      = currentHFR;
 
 3876                lastHFRPos   = currentPosition;
 
 3885                    qCDebug(KSTARS_EKOS_FOCUS) << 
"Focus is moving away from optimal HFR.";
 
 3888                    if (m_LastFocusDirection == FOCUS_IN)
 
 3890                        focusInLimit = currentPosition;
 
 3891                        qCDebug(KSTARS_EKOS_FOCUS) << 
"Setting focus IN limit to " << focusInLimit;
 
 3895                        focusOutLimit = currentPosition;
 
 3896                        qCDebug(KSTARS_EKOS_FOCUS) << 
"Setting focus OUT limit to " << focusOutLimit;
 
 3899                    if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && plot_position.count() > 4)
 
 3901                        polynomialFit.reset(
new PolynomialFit(2, 5, plot_position, plot_value));
 
 3902                        double a = *std::min_element(plot_position.constBegin(), plot_position.constEnd());
 
 3903                        double b = *std::max_element(plot_position.constBegin(), plot_position.constEnd());
 
 3904                        double min_position = 0, min_hfr = 0;
 
 3905                        isVShapeSolution = polynomialFit->findMinimum(minHFRPos, a, b, &min_position, &min_hfr);
 
 3906                        qCDebug(KSTARS_EKOS_FOCUS) << 
"Found Minimum?" << (isVShapeSolution ? 
"Yes" : 
"No");
 
 3907                        if (isVShapeSolution)
 
 3909                            ignoreLimitedDelta = 
true;
 
 3910                            qCDebug(KSTARS_EKOS_FOCUS) << 
"Minimum Solution:" << min_hfr << 
"@" << min_position;
 
 3911                            targetPosition = round(min_position);
 
 3912                            appendLogText(
i18n(
"Found polynomial solution @ %1", 
QString::number(min_position, 
'f', 0)));
 
 3914                            emit drawPolynomial(polynomialFit.get(), isVShapeSolution, 
true);
 
 3915                            emit minimumFound(min_position, min_hfr);
 
 3919                            emit drawPolynomial(polynomialFit.get(), isVShapeSolution, 
false);
 
 3928                    if (std::abs(lastDelta) > 0)
 
 3929                        targetPosition = currentPosition + lastDelta;
 
 3931                        targetPosition = currentPosition + pulseDuration;
 
 3933                else if (isVShapeSolution == 
false)
 
 3935                    ignoreLimitedDelta = 
true;
 
 3937                    if (m_LastFocusDirection == FOCUS_OUT)
 
 3938                        targetPosition = minHFRPos - pulseDuration / 2;
 
 3940                        targetPosition = minHFRPos + pulseDuration / 2;
 
 3943                qCDebug(KSTARS_EKOS_FOCUS) << 
"new targetPosition " << targetPosition;
 
 3947            if (focusInLimit != 0 && m_LastFocusDirection == FOCUS_IN && targetPosition < focusInLimit)
 
 3949                targetPosition = focusInLimit;
 
 3950                qCDebug(KSTARS_EKOS_FOCUS) << 
"Limiting target pulse to focus in limit " << targetPosition;
 
 3952            else if (focusOutLimit != 0 && m_LastFocusDirection == FOCUS_OUT && targetPosition > focusOutLimit)
 
 3954                targetPosition = focusOutLimit;
 
 3955                qCDebug(KSTARS_EKOS_FOCUS) << 
"Limiting target pulse to focus out limit " << targetPosition;
 
 3959            if (targetPosition < absMotionMin)
 
 3960                targetPosition = absMotionMin;
 
 3961            else if (targetPosition > absMotionMax)
 
 3962                targetPosition = absMotionMax;
 
 3965            if (targetPosition == currentPosition)
 
 3969                if (targetPosition == minHFRPos || isVShapeSolution)
 
 3971                    appendLogText(
"Stopping at minimum recorded HFR position.");
 
 3972                    completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
 
 3976                    QString message = 
i18n(
"Focuser cannot move further, device limits reached. Autofocus aborted.");
 
 3977                    appendLogText(message);
 
 3978                    KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
 
 3979                    completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_OOB);
 
 3985            if (fluctuations >= MAXIMUM_FLUCTUATIONS)
 
 3987                QString message = 
i18n(
"Unstable fluctuations. Try increasing initial step size or exposure time.");
 
 3988                appendLogText(message);
 
 3989                KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
 
 3990                completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FLUCTUATIONS);
 
 3995            if (focusOutLimit && focusOutLimit == focusInLimit)
 
 3997                QString message = 
i18n(
"Deadlock reached. Please try again with different settings.");
 
 3998                appendLogText(message);
 
 3999                KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
 
 4000                completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_DEADLOCK);
 
 4005            if (fabs(targetPosition - initialFocuserAbsPosition) > m_OpsFocusMechanics->focusMaxTravel->value())
 
 4007                int minTravelLimit = qMax(0.0, initialFocuserAbsPosition - m_OpsFocusMechanics->focusMaxTravel->value());
 
 4008                int maxTravelLimit = qMin(absMotionMax, initialFocuserAbsPosition + m_OpsFocusMechanics->focusMaxTravel->value());
 
 4012                if (fabs(currentPosition - minTravelLimit) > 10 && targetPosition < minTravelLimit)
 
 4014                    targetPosition = minTravelLimit;
 
 4017                else if (fabs(currentPosition - maxTravelLimit) > 10 && targetPosition > maxTravelLimit)
 
 4019                    targetPosition = maxTravelLimit;
 
 4023                    qCDebug(KSTARS_EKOS_FOCUS) << 
"targetPosition (" << targetPosition << 
") - initHFRAbsPos (" 
 4024                                               << initialFocuserAbsPosition << 
") exceeds maxTravel distance of " << m_OpsFocusMechanics->focusMaxTravel->value();
 
 4026                    QString message = 
i18n(
"Maximum travel limit reached. Autofocus aborted.");
 
 4027                    appendLogText(message);
 
 4028                    KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
 
 4029                    completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_OOB);
 
 4035            lastDelta = (targetPosition - currentPosition);
 
 4037            qCDebug(KSTARS_EKOS_FOCUS) << 
"delta (targetPosition - currentPosition) " << lastDelta;
 
 4040            if (ignoreLimitedDelta == 
false)
 
 4042                double limitedDelta = qMax(-1.0 * m_OpsFocusMechanics->focusMaxSingleStep->value(),
 
 4043                                           qMin(1.0 * m_OpsFocusMechanics->focusMaxSingleStep->value(), lastDelta));
 
 4044                if (std::fabs(limitedDelta - lastDelta) > 0)
 
 4046                    qCDebug(KSTARS_EKOS_FOCUS) << 
"Limited delta to maximum permitted single step " <<
 
 4047                                               m_OpsFocusMechanics->focusMaxSingleStep->value();
 
 4048                    lastDelta = limitedDelta;
 
 4052            m_LastFocusDirection = (lastDelta > 0) ? FOCUS_OUT : FOCUS_IN;
 
 4053            if (!changeFocus(lastDelta, 
false))
 
 4054                completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
 
 4060void Focus::addPlotPosition(
int pos, 
double value, 
bool plot)
 
 4062    plot_position.append(pos);
 
 4063    plot_value.append(value);
 
 4065        emit newHFRPlotPosition(
static_cast<double>(pos), value, 1.0, 
false, pulseDuration);
 
 4071void Focus::updatePlotPosition()
 
 4073    if (m_FocusAlgorithm == FOCUS_LINEAR1PASS)
 
 4076        if (inScanStartPos || focusAdvisor->inFocusAdvisor())
 
 4079            plot_position.clear();
 
 4081            plot_weight.clear();
 
 4082            plot_outlier.clear();
 
 4086            linearFocuser->getPass1Measurements(&positions, &plot_value, &plot_weight, &plot_outlier);
 
 4087            plot_position.clear();
 
 4088            for (
int i = 0; i < positions.
count(); i++)
 
 4089                plot_position.append(positions[i]);
 
 4092            if (linearFocuser && linearFocuser->isDone() && linearFocuser->solution() != -1)
 
 4094                plot_position.append(linearFocuser->solution());
 
 4095                plot_value.append(linearFocuser->solutionValue());
 
 4096                plot_weight.append(linearFocuser->solutionWeight());
 
 4097                plot_outlier.append(
false);
 
 4101    else if (m_FocusAlgorithm == FOCUS_LINEAR)
 
 4104        linearFocuser->getMeasurements(&positions, &plot_value, &plot_weight);
 
 4105        plot_position.
clear();
 
 4106        plot_outlier.clear();
 
 4107        for (
int i = 0; i < positions.
count(); i++)
 
 4109            plot_position.append(positions[i]);
 
 4111            plot_outlier.append(
false);
 
 4117        for (
int i = 0; i < plot_position.count(); i++)
 
 4119            plot_weight.append(1.0);
 
 4120            plot_outlier.append(
false);
 
 4125void Focus::autoFocusRel()
 
 4127    static int noStarCount = 0;
 
 4128    static double minHFR   = 1e6;
 
 4129    QString deltaTxt       = 
QString(
"%1").
arg(fabs(currentHFR - minHFR) * 100.0, 0, 
'g', 2);
 
 4133    appendLogText(
i18n(
"FITS received. HFR %1. Delta (%2%) Min HFR (%3)", HFRText, deltaTxt, minHFRText));
 
 4135    if (pulseDuration <= MINIMUM_PULSE_TIMER)
 
 4137        appendLogText(
i18n(
"Autofocus failed to reach proper focus. Try adjusting the tolerance value."));
 
 4138        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_TOLERANCE);
 
 4143    if (currentHFR == INVALID_STAR_MEASURE)
 
 4145        if (noStarCount < MAX_RECAPTURE_RETRIES)
 
 4148            appendLogText(
i18n(
"No stars detected, capturing again..."));
 
 4152        else if (m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
 
 4154            appendLogText(
i18n(
"Failed to detect any stars at position %1. Continuing...", currentPosition));
 
 4157        else if(!m_OpsFocusProcess->focusDonut->isChecked())
 
 4160            appendLogText(
i18n(
"Failed to detect any stars. Reset frame and try again."));
 
 4161            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
 
 4168    switch (m_LastFocusDirection)
 
 4171            lastHFR = currentHFR;
 
 4173            m_LastFocusDirection = FOCUS_IN;
 
 4174            changeFocus(-pulseDuration, 
false);
 
 4179            if (fabs(currentHFR - minHFR) < (m_OpsFocusProcess->focusTolerance->value() / 100.0) && HFRInc == 0)
 
 4181                completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
 
 4183            else if (currentHFR < lastHFR)
 
 4185                if (currentHFR < minHFR)
 
 4186                    minHFR = currentHFR;
 
 4188                lastHFR = currentHFR;
 
 4189                changeFocus(m_LastFocusDirection == FOCUS_IN ? -pulseDuration : pulseDuration, 
false);
 
 4196                lastHFR = currentHFR;
 
 4200                pulseDuration *= 0.75;
 
 4202                if (!changeFocus(m_LastFocusDirection == FOCUS_IN ? pulseDuration : -pulseDuration, 
false))
 
 4203                    completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
 
 4206                m_LastFocusDirection = (m_LastFocusDirection == FOCUS_IN) ? FOCUS_OUT : FOCUS_IN;
 
 4212void Focus::handleFocusButtonEvent()
 
 4214    bool inward = (sender() == focusInB);
 
 4218    updateButtonColors(inward ? focusInB : focusOutB, shift, ctrl);
 
 4221        speedup *= m_OpsFocusMechanics->speedupShift->value();
 
 4223        speedup *= m_OpsFocusMechanics->speedupCtrl->value();
 
 4226        focusIn(-1, speedup);
 
 4228        focusOut(-1, speedup);
 
 4231void Focus::autoFocusProcessPositionChange(IPState state)
 
 4233    if (state == IPS_OK)
 
 4239        if (focuserAdditionalMovement > 0)
 
 4241            int temp = focuserAdditionalMovement;
 
 4242            focuserAdditionalMovement = 0;
 
 4244            qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"Undoing overscan extension. Moving back in by %1 ticks in %2s")
 
 4245                                       .
arg(temp).
arg(m_OpsFocusMechanics->focusOverscanDelay->value());
 
 4247            QTimer::singleShot(m_OpsFocusMechanics->focusOverscanDelay->value() * 1000, 
this, [
this, temp]()
 
 4249                if (!changeFocus(-temp, focuserAdditionalMovementUpdateDir))
 
 4251                    appendLogText(i18n(
"Focuser error, check INDI panel."));
 
 4252                    completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
 
 4256        else if (inAutoFocus && !inAFOptimise)
 
 4259            if (m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
 
 4260                if (abs(linearRequestedPosition - currentPosition) > m_OpsFocusMechanics->focusTicks->value())
 
 4261                    qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"Focus positioning error: requested position %1, current position %2")
 
 4262                                               .
arg(linearRequestedPosition).
arg(currentPosition);
 
 4264            qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"Focus position reached at %1, starting capture in %2 seconds.").
arg(
 
 4265                                           currentPosition).
arg(m_OpsFocusMechanics->focusSettleTime->value());
 
 4267            if (m_OpsFocusProcess->focusDonut->isChecked())
 
 4268                donutTimeDilation();
 
 4269            capture(m_OpsFocusMechanics->focusSettleTime->value());
 
 4272    else if (state == IPS_ALERT)
 
 4274        appendLogText(
i18n(
"Focuser error, check INDI panel."));
 
 4275        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_ERROR);
 
 4278        qCDebug(KSTARS_EKOS_FOCUS) <<
 
 4279                                   QString(
"autoFocusProcessPositionChange called with state %1 (%2), focuserAdditionalMovement=%3, inAutoFocus=%4, m_captureInProgress=%5, currentPosition=%6")
 
 4280                                   .
arg(state).
arg(pstateStr(state)).
arg(focuserAdditionalMovement).
arg(inAutoFocus).
arg(m_captureInProgress)
 
 4281                                   .
arg(currentPosition);
 
 4285void Focus::donutTimeDilation()
 
 4287    if (m_OpsFocusProcess->focusTimeDilation->value() == 1.0 || inScanStartPos || focusAdvisor->inFocusAdvisor())
 
 4291    const double centre = (m_OpsFocusMechanics->focusNumSteps->value() + 1.0) / 2.0;
 
 4293    const int currentStep = linearFocuser->currentStep() + 1;
 
 4295    if (currentStep <= m_OpsFocusMechanics->focusNumSteps->value())
 
 4296        distance = std::abs(centre - currentStep);
 
 4300    double multiplier = 
distance / (centre - 1.0) * m_OpsFocusProcess->focusTimeDilation->value();
 
 4301    multiplier = std::max(multiplier, 1.0);
 
 4302    const double exposure = multiplier * m_donutOrigExposure;
 
 4303    focusExposure->setValue(exposure);
 
 4304    qCDebug(KSTARS_EKOS_FOCUS) << 
"Donut time dilation for point " << currentStep << 
" from " << m_donutOrigExposure << 
" to " 
 4311    if (m_Focuser == 
nullptr || prop.getType() != INDI_NUMBER || prop.getDeviceName() != m_Focuser->getDeviceName())
 
 4314    auto nvp = prop.getNumber();
 
 4320    if (nvp->isNameMatch(
"FOCUS_BACKLASH_STEPS"))
 
 4322        m_OpsFocusMechanics->focusBacklash->setValue(nvp->np[0].value);
 
 4326    if (nvp->isNameMatch(
"ABS_FOCUS_POSITION"))
 
 4331            if (m_DebugFocuserCounter++ >= 10 && m_DebugFocuserCounter <= 14)
 
 4333                if (m_DebugFocuserCounter == 14)
 
 4334                    m_DebugFocuserCounter = 0;
 
 4340        m_FocusMotionTimer.stop();
 
 4341        INumber *
pos = IUFindNumber(nvp, 
"FOCUS_ABSOLUTE_POSITION");
 
 4342        IPState newState = nvp->s;
 
 4347            int newPosition = 
static_cast<int>(
pos->value);
 
 4352            if (currentPosition == newPosition && currentPositionState == newState)
 
 4354                if (logPositionAndState)
 
 4356                    qCDebug(KSTARS_EKOS_FOCUS) << 
"Focuser position " << currentPosition << 
" and state:" 
 4357                                               << pstateStr(currentPositionState) << 
" unchanged";
 
 4358                    logPositionAndState = 
false;
 
 4364                logPositionAndState = 
true;
 
 4367            currentPositionState = newState;
 
 4369            if (currentPosition != newPosition)
 
 4371                currentPosition = newPosition;
 
 4372                qCDebug(KSTARS_EKOS_FOCUS) << 
"Abs Focuser position changed to " << currentPosition << 
"State:" << pstateStr(
 
 4373                                               currentPositionState);
 
 4375                emit absolutePositionChanged(currentPosition);
 
 4379            qCDebug(KSTARS_EKOS_FOCUS) << 
"Can't access FOCUS_ABSOLUTE_POSITION. Current state:" 
 4380                                       << pstateStr(currentPositionState) << 
" New state:" << pstateStr(newState);
 
 4382        if (newState != IPS_OK)
 
 4384            if (inAutoFocus || inAdjustFocus || adaptFocus->inAdaptiveFocus())
 
 4388                qCDebug(KSTARS_EKOS_FOCUS) << 
"Restarting focus motion timer, state " << pstateStr(newState);
 
 4389                m_FocusMotionTimer.start();
 
 4395            if (focuserAdditionalMovement == 0)
 
 4400                if (focuserAdditionalMovement == 0)
 
 4402                    inAdjustFocus = 
false;
 
 4403                    emit focusPositionAdjusted();
 
 4410                if (focuserAdditionalMovement == 0)
 
 4412                    inAFOptimise = 
false;
 
 4413                    emit focusAFOptimise();
 
 4418            if (adaptFocus->inAdaptiveFocus())
 
 4420                if (focuserAdditionalMovement == 0)
 
 4422                    adaptFocus->adaptiveFocusAdmin(currentPosition, 
true, 
true);
 
 4427            if (m_RestartState == RESTART_NOW && 
status() != Ekos::FOCUS_ABORTED)
 
 4429                if (focuserAdditionalMovement == 0)
 
 4431                    m_RestartState = RESTART_NONE;
 
 4433                    inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos = 
false;
 
 4434                    adaptFocus->setInAdaptiveFocus(
false);
 
 4435                    focusAdvisor->setInFocusAdvisor(
false);
 
 4437                    runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
 
 4441            else if (m_RestartState == RESTART_ABORT && focuserAdditionalMovement == 0)
 
 4447                completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
 
 4448                m_RestartState = RESTART_NONE;
 
 4449                inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos = 
false;
 
 4450                adaptFocus->setInAdaptiveFocus(
false);
 
 4451                focusAdvisor->setInFocusAdvisor(
false);
 
 4457            autoFocusProcessPositionChange(newState);
 
 4458        else if (newState == IPS_ALERT)
 
 4466    if (nvp->isNameMatch(
"manualfocusdrive"))
 
 4471            if (m_DebugFocuserCounter++ >= 10 && m_DebugFocuserCounter <= 14)
 
 4473                if (m_DebugFocuserCounter == 14)
 
 4474                    m_DebugFocuserCounter = 0;
 
 4480        m_FocusMotionTimer.stop();
 
 4482        INumber *
pos = IUFindNumber(nvp, 
"manualfocusdrive");
 
 4483        IPState newState = nvp->s;
 
 4484        if (
pos && newState == IPS_OK)
 
 4486            if (focuserAdditionalMovement == 0)
 
 4489            currentPosition += 
pos->value;
 
 4490            absTicksLabel->setText(
QString::number(
static_cast<int>(currentPosition)));
 
 4491            emit absolutePositionChanged(currentPosition);
 
 4494        if (inAdjustFocus && newState == IPS_OK)
 
 4496            if (focuserAdditionalMovement == 0)
 
 4498                inAdjustFocus = 
false;
 
 4499                emit focusPositionAdjusted();
 
 4504        if (inAFOptimise && newState == IPS_OK)
 
 4506            if (focuserAdditionalMovement == 0)
 
 4508                inAFOptimise = 
false;
 
 4509                emit focusAFOptimise();
 
 4514        if (adaptFocus->inAdaptiveFocus() && newState == IPS_OK)
 
 4516            if (focuserAdditionalMovement == 0)
 
 4518                adaptFocus->adaptiveFocusAdmin(currentPosition, 
true, 
true);
 
 4524        if (m_RestartState == RESTART_NOW && newState == IPS_OK && 
status() != Ekos::FOCUS_ABORTED)
 
 4526            if (focuserAdditionalMovement == 0)
 
 4528                m_RestartState = RESTART_NONE;
 
 4530                inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos = 
false;
 
 4531                adaptFocus->setInAdaptiveFocus(
false);
 
 4532                focusAdvisor->setInFocusAdvisor(
false);
 
 4534                runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
 
 4538        else if (m_RestartState == RESTART_ABORT && newState == IPS_OK)
 
 4541            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
 
 4542            m_RestartState = RESTART_NONE;
 
 4543            inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos = 
false;
 
 4544            adaptFocus->setInAdaptiveFocus(
false);
 
 4545            focusAdvisor->setInFocusAdvisor(
false);
 
 4550            autoFocusProcessPositionChange(newState);
 
 4551        else if (newState == IPS_ALERT)
 
 4557    if (nvp->isNameMatch(
"REL_FOCUS_POSITION"))
 
 4559        m_FocusMotionTimer.stop();
 
 4561        INumber *
pos = IUFindNumber(nvp, 
"FOCUS_RELATIVE_POSITION");
 
 4562        IPState newState = nvp->s;
 
 4563        if (
pos && newState == IPS_OK)
 
 4565            if (focuserAdditionalMovement == 0)
 
 4568            currentPosition += 
pos->value * (m_LastFocusDirection == FOCUS_IN ? -1 : 1);
 
 4569            qCDebug(KSTARS_EKOS_FOCUS)
 
 4570                    << 
QString(
"Rel Focuser position moved %1 by %2 to %3")
 
 4571                    .
arg((m_LastFocusDirection == FOCUS_IN) ? 
"in" : 
"out").
arg(
pos->value).
arg(currentPosition);
 
 4572            absTicksLabel->setText(
QString::number(
static_cast<int>(currentPosition)));
 
 4573            emit absolutePositionChanged(currentPosition);
 
 4576        if (inAdjustFocus && newState == IPS_OK)
 
 4578            if (focuserAdditionalMovement == 0)
 
 4580                inAdjustFocus = 
false;
 
 4581                emit focusPositionAdjusted();
 
 4586        if (inAFOptimise && newState == IPS_OK)
 
 4588            if (focuserAdditionalMovement == 0)
 
 4590                inAFOptimise = 
false;
 
 4591                emit focusAFOptimise();
 
 4596        if (adaptFocus->inAdaptiveFocus() && newState == IPS_OK)
 
 4598            if (focuserAdditionalMovement == 0)
 
 4600                adaptFocus->adaptiveFocusAdmin(currentPosition, 
true, 
true);
 
 4606        if (m_RestartState == RESTART_NOW && newState == IPS_OK && 
status() != Ekos::FOCUS_ABORTED)
 
 4608            if (focuserAdditionalMovement == 0)
 
 4610                m_RestartState = RESTART_NONE;
 
 4612                inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos = 
false;
 
 4613                adaptFocus->setInAdaptiveFocus(
false);
 
 4614                focusAdvisor->setInFocusAdvisor(
false);
 
 4616                runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
 
 4620        else if (m_RestartState == RESTART_ABORT && newState == IPS_OK)
 
 4623            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
 
 4624            m_RestartState = RESTART_NONE;
 
 4625            inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos = 
false;
 
 4626            adaptFocus->setInAdaptiveFocus(
false);
 
 4627            focusAdvisor->setInFocusAdvisor(
false);
 
 4632            autoFocusProcessPositionChange(newState);
 
 4633        else if (newState == IPS_ALERT)
 
 4642    if (nvp->isNameMatch(
"FOCUS_TIMER"))
 
 4644        IPState newState = nvp->s;
 
 4645        m_FocusMotionTimer.stop();
 
 4647        if (m_RestartState == RESTART_NOW && newState == IPS_OK && 
status() != Ekos::FOCUS_ABORTED)
 
 4649            if (focuserAdditionalMovement == 0)
 
 4651                m_RestartState = RESTART_NONE;
 
 4653                inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos = 
false;
 
 4654                adaptFocus->setInAdaptiveFocus(
false);
 
 4655                focusAdvisor->setInFocusAdvisor(
false);
 
 4657                runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
 
 4661        else if (m_RestartState == RESTART_ABORT && newState == IPS_OK)
 
 4664            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
 
 4665            m_RestartState = RESTART_NONE;
 
 4666            inAutoFocus = inBuildOffsets = inAFOptimise = inAdjustFocus = inScanStartPos = 
false;
 
 4667            adaptFocus->setInAdaptiveFocus(
false);
 
 4668            focusAdvisor->setInFocusAdvisor(
false);
 
 4672        if (canAbsMove == 
false && canRelMove == 
false)
 
 4675            INumber *
pos = IUFindNumber(nvp, 
"FOCUS_TIMER_VALUE");
 
 4678                currentPosition += 
pos->value * (m_LastFocusDirection == FOCUS_IN ? -1 : 1);
 
 4679                qCDebug(KSTARS_EKOS_FOCUS)
 
 4680                        << 
QString(
"Timer Focuser position moved %1 by %2 to %3")
 
 4681                        .
arg((m_LastFocusDirection == FOCUS_IN) ? 
"in" : 
"out").
arg(
pos->value).
arg(currentPosition);
 
 4684            if (
pos && newState == IPS_OK && focuserAdditionalMovement == 0)
 
 4687            if (inAdjustFocus && newState == IPS_OK)
 
 4689                if (focuserAdditionalMovement == 0)
 
 4691                    inAdjustFocus = 
false;
 
 4692                    emit focusPositionAdjusted();
 
 4697            if (inAFOptimise && newState == IPS_OK)
 
 4699                if (focuserAdditionalMovement == 0)
 
 4701                    inAFOptimise = 
false;
 
 4702                    emit focusAFOptimise();
 
 4707            if (adaptFocus->inAdaptiveFocus() && newState == IPS_OK)
 
 4709                if (focuserAdditionalMovement == 0)
 
 4711                    adaptFocus->adaptiveFocusAdmin(
true, 
true, 
true);
 
 4716            autoFocusProcessPositionChange(newState);
 
 4718        else if (newState == IPS_ALERT)
 
 
 4727    const QString logtext(m_Focuser == 
nullptr ? text : 
QString(
"[%1] %2").arg(m_Focuser->getDeviceName()).
arg(text));
 
 4728    emit newLog(logtext);
 
 
 4731void Focus::appendFocusLogText(
const QString &text)
 
 4733    if (Options::focusLogging())
 
 4735        const QString logtext(m_Focuser == 
nullptr ? text : 
QString(
"[%1] %2").arg(m_Focuser->getDeviceName()).
arg(text));
 
 4736        emit newFocusLog(logtext);
 
 4742    if (m_Camera == 
nullptr)
 
 4748    waitStarSelectTimer.stop();
 
 4751    starMeasureFrames.clear();
 
 4756    setState(Ekos::FOCUS_FRAMING);
 
 
 4765void Focus::resetButtons()
 
 4768    updateButtonColors(focusInB, 
false, 
false);
 
 4769    updateButtonColors(focusOutB, 
false, 
false);
 
 4773        startFocusB->setEnabled(
false);
 
 4774        startAbInsB->setEnabled(
false);
 
 4775        startLoopB->setEnabled(
false);
 
 4776        focusOutB->setEnabled(
true);
 
 4777        focusInB->setEnabled(
true);
 
 4778        startGotoB->setEnabled(canAbsMove);
 
 4779        stopFocusB->setEnabled(
true);
 
 4780        captureB->setEnabled(
false);
 
 4781        opticalTrainCombo->setEnabled(
false);
 
 4782        trainB->setEnabled(
false);
 
 4796        if (disabledWidgets.empty())
 
 4798            AFDisable(trainLabel, 
false);
 
 4799            AFDisable(opticalTrainCombo, 
false);
 
 4800            AFDisable(trainB, 
false);
 
 4801            AFDisable(focuserGroup, 
true);
 
 4802            AFDisable(clearDataB, 
false);
 
 4805            m_FocusGainAFEnabled = focusGain->isEnabled();
 
 4806            m_FocusISOAFEnabled = focusISO->isEnabled();
 
 4807            AFDisable(ccdGroup, 
false);
 
 4809            AFDisable(toolsGroup, 
false);
 
 4812            m_FocusSubFrameAFEnabled = m_OpsFocusSettings->focusSubFrame->isEnabled();
 
 4815            AFDisable(m_OpsFocusSettings, 
false);
 
 4816            AFDisable(m_OpsFocusProcess, 
false);
 
 4817            AFDisable(m_OpsFocusMechanics, 
false);
 
 4818            AFDisable(focusAdvisor->focusAdvGroupBox, 
false);
 
 4819            AFDisable(m_CFZDialog, 
false);
 
 4822            stopFocusB->setEnabled(
true);
 
 4828    for(
int i = 0 ; i < disabledWidgets.size() ; i++)
 
 4829        disabledWidgets[i]->setEnabled(
true);
 
 4830    disabledWidgets.clear();
 
 4832    bool cameraConnected = m_Camera && m_Camera->isConnected();
 
 4833    bool enableCaptureButtons = cameraConnected && (!m_captureInProgress && !m_starDetectInProgress);
 
 4835    captureB->setEnabled(enableCaptureButtons);
 
 4836    resetFrameB->setEnabled(enableCaptureButtons);
 
 4837    startLoopB->setEnabled(enableCaptureButtons);
 
 4838    startFocusB->setEnabled(enableCaptureButtons);
 
 4841    if (cameraConnected)
 
 4843        ccdGroup->setEnabled(
true);
 
 4844        toolsGroup->setEnabled(
true);
 
 4848        ccdGroup->setEnabled(
false);
 
 4849        toolsGroup->setEnabled(
false);
 
 4852    if (m_Focuser && m_Focuser->isConnected())
 
 4854        focusOutB->setEnabled(
true);
 
 4855        focusInB->setEnabled(
true);
 
 4856        startAbInsB->setEnabled(canAbInsStart());
 
 4857        stopFocusB->setEnabled(!enableCaptureButtons);
 
 4858        startGotoB->setEnabled(canAbsMove);
 
 4859        stopGotoB->setEnabled(
true);
 
 4860        focuserGroup->setEnabled(
true);
 
 4864        focusOutB->setEnabled(
false);
 
 4865        focusInB->setEnabled(
false);
 
 4866        startAbInsB->setEnabled(
false);
 
 4867        stopFocusB->setEnabled(
false);
 
 4868        startGotoB->setEnabled(
false);
 
 4869        stopGotoB->setEnabled(
false);
 
 4870        focuserGroup->setEnabled(cameraConnected);
 
 4874void Focus::updateButtonColors(
QPushButton *button, 
bool shift, 
bool ctrl)
 
 4879        stylesheet = 
"background-color: #D32F2F";
 
 4881        stylesheet = 
"background-color: #FFC107";
 
 4883        stylesheet = 
"background-color: #FF5722";
 
 4893bool Focus::canAbInsStart()
 
 4895    return canAbsMove && m_FocusAlgorithm == FOCUS_LINEAR1PASS && m_currentImageMask == FOCUS_MASK_MOSAIC
 
 4896           && m_CurveFit != CurveFitting::FOCUS_QUADRATIC;
 
 4900void Focus::AFDisable(
QWidget * widget, 
const bool children)
 
 4907            if (wid->isEnabled())
 
 4909                wid->setEnabled(
false);
 
 4910                disabledWidgets.push_back(wid);
 
 4919        disabledWidgets.push_back(widget);
 
 4923bool Focus::isFocusGainEnabled()
 
 4925    return (inAutoFocus) ? m_FocusGainAFEnabled : focusGain->isEnabled();
 
 4928bool Focus::isFocusISOEnabled()
 
 4930    return (inAutoFocus) ?  m_FocusISOAFEnabled : focusISO->isEnabled();
 
 4933bool Focus::isFocusSubFrameEnabled()
 
 4935    return (inAutoFocus) ? m_FocusSubFrameAFEnabled : m_OpsFocusSettings->focusSubFrame->isEnabled();
 
 4938void Focus::updateBoxSize(
int value)
 
 4940    if (m_Camera == 
nullptr)
 
 4943    ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 4945    if (targetChip == 
nullptr)
 
 4948    int subBinX, subBinY;
 
 4949    targetChip->getBinning(&subBinX, &subBinY);
 
 4951    QRect trackBox = m_FocusView->getTrackingBox();
 
 4955        QRect(
center.x() - value / (2 * subBinX), 
center.y() - value / (2 * subBinY), value / subBinX, value / subBinY);
 
 4957    m_FocusView->setTrackingBox(trackBox);
 
 4962    if (m_ImageData.isNull())
 
 4969        emit newImage(m_FocusView);
 
 
 4975    if (state() == Ekos::FOCUS_PROGRESS)
 
 4978    if (subFramed == 
false)
 
 4980        rememberStarCenter.setX(
x);
 
 4981        rememberStarCenter.setY(
y);
 
 4984    ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 4986    int subBinX, subBinY;
 
 4987    targetChip->getBinning(&subBinX, &subBinY);
 
 4990    if (subBinX != (focusBinning->currentIndex() + 1))
 
 4996    int offset = (
static_cast<double>(m_OpsFocusSettings->focusBoxSize->value()) / subBinX) * 1.5;
 
 5000    bool squareMovedOutside = 
false;
 
 5002    if (subFramed == 
false && m_OpsFocusSettings->focusSubFrame->isChecked() && targetChip->canSubframe())
 
 5005        if (!isStarMeasureStarBased())
 
 5011        int minX, maxX, minY, maxY, minW, maxW, minH, maxH; 
 
 5013        targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
 
 5016        x     = (
x - offset) * subBinX;
 
 5017        y     = (
y - offset) * subBinY;
 
 5018        int w = offset * 2 * subBinX;
 
 5019        int h = offset * 2 * subBinY;
 
 5038        QVariantMap settings = frameSettings[targetChip];
 
 5043        settings[
"binx"]     = subBinX;
 
 5044        settings[
"biny"]     = subBinY;
 
 5046        frameSettings[targetChip] = settings;
 
 5050        qCDebug(KSTARS_EKOS_FOCUS) << 
"Frame is subframed. X:" << 
x << 
"Y:" << 
y << 
"W:" << w << 
"H:" << h << 
"binX:" << subBinX <<
 
 5053        m_FocusView->setFirstLoad(
true);
 
 5057        if (isStarMeasureStarBased())
 
 5059            starCenter.setX(w / (2 * subBinX));
 
 5060            starCenter.setY(h / (2 * subBinY));
 
 5067        double dist = sqrt((starCenter.x() - 
x) * (starCenter.x() - 
x) + (starCenter.y() - 
y) * (starCenter.y() - 
y));
 
 5069        squareMovedOutside = (dist > (
static_cast<double>(m_OpsFocusSettings->focusBoxSize->value()) / subBinX));
 
 5073        starRect = 
QRect(starCenter.x() - m_OpsFocusSettings->focusBoxSize->value() / (2 * subBinX),
 
 5074                         starCenter.y() - m_OpsFocusSettings->focusBoxSize->value() / (2 * subBinY),
 
 5075                         m_OpsFocusSettings->focusBoxSize->value() / subBinX,
 
 5076                         m_OpsFocusSettings->focusBoxSize->value() / subBinY);
 
 5077        m_FocusView->setTrackingBox(starRect);
 
 5082    starCenter.setZ(subBinX);
 
 5084    if (squareMovedOutside && inAutoFocus == 
false && m_OpsFocusSettings->focusAutoStarEnabled->isChecked())
 
 5086        m_OpsFocusSettings->focusAutoStarEnabled->blockSignals(
true);
 
 5087        m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
 
 5088        m_OpsFocusSettings->focusAutoStarEnabled->blockSignals(
false);
 
 5089        appendLogText(
i18n(
"Disabling Auto Star Selection as star selection box was moved manually."));
 
 5090        starSelected = 
false;
 
 5092    else if (starSelected == 
false)
 
 5094        if (isStarMeasureStarBased())
 
 5099        starSelected = 
true;
 
 5103    waitStarSelectTimer.stop();
 
 5104    FocusState nextState = inAutoFocus ? FOCUS_PROGRESS : FOCUS_IDLE;
 
 5105    if (nextState != state())
 
 5107        setState(nextState);
 
 
 5113    if (inAutoFocus || inAdjustFocus || adaptFocus->inAdaptiveFocus())
 
 5117            str = 
i18n(
"Autofocus");
 
 5118        else if (inAdjustFocus)
 
 5119            str = 
i18n(
"Adjust Focus");
 
 5121            str = 
i18n(
"Adaptive Focus");
 
 5123        if (++m_StartRetries < MAXIMUM_RESTART_ITERATIONS)
 
 5125            appendLogText(
i18n(
"Check focus request - Waiting 10sec for %1 to complete.", str));
 
 5134        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
 
 5140    if (inFocusLoop || inBuildOffsets)
 
 5142        QString str = inFocusLoop ? 
"Focus Looping" : 
" Build Offsets";
 
 5143        qCDebug(KSTARS_EKOS_FOCUS) << 
QString(
"Check Focus rejected, %1 is already running.").
arg(str);
 
 5145    else if (!isStarMeasureStarBased())
 
 5149        qCDebug(KSTARS_EKOS_FOCUS) << 
"Check Focus requested with minimum required HFR" << requiredHFR;
 
 5150        minimumRequiredHFR = requiredHFR;
 
 
 5156void Focus::toggleSubframe(
bool enable)
 
 5158    if (enable == 
false)
 
 5161    m_FocusView->setTrackingBoxEnabled(enable);
 
 5162    starSelected = 
false;
 
 5167        m_OpsFocusSettings->focusNoMaskRB->setChecked(
true);
 
 5172    m_OpsFocusSettings->focusRingMaskRB->setEnabled(!enable);
 
 5173    m_OpsFocusSettings->focusMosaicMaskRB->setEnabled(!enable);
 
 5177    setAutoStarAndBox();
 
 5184void Focus::setUseWeights()
 
 5186    if (m_CurveFit == CurveFitting::FOCUS_QUADRATIC || !m_OpsFocusSettings->focusUseFullField->isChecked()
 
 5187            || m_StarMeasure == FOCUS_STAR_NUM_STARS || m_StarMeasure == FOCUS_STAR_FOURIER_POWER ||
 
 5188            m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
 
 5189            m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
 
 5191        m_OpsFocusProcess->focusUseWeights->setEnabled(
false);
 
 5192        m_OpsFocusProcess->focusUseWeights->setChecked(
false);
 
 5195        m_OpsFocusProcess->focusUseWeights->setEnabled(
true);
 
 5202void Focus::setDenoise()
 
 5204    if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
 
 5205            m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
 
 5206        m_OpsFocusProcess->focusDenoise->setEnabled(
true);
 
 5209        m_OpsFocusProcess->focusDenoise->setEnabled(
false);
 
 5210        m_OpsFocusProcess->focusDenoise->setChecked(
false);
 
 5219void Focus::setDonutBuster()
 
 5221    if (m_FocusAlgorithm != FOCUS_LINEAR1PASS)
 
 5223        m_OpsFocusProcess->focusDonut->hide();
 
 5224        m_OpsFocusProcess->focusDonut->setEnabled(
false);
 
 5225        m_OpsFocusProcess->focusDonut->setChecked(
false);
 
 5229        m_OpsFocusProcess->focusDonut->show();
 
 5230        if ((m_StarMeasure == FOCUS_STAR_HFR || m_StarMeasure == FOCUS_STAR_HFR_ADJ || m_StarMeasure == FOCUS_STAR_FWHM) &&
 
 5231                (m_FocusWalk == FOCUS_WALK_FIXED_STEPS || m_FocusWalk == FOCUS_WALK_CFZ_SHUFFLE) &&
 
 5232                (m_CurveFit != CurveFitting::FOCUS_QUADRATIC))
 
 5233            m_OpsFocusProcess->focusDonut->setEnabled(
true);
 
 5236            m_OpsFocusProcess->focusDonut->setEnabled(
false);
 
 5237            m_OpsFocusProcess->focusDonut->setChecked(
false);
 
 5244    focusExposure->setValue(value);
 
 
 5249    INDI_UNUSED(subBinY);
 
 5250    focusBinning->setCurrentIndex(subBinX - 1);
 
 
 5255    m_OpsFocusSettings->focusAutoStarEnabled->setChecked(enable);
 
 
 5260    m_OpsFocusSettings->focusSubFrame->setChecked(enable);
 
 
 5265    m_OpsFocusSettings->focusBoxSize->setValue(boxSize);
 
 5266    m_OpsFocusMechanics->focusTicks->setValue(stepSize);
 
 5267    m_OpsFocusMechanics->focusMaxTravel->setValue(maxTravel);
 
 5268    m_OpsFocusProcess->focusTolerance->setValue(tolerance);
 
 
 5271void Focus::checkAutoStarTimeout()
 
 5274    if (starCenter.isNull() && (inAutoFocus || minimumRequiredHFR > 0))
 
 5278            if (rememberStarCenter.isNull() == 
false)
 
 5280                focusStarSelected(rememberStarCenter.x(), rememberStarCenter.y());
 
 5281                appendLogText(
i18n(
"No star was selected. Using last known position..."));
 
 5286        initialFocuserAbsPosition = -1;
 
 5287        appendLogText(
i18n(
"No star was selected. Aborting..."));
 
 5288        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
 
 5290    else if (state() == FOCUS_WAITING)
 
 5291        setState(FOCUS_IDLE);
 
 5294void Focus::setAbsoluteFocusTicks()
 
 5296    if (absTicksSpin->value() == currentPosition)
 
 5298        appendLogText(
i18n(
"Focuser already at %1...", currentPosition));
 
 5301    focusInB->setEnabled(
false);
 
 5302    focusOutB->setEnabled(
false);
 
 5303    startGotoB->setEnabled(
false);
 
 5304    if (!changeFocus(absTicksSpin->value() - currentPosition))
 
 5305        qCDebug(KSTARS_EKOS_FOCUS) << 
"setAbsoluteFocusTicks unable to move focuser.";
 
 5308void Focus::syncTrackingBoxPosition()
 
 5310    if (m_OpsFocusSettings->focusUseFullField->isChecked() || starCenter.isNull())
 
 5313    ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 5314    Q_ASSERT(targetChip);
 
 5316    int subBinX = 1, subBinY = 1;
 
 5317    targetChip->getBinning(&subBinX, &subBinY);
 
 5319    double boxSize = m_OpsFocusSettings->focusBoxSize->value();
 
 5321    targetChip->getFrame(&x, &y, &w, &h);
 
 5323    if (boxSize / subBinX >= w || boxSize / subBinY >= h)
 
 5325        m_OpsFocusSettings->focusBoxSize->setValue((boxSize / subBinX >= w) ? w : h);
 
 5330    if (subBinX != starCenter.z())
 
 5332        if (starCenter.z() > 0)
 
 5334            starCenter.setX(starCenter.x() * (starCenter.z() / subBinX));
 
 5335            starCenter.setY(starCenter.y() * (starCenter.z() / subBinY));
 
 5338        starCenter.setZ(subBinX);
 
 5342    if (isStarMeasureStarBased())
 
 5343        starRect = 
QRect(starCenter.x() - boxSize / (2 * subBinX), starCenter.y() - boxSize / (2 * subBinY),
 
 5344                         boxSize / subBinX, boxSize / subBinY);
 
 5348        int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
 
 5349        targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
 
 5350        int boxTLX = starCenter.x() - boxSize / (2 * subBinX);
 
 5351        boxTLX = std::max(boxTLX, minX);
 
 5352        int boxTLY = starCenter.y() - boxSize / (2 * subBinY);
 
 5353        boxTLY = std::max(boxTLY, minY);
 
 5354        const int boxBRX = boxTLX + (boxSize / subBinX);
 
 5356            boxTLX -= boxBRX - maxX;
 
 5357        const int boxBRY = boxTLY + (boxSize / subBinY);
 
 5359            boxTLY -= boxBRY - maxY;
 
 5361        starRect = 
QRect(boxTLX, boxTLY, boxSize / subBinX, boxSize / subBinY);
 
 5363    m_FocusView->setTrackingBoxEnabled(
true);
 
 5364    m_FocusView->setTrackingBox(starRect);
 
 5367void Focus::showFITSViewer()
 
 5369    static int lastFVTabID = -1;
 
 5376            fv->loadData(m_ImageData, url, &lastFVTabID);
 
 5377            connect(fv.get(), &FITSViewer::terminated, 
this, [
this]()
 
 5382        else if (fv->updateData(m_ImageData, url, lastFVTabID, &lastFVTabID) == 
false)
 
 5383            fv->loadData(m_ImageData, url, &lastFVTabID);
 
 5389void Focus::adjustFocusOffset(
int value, 
bool useAbsoluteOffset)
 
 5392    if (inAdjustFocus || adaptFocus->inAdaptiveFocus())
 
 5394        QString str = inAdjustFocus ? 
i18n(
"Adjust Focus") : 
i18n(
"Adaptive Focus");
 
 5395        if (++m_StartRetries < MAXIMUM_RESTART_ITERATIONS)
 
 5397            appendLogText(
i18n(
"Adjust focus request - Waiting 10sec for %1 to complete.", str));
 
 5400                adjustFocusOffset(value, useAbsoluteOffset);
 
 5405        qCDebug(KSTARS_EKOS_FOCUS) << 
"adjustFocusOffset called whilst" << str << 
"in progress. Ignoring...";
 
 5406        emit focusPositionAdjusted();
 
 5411    inAdjustFocus = 
true;
 
 5414    int newPosition = (useAbsoluteOffset) ? value : value + currentPosition;
 
 5416    if (!changeFocus(newPosition - currentPosition))
 
 5417        qCDebug(KSTARS_EKOS_FOCUS) << 
"adjustFocusOffset unable to move focuser";
 
 5420void Focus::toggleFocusingWidgetFullScreen()
 
 5422    if (focusingWidget->parent() == 
nullptr)
 
 5424        focusingWidget->setParent(
this);
 
 5425        rightLayout->insertWidget(0, focusingWidget);
 
 5426        focusingWidget->showNormal();
 
 5430        focusingWidget->setParent(
nullptr);
 
 5431        focusingWidget->setWindowTitle(
i18nc(
"@title:window", 
"Focus Frame"));
 
 5433        focusingWidget->showMaximized();
 
 5434        focusingWidget->show();
 
 5438void Focus::setMountStatus(ISD::Mount::Status newState)
 
 5442        case ISD::Mount::MOUNT_PARKING:
 
 5443        case ISD::Mount::MOUNT_SLEWING:
 
 5444        case ISD::Mount::MOUNT_MOVING:
 
 5445            captureB->setEnabled(
false);
 
 5446            startFocusB->setEnabled(
false);
 
 5447            startAbInsB->setEnabled(
false);
 
 5448            startLoopB->setEnabled(
false);
 
 5463void Focus::setMountCoords(
const SkyPoint &position, ISD::Mount::PierSide pierSide, 
const dms &ha)
 
 5472    auto name = deviceRemoved->getDeviceName();
 
 5476    if (m_Focuser && m_Focuser->getDeviceName() == name)
 
 5478        m_Focuser->disconnect(
this);
 
 5479        m_Focuser = 
nullptr;
 
 5488    for (
auto &oneSource : m_TemperatureSources)
 
 5490        if (oneSource->getDeviceName() == name)
 
 5493            if (m_LastSourceDeviceAutofocusTemperature && m_LastSourceDeviceAutofocusTemperature->getDeviceName() == name)
 
 5494                m_LastSourceDeviceAutofocusTemperature.reset(
nullptr);
 
 5496            m_TemperatureSources.removeAll(oneSource);
 
 5499                defaultFocusTemperatureSource->removeItem(defaultFocusTemperatureSource->findText(name));
 
 5506    if (m_Camera && m_Camera->getDeviceName() == name)
 
 5508        m_Camera->disconnect(
this);
 
 5519    if (m_FilterWheel && m_FilterWheel->getDeviceName() == name)
 
 5521        m_FilterWheel->disconnect(
this);
 
 5522        m_FilterWheel = 
nullptr;
 
 
 5532void Focus::setupFilterManager()
 
 5535    if (m_FilterManager)
 
 5536        m_FilterManager->disconnect(
this);
 
 5539    Ekos::Manager::Instance()->createFilterManager(m_FilterWheel);
 
 5542    Ekos::Manager::Instance()->getFilterManager(m_FilterWheel->getDeviceName(), m_FilterManager);
 
 5547    connect(
this, &Focus::absolutePositionChanged, m_FilterManager.get(), &FilterManager::setFocusAbsolutePosition);
 
 5549    if (m_Focuser && m_Focuser->isConnected() && currentPosition >= 0)
 
 5550        m_FilterManager->setFocusAbsolutePosition(currentPosition);
 
 5553    connect(
this, &Focus::newStatus, 
this, [
this](Ekos::FocusState state, 
const QString trainname, 
const bool update)
 
 5555        Q_UNUSED(trainname);
 
 5556        if (m_FilterManager)
 
 5558            m_FilterManager->setFocusStatus(state);
 
 5559            if (update && focusFilter->currentIndex() != -1 && canAbsMove && state == Ekos::FOCUS_COMPLETE)
 
 5561                m_FilterManager->setFilterAbsoluteFocusDetails(focusFilter->currentIndex(), currentPosition,
 
 5562                        m_LastSourceAutofocusTemperature, m_LastSourceAutofocusAlt);
 
 5570    connect(m_FilterManager.get(), &FilterManager::newStatus, 
this, [
this](Ekos::FilterState filterState)
 
 5573        if (filterState == FILTER_OFFSET && state() != Ekos::FOCUS_PROGRESS)
 
 5575            if (m_GuidingSuspended == false && m_OpsFocusSettings->focusSuspendGuiding->isChecked())
 
 5577                m_GuidingSuspended = true;
 
 5578                emit suspendGuiding();
 
 5584    connect(m_FilterManager.get(), &FilterManager::ready, 
this, [
this]()
 
 5587        if (focusFilter->currentIndex() != currentFilterPosition - 1)
 
 5588            focusFilter->setCurrentIndex(currentFilterPosition - 1);
 
 5590        if (filterPositionPending)
 
 5592            filterPositionPending = false;
 
 5595        else if (fallbackFilterPending)
 
 5597            fallbackFilterPending = 
false;
 
 5598            setState(m_pendingState);
 
 5599            m_pendingState = FOCUS_IDLE;
 
 5604    connect(m_FilterManager.get(), &FilterManager::failed, 
this, [
this]()
 
 5606        if (filterPositionPending)
 
 5608            appendLogText(i18n(
"Filter operation failed."));
 
 5609            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FILTER_MANAGER);
 
 5614    connect(m_FilterManager.get(), &FilterManager::runAutoFocus, 
this, &Focus::runAutoFocus);
 
 5617    connect(m_FilterManager.get(), &FilterManager::abortAutoFocus, 
this, &Focus::abort);
 
 5620    connect(m_FilterManager.get(), &FilterManager::newFocusOffset, 
this, &Focus::adjustFocusOffset);
 
 5623    connect(m_FilterManager.get(), &FilterManager::labelsChanged, 
this, [
this]()
 
 5625        focusFilter->clear();
 
 5626        focusFilter->addItems(m_FilterManager->getFilterLabels());
 
 5627        currentFilterPosition = m_FilterManager->getFilterPosition();
 
 5628        focusFilter->setCurrentIndex(currentFilterPosition - 1);
 
 5632    connect(m_FilterManager.get(), &FilterManager::positionChanged, 
this, [
this]()
 
 5634        currentFilterPosition = m_FilterManager->getFilterPosition();
 
 5635        focusFilter->setCurrentIndex(currentFilterPosition - 1);
 
 5639    connect(m_FilterManager.get(), &FilterManager::exposureChanged, 
this, [
this]()
 
 5641        focusExposure->setValue(m_FilterManager->getFilterExposure());
 
 5645    connect(m_FilterManager.get(), &FilterManager::wavelengthChanged, 
this, [
this]()
 
 5647        wavelengthChanged();
 
 5651void Focus::connectFilterManager()
 
 5656        if (m_FilterManager)
 
 5658            m_FilterManager->refreshFilterModel();
 
 5659            m_FilterManager->show();
 
 5660            m_FilterManager->raise();
 
 5665    connect(
this, &Focus::focusPositionAdjusted, 
this, [
this]()
 
 5667        if (m_FilterManager)
 
 5668            m_FilterManager->setFocusOffsetComplete();
 
 5669        if (m_GuidingSuspended && state() != Ekos::FOCUS_PROGRESS)
 
 5671            QTimer::singleShot(m_OpsFocusMechanics->focusSettleTime->value() * 1000, 
this, [
this]()
 
 5673                m_GuidingSuspended = false;
 
 5674                emit resumeGuiding();
 
 5680    connect(
this, &Focus::focusAFOptimise, 
this, [
this]()
 
 5682        completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_OPTIMISED_OUT);
 
 5689        if (inAutoFocus && m_OpsFocusProcess->focusDonut->isEnabled())
 
 5692        if (m_FilterManager)
 
 5693            m_FilterManager->setFilterExposure(focusFilter->currentIndex(), focusExposure->value());
 
 5699        if (m_FilterManager)
 
 5701            focusExposure->setValue(m_FilterManager->getFilterExposure(text));
 
 5711    if (m_Camera == 
nullptr)
 
 5714    if (m_Camera->isBLOBEnabled() == 
false)
 
 5717        if (Options::guiderType() != Ekos::Guide::GUIDE_INTERNAL)
 
 5718            m_Camera->setBLOBEnabled(
true);
 
 5724                KSMessageBox::Instance()->disconnect(
this);
 
 5725                m_Camera->setVideoStreamEnabled(
enabled);
 
 5727            KSMessageBox::Instance()->questionYesNo(
i18n(
"Image transfer is disabled for this camera. Would you like to enable it?"));
 
 5731        m_Camera->setVideoStreamEnabled(
enabled);
 
 
 5747void Focus::setVideoStreamEnabled(
bool enabled)
 
 5751        liveVideoB->setChecked(
true);
 
 5756        liveVideoB->setChecked(
false);
 
 5761void Focus::processCaptureTimeout()
 
 5763    m_captureInProgress = 
false;
 
 5765    if (m_abortInProgress)
 
 5768        qCDebug(KSTARS_EKOS_FOCUS) << 
"Abort AF: discarding frame in " << __FUNCTION__;
 
 5772    captureTimeoutCounter++;
 
 5774    if (captureTimeoutCounter >= 3)
 
 5776        captureTimeoutCounter = 0;
 
 5777        m_MissingCameraCounter = 0;
 
 5778        captureTimeout.stop();
 
 5779        appendLogText(
i18n(
"Exposure timeout. Aborting..."));
 
 5780        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_TIMEOUT);
 
 5784        appendLogText(
i18n(
"Exposure timeout. Restarting exposure..."));
 
 5785        ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 5786        targetChip->abortExposure();
 
 5788        capture(focusExposure->value());
 
 5792    else if (m_MissingCameraCounter < 40)
 
 5794        m_MissingCameraCounter++;
 
 5795        qCDebug(KSTARS_EKOS_FOCUS) << 
"Unable to restart focus exposure as camera is missing, trying again in 5 seconds...";
 
 5800        m_MissingCameraCounter = 0;
 
 5801        captureTimeoutCounter = 0;
 
 5802        captureTimeout.stop();
 
 5803        appendLogText(
i18n(
"Exposure timeout. Aborting..."));
 
 5804        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_TIMEOUT);
 
 5809void Focus::processCaptureErrorDefault()
 
 5811    processCaptureError(ISD::Camera::ERROR_CAPTURE);
 
 5816    m_captureInProgress = 
false;
 
 5817    captureTimeout.stop();
 
 5819    if (m_abortInProgress)
 
 5821        qCDebug(KSTARS_EKOS_FOCUS) << 
"Abort AF: discarding frame in " << __FUNCTION__;
 
 5827        appendLogText(
i18n(
"Failed to save image. Aborting..."));
 
 5828        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
 
 5835        captureFailureCounter++;
 
 5837        if (captureFailureCounter >= 3)
 
 5839            captureFailureCounter = 0;
 
 5840            captureTimeoutCounter = 0;
 
 5841            m_MissingCameraCounter = 0;
 
 5842            appendLogText(
i18n(
"Exposure failure. Aborting..."));
 
 5843            completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
 
 5847        ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 5848        targetChip->abortExposure();
 
 5849        capture(focusExposure->value());
 
 5853    else if (m_MissingCameraCounter < 40)
 
 5855        m_MissingCameraCounter++;
 
 5856        qCDebug(KSTARS_EKOS_FOCUS) << 
"Unable to restart focus exposure as camera is missing, trying again in 5 seconds...";
 
 5863        m_MissingCameraCounter = 0;
 
 5864        captureFailureCounter = 0;
 
 5865        captureTimeoutCounter = 0;
 
 5866        captureTimeout.stop();
 
 5867        appendLogText(
i18n(
"Exposure failure. Aborting..."));
 
 5868        completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
 
 5872void Focus::syncSettings()
 
 5885    if ( (dsb = qobject_cast<QDoubleSpinBox*>(sender())))
 
 5888        value = dsb->
value();
 
 5891    else if ( (sb = qobject_cast<QSpinBox*>(sender())))
 
 5894        value = sb->
value();
 
 5896    else if ( (cb = qobject_cast<QCheckBox*>(sender())))
 
 5901    else if ( (gb = qobject_cast<QGroupBox*>(sender())))
 
 5906    else if ( (rb = qobject_cast<QRadioButton*>(sender())))
 
 5912            m_Settings.remove(key);
 
 5917    else if ( (cbox = qobject_cast<QComboBox*>(sender())))
 
 5922    else if ( (s = qobject_cast<QSplitter*>(sender())))
 
 5930    Options::self()->setProperty(key.
toLatin1(), value);
 
 5932    m_Settings[key] = value;
 
 5933    m_GlobalSettings[key] = value;
 
 5937    m_DebounceTimer.start();
 
 5943void Focus::settleSettings()
 
 5945    emit settingsUpdated(getAllSettings());
 
 5947    OpticalTrainSettings::Instance()->setOpticalTrainID(OpticalTrainManager::Instance()->
id(opticalTrainCombo->currentText()));
 
 5948    OpticalTrainSettings::Instance()->setOneSetting(OpticalTrainSettings::Focus, m_Settings);
 
 5951void Focus::loadGlobalSettings()
 
 5956    QVariantMap settings;
 
 5958    for (
auto &oneWidget : findChildren<QComboBox*>())
 
 5960        if (oneWidget->objectName() == 
"opticalTrainCombo")
 
 5963        key = oneWidget->objectName();
 
 5964        value = Options::self()->property(key.
toLatin1());
 
 5965        if (value.
isValid() && oneWidget->count() > 0)
 
 5967            oneWidget->setCurrentText(value.
toString());
 
 5968            settings[key] = value;
 
 5971            qCDebug(KSTARS_EKOS_FOCUS) << 
"Option" << key << 
"not found!";
 
 5975    for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
 
 5977        key = oneWidget->objectName();
 
 5978        value = Options::self()->property(key.
toLatin1());
 
 5981            oneWidget->setValue(value.
toDouble());
 
 5982            settings[key] = value;
 
 5985            qCDebug(KSTARS_EKOS_FOCUS) << 
"Option" << key << 
"not found!";
 
 5989    for (
auto &oneWidget : findChildren<QSpinBox*>())
 
 5991        key = oneWidget->objectName();
 
 5992        value = Options::self()->property(key.
toLatin1());
 
 5995            oneWidget->setValue(value.
toInt());
 
 5996            settings[key] = value;
 
 5999            qCDebug(KSTARS_EKOS_FOCUS) << 
"Option" << key << 
"not found!";
 
 6003    for (
auto &oneWidget : findChildren<QCheckBox*>())
 
 6005        key = oneWidget->objectName();
 
 6006        value = Options::self()->property(key.
toLatin1());
 
 6009            oneWidget->setChecked(value.
toBool());
 
 6010            settings[key] = value;
 
 6012        else if (key != forceInSeqAF->objectName())
 
 6013            qCDebug(KSTARS_EKOS_FOCUS) << 
"Option" << key << 
"not found!";
 
 6017    for (
auto &oneWidget : findChildren<QGroupBox*>())
 
 6019        if (oneWidget->isCheckable())
 
 6021            key = oneWidget->objectName();
 
 6022            value = Options::self()->property(key.
toLatin1());
 
 6025                oneWidget->setChecked(value.
toBool());
 
 6026                settings[key] = value;
 
 6029                qCDebug(KSTARS_EKOS_FOCUS) << 
"Option" << key << 
"not found!";
 
 6034    for (
auto &oneWidget : findChildren<QSplitter*>())
 
 6036        key = oneWidget->objectName();
 
 6037        value = Options::self()->property(key.
toLatin1());
 
 6042            oneWidget->restoreState(valueBA);
 
 6043            settings[key] = valueBA;
 
 6046            qCDebug(KSTARS_EKOS_FOCUS) << 
"Option" << key << 
"not found!";
 
 6050    for (
auto &oneWidget : findChildren<QRadioButton*>())
 
 6052        key = oneWidget->objectName();
 
 6053        value = Options::self()->property(key.
toLatin1());
 
 6056            oneWidget->setChecked(value.
toBool());
 
 6057            settings[key] = value;
 
 6062    m_GlobalSettings = m_Settings = settings;
 
 6065void Focus::checkMosaicMaskLimits()
 
 6067    if (m_Camera == 
nullptr || m_Camera->isConnected() == 
false)
 
 6069    auto targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
 
 6070    if (targetChip == 
nullptr || frameSettings.contains(targetChip) == 
false)
 
 6072    auto settings = frameSettings[targetChip];
 
 6075    auto width = settings[
"w"].toInt();
 
 6076    auto height = settings[
"h"].toInt();
 
 6077    if (width == 0 || height == 0)
 
 6081    auto min = std::min(width, height);
 
 6083    m_OpsFocusSettings->focusMosaicTileWidth->setMaximum(100 * min / (3 * width));
 
 6086void Focus::connectSyncSettings()
 
 6089    for (
auto &oneWidget : findChildren<QComboBox*>())
 
 6091        if (oneWidget != opticalTrainCombo)
 
 6095    for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
 
 6099    for (
auto &oneWidget : findChildren<QSpinBox*>())
 
 6103    for (
auto &oneWidget : findChildren<QCheckBox*>())
 
 6107    for (
auto &oneWidget : findChildren<QGroupBox*>())
 
 6108        if (oneWidget->isCheckable())
 
 6112    for (
auto &oneWidget : findChildren<QSplitter*>())
 
 6116    for (
auto &oneWidget : findChildren<QRadioButton*>())
 
 6120void Focus::disconnectSyncSettings()
 
 6123    for (
auto &oneWidget : findChildren<QComboBox*>())
 
 6124        disconnect(oneWidget, QOverload<int>::of(&
QComboBox::activated), 
this, &Ekos::Focus::syncSettings);
 
 6127    for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
 
 6131    for (
auto &oneWidget : findChildren<QSpinBox*>())
 
 6135    for (
auto &oneWidget : findChildren<QCheckBox*>())
 
 6139    for (
auto &oneWidget : findChildren<QGroupBox*>())
 
 6140        if (oneWidget->isCheckable())
 
 6144    for (
auto &oneWidget : findChildren<QSplitter*>())
 
 6148    for (
auto &oneWidget : findChildren<QRadioButton*>())
 
 6152void Focus::initPlots()
 
 6156    profileDialog = 
new QDialog(
this);
 
 6159    profileDialog->setWindowTitle(
i18nc(
"@title:window", 
"Relative Profile"));
 
 6160    profilePlot = 
new FocusProfilePlot(profileDialog);
 
 6163    profileDialog->setLayout(profileLayout);
 
 6164    profileDialog->resize(400, 300);
 
 6167    connect(
this, &Ekos::Focus::newHFR, [
this](
double currentHFR, 
int pos)
 
 6169        Q_UNUSED(pos) profilePlot->drawProfilePlot(currentHFR);
 
 6173void Focus::initConnections()
 
 6176    waitStarSelectTimer.setInterval(AUTO_STAR_TIMEOUT);
 
 6181    m_DebounceTimer.setInterval(500);
 
 6182    m_DebounceTimer.setSingleShot(
true);
 
 6197    captureTimer.setSingleShot(
true);
 
 6204    captureTimeout.setSingleShot(
true);
 
 6239            &Ekos::Focus::updateBoxSize);
 
 6245        m_CFZDialog->show();
 
 6246        m_CFZDialog->raise();
 
 6252            focusAdvisor->setButtons(
false);
 
 6253            focusAdvisor->show();
 
 6254            focusAdvisor->raise();
 
 6260        emit inSequenceAF(enabled, opticalTrain());
 
 6266        setFocusDetection(static_cast<StarAlgorithm>(index));
 
 6272        setFocusAlgorithm(static_cast<Algorithm>(index));
 
 6278            this, [&](
int index)
 
 6280        setCurveFit(static_cast<CurveFitting::CurveFit>(index));
 
 6285            this, [&](
int index)
 
 6287        setStarMeasure(static_cast<StarMeasure>(index));
 
 6292            this, [&](
int index)
 
 6294        setStarPSF(static_cast<StarPSF>(index));
 
 6299            this, [&](
int index)
 
 6301        setStarUnits(static_cast<StarUnits>(index));
 
 6306            this, [&](
int index)
 
 6308        setWalk(static_cast<FocusWalk>(index));
 
 6319            starCenter   = QVector3D();
 
 6320            starSelected = false;
 
 6321            m_FocusView->setTrackingBox(QRect());
 
 6329            &Ekos::Focus::calcCFZ);
 
 6332            &Ekos::Focus::calcCFZ);
 
 6373void Focus::setFocusDetection(StarAlgorithm starAlgorithm)
 
 6375    static bool first = 
true;
 
 6376    if (!first && m_FocusDetection == starAlgorithm)
 
 6381    m_FocusDetection = starAlgorithm;
 
 6384    setFocusAlgorithm(m_FocusAlgorithm);
 
 6385    setAutoStarAndBox();
 
 6393void Focus::setAutoStarAndBox()
 
 6395    if (m_FocusDetection == ALGORITHM_BAHTINOV)
 
 6397        m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
false);
 
 6398        m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
 
 6399        m_OpsFocusSettings->focusBoxSize->setEnabled(m_OpsFocusSettings->focusSubFrame->isChecked());
 
 6400        m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(m_OpsFocusSettings->focusSubFrame->isChecked());
 
 6401        m_OpsFocusSettings->focusBoxSize->setMaximum(512);
 
 6402        if (m_OpsFocusSettings->focusBoxSize->value() > 512)
 
 6403            m_OpsFocusSettings->focusBoxSize->setValue(m_OpsFocusSettings->focusBoxSize->value());
 
 6405    else if(m_OpsFocusSettings->focusSubFrame->isChecked())
 
 6407        if(isStarMeasureStarBased())
 
 6409            m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
true);
 
 6411            m_OpsFocusSettings->focusBoxSize->setEnabled(
true);
 
 6412            m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(
true);
 
 6413            if (m_OpsFocusSettings->focusBoxSize->value() > 256)
 
 6414                m_OpsFocusSettings->focusBoxSize->setValue(m_OpsFocusSettings->focusBoxSize->value());
 
 6415            m_OpsFocusSettings->focusBoxSize->setMaximum(256);
 
 6419            m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
false);
 
 6420            m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
 
 6423            m_OpsFocusSettings->focusBoxSize->setEnabled(
true);
 
 6424            m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(
true);
 
 6425            int maxSize = std::min(m_CcdWidth, m_CcdHeight);
 
 6426            int step = m_OpsFocusSettings->focusBoxSize->singleStep();
 
 6427            maxSize = std::max(256, (maxSize / step) * step);
 
 6428            m_OpsFocusSettings->focusBoxSize->setMaximum(maxSize);
 
 6434        m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
false);
 
 6435        m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
 
 6436        m_OpsFocusSettings->focusBoxSize->setEnabled(
false);
 
 6437        m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(
false);
 
 6442void Focus::setFocusAlgorithm(Algorithm algorithm)
 
 6444    m_FocusAlgorithm = algorithm;
 
 6447        case FOCUS_ITERATIVE:
 
 6449            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
 
 6450            m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
 
 6451            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
 
 6452            m_OpsFocusProcess->focusMultiRowAverage->hide();
 
 6454            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
 
 6455            m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
 
 6456            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
 
 6457            m_OpsFocusProcess->focusGaussianSigma->hide();
 
 6459            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
 
 6460            m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
 
 6461            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
 
 6462            m_OpsFocusProcess->focusGaussianKernelSize->hide();
 
 6464            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarMeasureLabel);
 
 6465            m_OpsFocusProcess->focusStarMeasureLabel->hide();
 
 6466            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarMeasure);
 
 6467            m_OpsFocusProcess->focusStarMeasure->hide();
 
 6469            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
 
 6470            m_OpsFocusProcess->focusStarPSFLabel->hide();
 
 6471            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
 
 6472            m_OpsFocusProcess->focusStarPSF->hide();
 
 6474            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
 
 6475            m_OpsFocusProcess->focusUseWeights->hide();
 
 6477            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2LimitLabel);
 
 6478            m_OpsFocusProcess->focusR2LimitLabel->hide();
 
 6479            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2Limit);
 
 6480            m_OpsFocusProcess->focusR2Limit->hide();
 
 6482            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusRefineCurveFit);
 
 6483            m_OpsFocusProcess->focusRefineCurveFit->hide();
 
 6484            m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
 
 6486            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
 
 6487            m_OpsFocusProcess->focusToleranceLabel->hide();
 
 6488            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusTolerance);
 
 6489            m_OpsFocusProcess->focusTolerance->hide();
 
 6491            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
 
 6492            m_OpsFocusProcess->focusThresholdLabel->hide();
 
 6493            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
 
 6494            m_OpsFocusProcess->focusThreshold->hide();
 
 6496            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusCurveFitLabel);
 
 6497            m_OpsFocusProcess->focusCurveFitLabel->hide();
 
 6498            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusCurveFit);
 
 6499            m_OpsFocusProcess->focusCurveFit->hide();
 
 6501            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
 
 6502            m_OpsFocusProcess->focusDenoise->hide();
 
 6505            m_OpsFocusProcess->focusDonut->hide();
 
 6506            m_OpsFocusProcess->focusDonut->setChecked(
false);
 
 6509            m_OpsFocusProcess->focusScanStartPos->hide();
 
 6510            m_OpsFocusProcess->focusScanStartPos->setChecked(
false);
 
 6513            m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_QUADRATIC);
 
 6516            if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
 
 6518                m_OpsFocusProcess->focusStarMeasure->clear();
 
 6519                m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
 
 6520                m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
 
 6524            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusToleranceLabel, 3, 0);
 
 6525            m_OpsFocusProcess->focusToleranceLabel->show();
 
 6526            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusTolerance, 3, 1);
 
 6527            m_OpsFocusProcess->focusTolerance->show();
 
 6529            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 3, 2);
 
 6530            m_OpsFocusProcess->focusFramesCountLabel->show();
 
 6531            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 3, 3);
 
 6532            m_OpsFocusProcess->focusFramesCount->show();
 
 6534            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 4, 2);
 
 6535            m_OpsFocusProcess->focusHFRFramesCountLabel->show();
 
 6536            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 4, 3);
 
 6537            m_OpsFocusProcess->focusHFRFramesCount->show();
 
 6539            if (m_FocusDetection == ALGORITHM_THRESHOLD)
 
 6541                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 5, 0);
 
 6542                m_OpsFocusProcess->focusThresholdLabel->show();
 
 6543                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 5, 1);
 
 6544                m_OpsFocusProcess->focusThreshold->show();
 
 6546            else if (m_FocusDetection == ALGORITHM_BAHTINOV)
 
 6548                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 5, 0);
 
 6549                m_OpsFocusProcess->focusMultiRowAverageLabel->show();
 
 6550                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 5, 1);
 
 6551                m_OpsFocusProcess->focusMultiRowAverage->show();
 
 6553                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 5, 2);
 
 6554                m_OpsFocusProcess->focusGaussianSigmaLabel->show();
 
 6555                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 5, 3);
 
 6556                m_OpsFocusProcess->focusGaussianSigma->show();
 
 6558                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 6, 0);
 
 6559                m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
 
 6560                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 6, 1);
 
 6561                m_OpsFocusProcess->focusGaussianKernelSize->show();
 
 6565            startAbInsB->setEnabled(canAbInsStart());
 
 6569            m_OpsFocusSettings->focusAdaptive->setChecked(
false);
 
 6570            m_OpsFocusSettings->focusAdaptStart->setChecked(
false);
 
 6571            m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(
false);
 
 6573            m_OpsFocusSettings->focusAFOptimize->setValue(0);
 
 6574            m_OpsFocusSettings->focusAFOptimize->setEnabled(
false);
 
 6577            m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
true);
 
 6578            m_OpsFocusMechanics->focusOutSteps->setEnabled(
false);
 
 6581            if (m_OpsFocusMechanics->focusWalk->count() != 1)
 
 6583                m_OpsFocusMechanics->focusWalk->clear();
 
 6584                m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
 
 6585                m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
 
 6589        case FOCUS_POLYNOMIAL:
 
 6591            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
 
 6592            m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
 
 6593            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
 
 6594            m_OpsFocusProcess->focusMultiRowAverage->hide();
 
 6596            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
 
 6597            m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
 
 6598            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
 
 6599            m_OpsFocusProcess->focusGaussianSigma->hide();
 
 6601            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
 
 6602            m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
 
 6603            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
 
 6604            m_OpsFocusProcess->focusGaussianKernelSize->hide();
 
 6606            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
 
 6607            m_OpsFocusProcess->focusStarPSFLabel->hide();
 
 6608            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
 
 6609            m_OpsFocusProcess->focusStarPSF->hide();
 
 6611            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
 
 6612            m_OpsFocusProcess->focusUseWeights->hide();
 
 6614            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2LimitLabel);
 
 6615            m_OpsFocusProcess->focusR2LimitLabel->hide();
 
 6616            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2Limit);
 
 6617            m_OpsFocusProcess->focusR2Limit->hide();
 
 6619            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusRefineCurveFit);
 
 6620            m_OpsFocusProcess->focusRefineCurveFit->hide();
 
 6621            m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
 
 6623            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
 
 6624            m_OpsFocusProcess->focusToleranceLabel->hide();
 
 6625            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusTolerance);
 
 6626            m_OpsFocusProcess->focusTolerance->hide();
 
 6628            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
 
 6629            m_OpsFocusProcess->focusThresholdLabel->hide();
 
 6630            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
 
 6631            m_OpsFocusProcess->focusThreshold->hide();
 
 6633            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
 
 6634            m_OpsFocusProcess->focusDenoise->hide();
 
 6637            m_OpsFocusProcess->focusDonut->hide();
 
 6638            m_OpsFocusProcess->focusDonut->setChecked(
false);
 
 6641            m_OpsFocusProcess->focusScanStartPos->hide();
 
 6642            m_OpsFocusProcess->focusScanStartPos->setChecked(
false);
 
 6645            if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
 
 6647                m_OpsFocusProcess->focusStarMeasure->clear();
 
 6648                m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
 
 6649                m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
 
 6654            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFitLabel, 1, 2);
 
 6655            m_OpsFocusProcess->focusCurveFitLabel->show();
 
 6656            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFit, 1, 3);
 
 6657            m_OpsFocusProcess->focusCurveFit->show();
 
 6658            if (m_OpsFocusProcess->focusCurveFit->count() != 1)
 
 6660                m_OpsFocusProcess->focusCurveFit->clear();
 
 6661                m_OpsFocusProcess->focusCurveFit->addItem(m_CurveFitText.at(CurveFitting::FOCUS_QUADRATIC));
 
 6662                m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_QUADRATIC);
 
 6665            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusToleranceLabel, 3, 0);
 
 6666            m_OpsFocusProcess->focusToleranceLabel->show();
 
 6667            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusTolerance, 3, 1);
 
 6668            m_OpsFocusProcess->focusTolerance->show();
 
 6670            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 3, 2);
 
 6671            m_OpsFocusProcess->focusFramesCountLabel->show();
 
 6672            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 3, 3);
 
 6673            m_OpsFocusProcess->focusFramesCount->show();
 
 6675            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 4, 2);
 
 6676            m_OpsFocusProcess->focusHFRFramesCountLabel->show();
 
 6677            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 4, 3);
 
 6678            m_OpsFocusProcess->focusHFRFramesCount->show();
 
 6680            if (m_FocusDetection == ALGORITHM_THRESHOLD)
 
 6682                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 5, 0);
 
 6683                m_OpsFocusProcess->focusThresholdLabel->show();
 
 6684                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 5, 1);
 
 6685                m_OpsFocusProcess->focusThreshold->show();
 
 6687            else if (m_FocusDetection == ALGORITHM_BAHTINOV)
 
 6689                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 5, 0);
 
 6690                m_OpsFocusProcess->focusMultiRowAverageLabel->show();
 
 6691                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 5, 1);
 
 6692                m_OpsFocusProcess->focusMultiRowAverage->show();
 
 6694                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 5, 2);
 
 6695                m_OpsFocusProcess->focusGaussianSigmaLabel->show();
 
 6696                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 5, 3);
 
 6697                m_OpsFocusProcess->focusGaussianSigma->show();
 
 6699                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 6, 0);
 
 6700                m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
 
 6701                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 6, 1);
 
 6702                m_OpsFocusProcess->focusGaussianKernelSize->show();
 
 6706            startAbInsB->setEnabled(canAbInsStart());
 
 6710            m_OpsFocusSettings->focusAdaptive->setChecked(
false);
 
 6711            m_OpsFocusSettings->focusAdaptStart->setChecked(
false);
 
 6712            m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(
false);
 
 6714            m_OpsFocusSettings->focusAFOptimize->setValue(0);
 
 6715            m_OpsFocusSettings->focusAFOptimize->setEnabled(
false);
 
 6718            m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
true);
 
 6719            m_OpsFocusMechanics->focusOutSteps->setEnabled(
false);
 
 6722            if (m_OpsFocusMechanics->focusWalk->count() != 1)
 
 6724                m_OpsFocusMechanics->focusWalk->clear();
 
 6725                m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
 
 6726                m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
 
 6732            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
 
 6733            m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
 
 6734            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
 
 6735            m_OpsFocusProcess->focusMultiRowAverage->hide();
 
 6737            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
 
 6738            m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
 
 6739            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
 
 6740            m_OpsFocusProcess->focusGaussianSigma->hide();
 
 6742            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
 
 6743            m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
 
 6744            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
 
 6745            m_OpsFocusProcess->focusGaussianKernelSize->hide();
 
 6747            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
 
 6748            m_OpsFocusProcess->focusThresholdLabel->hide();
 
 6749            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
 
 6750            m_OpsFocusProcess->focusThreshold->hide();
 
 6752            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
 
 6753            m_OpsFocusProcess->focusStarPSFLabel->hide();
 
 6754            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
 
 6755            m_OpsFocusProcess->focusStarPSF->hide();
 
 6757            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
 
 6758            m_OpsFocusProcess->focusUseWeights->hide();
 
 6760            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2LimitLabel);
 
 6761            m_OpsFocusProcess->focusR2LimitLabel->hide();
 
 6762            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2Limit);
 
 6763            m_OpsFocusProcess->focusR2Limit->hide();
 
 6765            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusRefineCurveFit);
 
 6766            m_OpsFocusProcess->focusRefineCurveFit->hide();
 
 6767            m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
 
 6769            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
 
 6770            m_OpsFocusProcess->focusDenoise->hide();
 
 6773            m_OpsFocusProcess->focusDonut->hide();
 
 6774            m_OpsFocusProcess->focusDonut->setChecked(
false);
 
 6777            m_OpsFocusProcess->focusScanStartPos->hide();
 
 6778            m_OpsFocusProcess->focusScanStartPos->setChecked(
false);
 
 6781            if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
 
 6783                m_OpsFocusProcess->focusStarMeasure->clear();
 
 6784                m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
 
 6785                m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
 
 6790            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFitLabel, 1, 2);
 
 6791            m_OpsFocusProcess->focusCurveFitLabel->show();
 
 6792            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFit, 1, 3);
 
 6793            m_OpsFocusProcess->focusCurveFit->show();
 
 6794            if (m_OpsFocusProcess->focusCurveFit->count() != 1)
 
 6796                m_OpsFocusProcess->focusCurveFit->clear();
 
 6797                m_OpsFocusProcess->focusCurveFit->addItem(m_CurveFitText.at(CurveFitting::FOCUS_QUADRATIC));
 
 6798                m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_QUADRATIC);
 
 6801            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusToleranceLabel, 3, 0);
 
 6802            m_OpsFocusProcess->focusToleranceLabel->show();
 
 6803            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusTolerance, 3, 1);
 
 6804            m_OpsFocusProcess->focusTolerance->show();
 
 6806            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 3, 2);
 
 6807            m_OpsFocusProcess->focusFramesCountLabel->show();
 
 6808            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 3, 3);
 
 6809            m_OpsFocusProcess->focusFramesCount->show();
 
 6811            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 4, 2);
 
 6812            m_OpsFocusProcess->focusHFRFramesCountLabel->show();
 
 6813            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 4, 3);
 
 6814            m_OpsFocusProcess->focusHFRFramesCount->show();
 
 6816            if (m_FocusDetection == ALGORITHM_THRESHOLD)
 
 6818                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 5, 0);
 
 6819                m_OpsFocusProcess->focusThresholdLabel->show();
 
 6820                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 5, 1);
 
 6821                m_OpsFocusProcess->focusThreshold->show();
 
 6823            else if (m_FocusDetection == ALGORITHM_BAHTINOV)
 
 6825                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 5, 0);
 
 6826                m_OpsFocusProcess->focusMultiRowAverageLabel->show();
 
 6827                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 5, 1);
 
 6828                m_OpsFocusProcess->focusMultiRowAverage->show();
 
 6830                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 5, 2);
 
 6831                m_OpsFocusProcess->focusGaussianSigmaLabel->show();
 
 6832                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 5, 3);
 
 6833                m_OpsFocusProcess->focusGaussianSigma->show();
 
 6835                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 6, 0);
 
 6836                m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
 
 6837                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 6, 1);
 
 6838                m_OpsFocusProcess->focusGaussianKernelSize->show();
 
 6842            startAbInsB->setEnabled(canAbInsStart());
 
 6846            m_OpsFocusSettings->focusAdaptive->setChecked(
false);
 
 6847            m_OpsFocusSettings->focusAdaptStart->setChecked(
false);
 
 6848            m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(
false);
 
 6850            if (m_FilterManager)
 
 6851                m_OpsFocusSettings->focusAFOptimize->setEnabled(
true);
 
 6854                m_OpsFocusSettings->focusAFOptimize->setValue(0);
 
 6855                m_OpsFocusSettings->focusAFOptimize->setEnabled(
false);
 
 6859            m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
false);
 
 6860            m_OpsFocusMechanics->focusOutSteps->setEnabled(
true);
 
 6863            if (m_OpsFocusMechanics->focusWalk->count() != 1)
 
 6865                m_OpsFocusMechanics->focusWalk->clear();
 
 6866                m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
 
 6867                m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
 
 6871        case FOCUS_LINEAR1PASS:
 
 6873            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
 
 6874            m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
 
 6875            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
 
 6876            m_OpsFocusProcess->focusMultiRowAverage->hide();
 
 6878            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
 
 6879            m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
 
 6880            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
 
 6881            m_OpsFocusProcess->focusGaussianSigma->hide();
 
 6883            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
 
 6884            m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
 
 6885            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
 
 6886            m_OpsFocusProcess->focusGaussianKernelSize->hide();
 
 6888            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
 
 6889            m_OpsFocusProcess->focusThresholdLabel->hide();
 
 6890            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
 
 6891            m_OpsFocusProcess->focusThreshold->hide();
 
 6893            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
 
 6894            m_OpsFocusProcess->focusToleranceLabel->hide();
 
 6895            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusTolerance);
 
 6896            m_OpsFocusProcess->focusTolerance->hide();
 
 6900            if (m_FocusDetection == ALGORITHM_SEP && m_CurveFit != CurveFitting::FOCUS_QUADRATIC)
 
 6902                if (m_OpsFocusProcess->focusStarMeasure->count() != m_StarMeasureText.count())
 
 6904                    m_OpsFocusProcess->focusStarMeasure->clear();
 
 6905                    m_OpsFocusProcess->focusStarMeasure->addItems(m_StarMeasureText);
 
 6906                    m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
 
 6910#if !defined(HAVE_OPENCV) 
 6918            else if (m_FocusDetection != ALGORITHM_SEP || m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
 
 6920                if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
 
 6922                    m_OpsFocusProcess->focusStarMeasure->clear();
 
 6923                    m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
 
 6924                    m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
 
 6930            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFitLabel, 1, 2);
 
 6931            m_OpsFocusProcess->focusCurveFitLabel->show();
 
 6932            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFit, 1, 3);
 
 6933            m_OpsFocusProcess->focusCurveFit->show();
 
 6934            if (m_OpsFocusProcess->focusCurveFit->count() != m_CurveFitText.count())
 
 6936                m_OpsFocusProcess->focusCurveFit->clear();
 
 6937                m_OpsFocusProcess->focusCurveFit->addItems(m_CurveFitText);
 
 6938                m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_HYPERBOLA);
 
 6941            if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
 
 6942                    m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
 
 6944                m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
 
 6945                m_OpsFocusProcess->focusUseWeights->hide();
 
 6946                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusDenoise, 3, 0, 1, 2); 
 
 6947                m_OpsFocusProcess->focusDenoise->show();
 
 6951                m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
 
 6952                m_OpsFocusProcess->focusDenoise->hide();
 
 6953                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusUseWeights, 3, 0, 1, 2); 
 
 6954                m_OpsFocusProcess->focusUseWeights->show();
 
 6957            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusR2LimitLabel, 3, 2);
 
 6958            m_OpsFocusProcess->focusR2LimitLabel->show();
 
 6959            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusR2Limit, 3, 3);
 
 6960            m_OpsFocusProcess->focusR2Limit->show();
 
 6962            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusRefineCurveFit, 4, 0, 1, 2); 
 
 6963            m_OpsFocusProcess->focusRefineCurveFit->show();
 
 6965            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 4, 2);
 
 6966            m_OpsFocusProcess->focusFramesCountLabel->show();
 
 6967            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 4, 3);
 
 6968            m_OpsFocusProcess->focusFramesCount->show();
 
 6970            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 5, 2);
 
 6971            m_OpsFocusProcess->focusHFRFramesCountLabel->show();
 
 6972            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 5, 3);
 
 6973            m_OpsFocusProcess->focusHFRFramesCount->show();
 
 6975            if (m_FocusDetection == ALGORITHM_THRESHOLD)
 
 6977                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 6, 0);
 
 6978                m_OpsFocusProcess->focusThresholdLabel->show();
 
 6979                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 6, 1);
 
 6980                m_OpsFocusProcess->focusThreshold->show();
 
 6982            else if (m_FocusDetection == ALGORITHM_BAHTINOV)
 
 6984                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 6, 0);
 
 6985                m_OpsFocusProcess->focusMultiRowAverageLabel->show();
 
 6986                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 6, 1);
 
 6987                m_OpsFocusProcess->focusMultiRowAverage->show();
 
 6989                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 6, 2);
 
 6990                m_OpsFocusProcess->focusGaussianSigmaLabel->show();
 
 6991                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 6, 3);
 
 6992                m_OpsFocusProcess->focusGaussianSigma->show();
 
 6994                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 7, 0);
 
 6995                m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
 
 6996                m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 7, 1);
 
 6997                m_OpsFocusProcess->focusGaussianKernelSize->show();
 
 7001            m_OpsFocusProcess->focusDonut->show();
 
 7002            m_OpsFocusProcess->focusDonut->setEnabled(
true);
 
 7005            m_OpsFocusProcess->focusScanStartPos->show();
 
 7006            m_OpsFocusProcess->focusScanStartPos->setEnabled(
true);
 
 7009            startAbInsB->setEnabled(canAbInsStart());
 
 7013            m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(canAbsMove);
 
 7015            if (m_FilterManager)
 
 7016                m_OpsFocusSettings->focusAFOptimize->setEnabled(
true);
 
 7019                m_OpsFocusSettings->focusAFOptimize->setValue(0);
 
 7020                m_OpsFocusSettings->focusAFOptimize->setEnabled(
false);
 
 7025            m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
false);
 
 7026            m_OpsFocusMechanics->focusOutSteps->setEnabled(
true);
 
 7029            if (m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
 
 7031                if (m_OpsFocusMechanics->focusWalk->count() != 1)
 
 7033                    m_OpsFocusMechanics->focusWalk->clear();
 
 7034                    m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
 
 7035                    m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
 
 7040                if (m_OpsFocusMechanics->focusWalk->count() != m_FocusWalkText.count())
 
 7042                    m_OpsFocusMechanics->focusWalk->clear();
 
 7043                    m_OpsFocusMechanics->focusWalk->addItems(m_FocusWalkText);
 
 7044                    m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
 
 7051void Focus::setCurveFit(CurveFitting::CurveFit curve)
 
 7053    if (m_OpsFocusProcess->focusCurveFit->currentIndex() == -1)
 
 7056    static bool first = 
true;
 
 7057    if (!first && m_CurveFit == curve)
 
 7063    setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
 
 7070        case CurveFitting::FOCUS_QUADRATIC:
 
 7071            m_OpsFocusProcess->focusR2Limit->setEnabled(
false);
 
 7072            m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
 
 7073            m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
false);
 
 7076        case CurveFitting::FOCUS_HYPERBOLA:
 
 7077            m_OpsFocusProcess->focusR2Limit->setEnabled(
true);      
 
 7078            m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
true);
 
 7081        case CurveFitting::FOCUS_PARABOLA:
 
 7082            m_OpsFocusProcess->focusR2Limit->setEnabled(
true);      
 
 7083            m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
true);
 
 7086        case CurveFitting::FOCUS_2DGAUSSIAN:
 
 7087            m_OpsFocusProcess->focusR2Limit->setEnabled(
true);      
 
 7088            m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
true);
 
 7096void Focus::setStarMeasure(StarMeasure starMeasure)
 
 7098    if (m_OpsFocusProcess->focusStarMeasure->currentIndex() == -1)
 
 7101    static bool first = 
true;
 
 7102    if (!first && m_StarMeasure == starMeasure)
 
 7107    m_StarMeasure = starMeasure;
 
 7108    setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
 
 7112    setAutoStarAndBox();
 
 7118    switch(m_StarMeasure)
 
 7120        case FOCUS_STAR_HFR:
 
 7121            m_OptDir = CurveFitting::OPTIMISATION_MINIMISE;
 
 7122            m_FocusView->setStarsHFREnabled(
true);
 
 7125            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
 
 7126            m_OpsFocusProcess->focusStarPSFLabel->hide();
 
 7127            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
 
 7128            m_OpsFocusProcess->focusStarPSF->hide();
 
 7131        case FOCUS_STAR_HFR_ADJ:
 
 7132            m_OptDir = CurveFitting::OPTIMISATION_MINIMISE;
 
 7133            m_FocusView->setStarsHFREnabled(
false);
 
 7136            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
 
 7137            m_OpsFocusProcess->focusStarPSFLabel->hide();
 
 7138            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
 
 7139            m_OpsFocusProcess->focusStarPSF->hide();
 
 7142        case FOCUS_STAR_FWHM:
 
 7143            m_OptDir = CurveFitting::OPTIMISATION_MINIMISE;
 
 7145            m_FocusView->setStarsHFREnabled(
false);
 
 7148            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusStarPSFLabel, 2, 2);
 
 7149            m_OpsFocusProcess->focusStarPSFLabel->show();
 
 7150            m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusStarPSF, 2, 3);
 
 7151            m_OpsFocusProcess->focusStarPSF->show();
 
 7154        case FOCUS_STAR_NUM_STARS:
 
 7155            m_OptDir = CurveFitting::OPTIMISATION_MAXIMISE;
 
 7156            m_FocusView->setStarsHFREnabled(
true);
 
 7159            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
 
 7160            m_OpsFocusProcess->focusStarPSFLabel->hide();
 
 7161            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
 
 7162            m_OpsFocusProcess->focusStarPSF->hide();
 
 7165        case FOCUS_STAR_FOURIER_POWER:
 
 7166            m_OptDir = CurveFitting::OPTIMISATION_MAXIMISE;
 
 7167            m_FocusView->setStarsHFREnabled(
true);
 
 7170            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
 
 7171            m_OpsFocusProcess->focusStarPSFLabel->hide();
 
 7172            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
 
 7173            m_OpsFocusProcess->focusStarPSF->hide();
 
 7176        case FOCUS_STAR_STDDEV:
 
 7177        case FOCUS_STAR_SOBEL:
 
 7178        case FOCUS_STAR_LAPLASSIAN:
 
 7179        case FOCUS_STAR_CANNY:
 
 7180            m_OptDir = CurveFitting::OPTIMISATION_MAXIMISE;
 
 7181            m_FocusView->setStarsHFREnabled(
true);
 
 7184            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
 
 7185            m_OpsFocusProcess->focusStarPSFLabel->hide();
 
 7186            m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
 
 7187            m_OpsFocusProcess->focusStarPSF->hide();
 
 7195void Focus::setStarPSF(StarPSF starPSF)
 
 7197    m_StarPSF = starPSF;
 
 7200void Focus::setStarUnits(StarUnits starUnits)
 
 7202    m_StarUnits = starUnits;
 
 7205void Focus::setWalk(FocusWalk walk)
 
 7207    if (m_OpsFocusMechanics->focusWalk->currentIndex() == -1)
 
 7210    static bool first = 
true;
 
 7211    if (!first && m_FocusWalk == walk)
 
 7220        case FOCUS_WALK_CLASSIC:
 
 7221            m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusNumStepsLabel,
 
 7222                    m_OpsFocusMechanics->focusOutStepsLabel);
 
 7223            m_OpsFocusMechanics->focusNumStepsLabel->hide();
 
 7224            m_OpsFocusMechanics->focusOutStepsLabel->show();
 
 7225            m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusNumSteps,
 
 7226                    m_OpsFocusMechanics->focusOutSteps);
 
 7227            m_OpsFocusMechanics->focusNumSteps->hide();
 
 7228            m_OpsFocusMechanics->focusOutSteps->show();
 
 7231        case FOCUS_WALK_FIXED_STEPS:
 
 7232        case FOCUS_WALK_CFZ_SHUFFLE:
 
 7233            m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutStepsLabel,
 
 7234                    m_OpsFocusMechanics->focusNumStepsLabel);
 
 7235            m_OpsFocusMechanics->focusOutStepsLabel->hide();
 
 7236            m_OpsFocusMechanics->focusNumStepsLabel->show();
 
 7237            m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutSteps,
 
 7238                    m_OpsFocusMechanics->focusNumSteps);
 
 7239            m_OpsFocusMechanics->focusOutSteps->hide();
 
 7240            m_OpsFocusMechanics->focusNumSteps->show();
 
 7249double Focus::getStarUnits(
const StarMeasure starMeasure, 
const StarUnits starUnits)
 
 7251    if (starUnits == FOCUS_UNITS_PIXEL || starMeasure == FOCUS_STAR_NUM_STARS || starMeasure == FOCUS_STAR_FOURIER_POWER
 
 7252            || starMeasure == FOCUS_STAR_STDDEV || starMeasure == FOCUS_STAR_SOBEL || starMeasure == FOCUS_STAR_LAPLASSIAN
 
 7253            || starMeasure == FOCUS_STAR_CANNY)
 
 7255    if (m_CcdPixelSizeX <= 0.0 || m_FocalLength <= 0.0)
 
 7259    return m_CcdPixelSizeX / m_FocalLength * 206.265;
 
 7262void Focus::calcCFZ()
 
 7264    double cfzMicrons, cfzSteps;
 
 7265    double cfzCameraSteps = calcCameraCFZ() / m_CFZUI->focusCFZStepSize->value();
 
 7267    switch(
static_cast<Focus::CFZAlgorithm
> (m_CFZUI->focusCFZAlgorithm->currentIndex()))
 
 7269        case Focus::FOCUS_CFZ_CLASSIC:
 
 7271            cfzMicrons = 4.88f * m_CFZUI->focusCFZTolerance->value() * m_CFZUI->focusCFZWavelength->value() / 1000.0f *
 
 7272                         pow(m_CFZUI->focusCFZFNumber->value(), 2.0f);
 
 7273            cfzSteps = cfzMicrons / m_CFZUI->focusCFZStepSize->value();
 
 7274            m_cfzSteps = std::round(std::max(cfzSteps, cfzCameraSteps));
 
 7275            m_CFZUI->focusCFZFormula->setText(
"CFZ = 4.88 t λ f²");
 
 7276            m_CFZUI->focusCFZ->setText(
QString(
"%1 μm").arg(cfzMicrons, 0, 
'f', 0));
 
 7277            m_CFZUI->focusCFZSteps->setText(
QString(
"%1 steps").arg(cfzSteps, 0, 
'f', 0));
 
 7278            m_CFZUI->focusCFZCameraSteps->setText(
QString(
"%1 steps").arg(cfzCameraSteps, 0, 
'f', 0));
 
 7279            m_CFZUI->focusCFZFinal->setText(
QString(
"%1 steps").arg(m_cfzSteps, 0, 
'f', 0));
 
 7282            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTauLabel);
 
 7283            m_CFZUI->focusCFZTauLabel->hide();
 
 7284            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTau);
 
 7285            m_CFZUI->focusCFZTau->hide();
 
 7286            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeingLabel);
 
 7287            m_CFZUI->focusCFZSeeingLabel->hide();
 
 7288            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeing);
 
 7289            m_CFZUI->focusCFZSeeing->hide();
 
 7292            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZToleranceLabel, 1, 0);
 
 7293            m_CFZUI->focusCFZToleranceLabel->show();
 
 7294            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTolerance, 1, 1);
 
 7295            m_CFZUI->focusCFZTolerance->show();
 
 7296            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelengthLabel, 2, 0);
 
 7297            m_CFZUI->focusCFZWavelengthLabel->show();
 
 7298            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelength, 2, 1);
 
 7299            m_CFZUI->focusCFZWavelength->show();
 
 7302        case Focus::FOCUS_CFZ_WAVEFRONT:
 
 7304            cfzMicrons = 4.0f * m_CFZUI->focusCFZTolerance->value() * m_CFZUI->focusCFZWavelength->value() / 1000.0f * pow(
 
 7305                             m_CFZUI->focusCFZFNumber->value(),
 
 7307            cfzSteps = cfzMicrons / m_CFZUI->focusCFZStepSize->value();
 
 7308            m_cfzSteps = std::round(std::max(cfzSteps, cfzCameraSteps));
 
 7309            m_CFZUI->focusCFZFormula->setText(
"CFZ = 4 t λ f²");
 
 7310            m_CFZUI->focusCFZ->setText(
QString(
"%1 μm").arg(cfzMicrons, 0, 
'f', 0));
 
 7311            m_CFZUI->focusCFZSteps->setText(
QString(
"%1 steps").arg(cfzSteps, 0, 
'f', 0));
 
 7312            m_CFZUI->focusCFZCameraSteps->setText(
QString(
"%1 steps").arg(cfzCameraSteps, 0, 
'f', 0));
 
 7313            m_CFZUI->focusCFZFinal->setText(
QString(
"%1 steps").arg(m_cfzSteps, 0, 
'f', 0));
 
 7316            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTauLabel);
 
 7317            m_CFZUI->focusCFZTauLabel->hide();
 
 7318            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTau);
 
 7319            m_CFZUI->focusCFZTau->hide();
 
 7320            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeingLabel);
 
 7321            m_CFZUI->focusCFZSeeingLabel->hide();
 
 7322            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeing);
 
 7323            m_CFZUI->focusCFZSeeing->hide();
 
 7326            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZToleranceLabel, 1, 0);
 
 7327            m_CFZUI->focusCFZToleranceLabel->show();
 
 7328            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTolerance, 1, 1);
 
 7329            m_CFZUI->focusCFZTolerance->show();
 
 7330            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelengthLabel, 2, 0);
 
 7331            m_CFZUI->focusCFZWavelengthLabel->show();
 
 7332            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelength, 2, 1);
 
 7333            m_CFZUI->focusCFZWavelength->show();
 
 7336        case Focus::FOCUS_CFZ_GOLD:
 
 7338            cfzMicrons = 0.00225f * pow(m_CFZUI->focusCFZTau->value(), 0.5f) * m_CFZUI->focusCFZSeeing->value()
 
 7339                         * pow(m_CFZUI->focusCFZFNumber->value(), 2.0f) * m_CFZUI->focusCFZAperture->value();
 
 7340            cfzSteps = cfzMicrons / m_CFZUI->focusCFZStepSize->value();
 
 7341            m_cfzSteps = std::round(std::max(cfzSteps, cfzCameraSteps));
 
 7342            m_CFZUI->focusCFZFormula->setText(
"CFZ = 0.00225 √τ θ f² A");
 
 7343            m_CFZUI->focusCFZ->setText(
QString(
"%1 μm").arg(cfzMicrons, 0, 
'f', 0));
 
 7344            m_CFZUI->focusCFZSteps->setText(
QString(
"%1 steps").arg(cfzSteps, 0, 
'f', 0));
 
 7345            m_CFZUI->focusCFZCameraSteps->setText(
QString(
"%1 steps").arg(cfzCameraSteps, 0, 
'f', 0));
 
 7346            m_CFZUI->focusCFZFinal->setText(
QString(
"%1 steps").arg(m_cfzSteps, 0, 
'f', 0));
 
 7349            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZToleranceLabel);
 
 7350            m_CFZUI->focusCFZToleranceLabel->hide();
 
 7351            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTolerance);
 
 7352            m_CFZUI->focusCFZTolerance->hide();
 
 7353            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZWavelengthLabel);
 
 7354            m_CFZUI->focusCFZWavelengthLabel->hide();
 
 7355            m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZWavelength);
 
 7356            m_CFZUI->focusCFZWavelength->hide();
 
 7359            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTauLabel, 1, 0);
 
 7360            m_CFZUI->focusCFZTauLabel->show();
 
 7361            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTau, 1, 1);
 
 7362            m_CFZUI->focusCFZTau->show();
 
 7363            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZSeeingLabel, 2, 0);
 
 7364            m_CFZUI->focusCFZSeeingLabel->show();
 
 7365            m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZSeeing, 2, 1);
 
 7366            m_CFZUI->focusCFZSeeing->show();
 
 7369    if (linearFocuser != 
nullptr && linearFocuser->isDone())
 
 7370        emit drawCFZ(linearFocuser->solution(), linearFocuser->solutionValue(), m_cfzSteps,
 
 7371                     m_CFZUI->focusCFZDisplayVCurve->isChecked());
 
 7377double Focus::calcCameraCFZ()
 
 7379    return m_CcdPixelSizeX * pow(m_CFZUI->focusCFZFNumber->value(), 2.0) * m_CFZUI->focusCFZAperture->value() / 1000.0;
 
 7382void Focus::wavelengthChanged()
 
 7385    if (m_FilterManager)
 
 7387        m_CFZUI->focusCFZWavelength->setValue(m_FilterManager->getFilterWavelength(
filter()));
 
 7392void Focus::resetCFZToOT()
 
 7395    m_CFZUI->focusCFZFNumber->setValue(m_FocalRatio);
 
 7396    m_CFZUI->focusCFZAperture->setValue(m_Aperture);
 
 7399    if (m_FilterManager)
 
 7401        if (m_CFZUI->focusCFZWavelength->value() != m_FilterManager->getFilterWavelength(
filter()))
 
 7402            m_CFZUI->focusCFZWavelength->setValue(m_FilterManager->getFilterWavelength(
filter()));
 
 7407void Focus::setState(FocusState newState, 
const bool update)
 
 7409    qCDebug(KSTARS_EKOS_FOCUS) << 
"Focus State changes from" << getFocusStatusString(m_state) << 
"to" << getFocusStatusString(
 
 7412    emit newStatus(m_state, opticalTrain(), update);
 
 7415void Focus::initView()
 
 7417    m_FocusView.reset(
new FITSView(focusingWidget, FITS_FOCUS));
 
 7419    m_FocusView->setBaseSize(focusingWidget->size());
 
 7420    m_FocusView->createFloatingToolBar();
 
 7423    focusingWidget->setLayout(vlayout);
 
 7425    m_FocusView->setStarsEnabled(
true);
 
 7426    m_FocusView->setStarsHFREnabled(
true);
 
 7429void Focus::initHelperObjects()
 
 7432    starFitting.reset(
new CurveFitting());
 
 7433    focusFWHM.reset(
new FocusFWHM(m_ScaleCalc));
 
 7434    focusFourierPower.reset(
new FocusFourierPower(m_ScaleCalc));
 
 7435#if defined(HAVE_OPENCV) 
 7436    focusBlurriness.reset(
new FocusBlurriness());
 
 7440    adaptFocus.reset(
new AdaptiveFocus(
this));
 
 7443    focusAdvisor.reset(
new FocusAdvisor(
this));
 
 7446QVariantMap Focus::getAllSettings()
 const 
 7448    QVariantMap settings;
 
 7451    for (
auto &oneWidget : findChildren<QComboBox*>())
 
 7452        settings.insert(oneWidget->objectName(), oneWidget->currentText());
 
 7455    for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
 
 7456        settings.insert(oneWidget->objectName(), oneWidget->value());
 
 7459    for (
auto &oneWidget : findChildren<QSpinBox*>())
 
 7460        settings.insert(oneWidget->objectName(), oneWidget->value());
 
 7463    for (
auto &oneWidget : findChildren<QCheckBox*>())
 
 7464        settings.insert(oneWidget->objectName(), oneWidget->isChecked());
 
 7467    for (
auto &oneWidget : findChildren<QGroupBox*>())
 
 7468        if (oneWidget->isCheckable())
 
 7469            settings.insert(oneWidget->objectName(), oneWidget->isChecked());
 
 7472    for (
auto &oneWidget : findChildren<QSplitter*>())
 
 7473        settings.insert(oneWidget->objectName(), 
QString::fromUtf8(oneWidget->saveState().toBase64()));
 
 7476    for (
auto &oneWidget : findChildren<QRadioButton*>())
 
 7477        settings.insert(oneWidget->objectName(), oneWidget->isChecked());
 
 7482void Focus::setAllSettings(
const QVariantMap &settings)
 
 7486    disconnectSyncSettings();
 
 7488    for (
auto &name : settings.keys())
 
 7491        auto comboBox = findChild<QComboBox*>(name);
 
 7494            syncControl(settings, name, comboBox);
 
 7499        auto doubleSpinBox = findChild<QDoubleSpinBox*>(name);
 
 7502            syncControl(settings, name, doubleSpinBox);
 
 7507        auto spinBox = findChild<QSpinBox*>(name);
 
 7510            syncControl(settings, name, spinBox);
 
 7515        auto checkbox = findChild<QCheckBox*>(name);
 
 7518            syncControl(settings, name, checkbox);
 
 7523        auto groupbox = findChild<QGroupBox*>(name);
 
 7524        if (groupbox && groupbox->isCheckable())
 
 7526            syncControl(settings, name, groupbox);
 
 7531        auto splitter = findChild<QSplitter*>(name);
 
 7534            syncControl(settings, name, splitter);
 
 7539        auto radioButton = findChild<QRadioButton*>(name);
 
 7542            syncControl(settings, name, radioButton);
 
 7548    for (
auto &key : settings.keys())
 
 7550        auto value = settings[key];
 
 7552        Options::self()->setProperty(key.
toLatin1(), value);
 
 7554        m_Settings[key] = value;
 
 7555        m_GlobalSettings[key] = value;
 
 7558    emit settingsUpdated(getAllSettings());
 
 7561    OpticalTrainSettings::Instance()->setOpticalTrainID(OpticalTrainManager::Instance()->
id(opticalTrainCombo->currentText()));
 
 7562    OpticalTrainSettings::Instance()->setOneSetting(OpticalTrainSettings::Focus, m_Settings);
 
 7565    connectSyncSettings();
 
 7568    m_CurveFit = 
static_cast<CurveFitting::CurveFit
> (m_OpsFocusProcess->focusCurveFit->currentIndex());
 
 7569    setFocusDetection(
static_cast<StarAlgorithm
> (m_OpsFocusProcess->focusDetection->currentIndex()));
 
 7570    setCurveFit(
static_cast<CurveFitting::CurveFit
>(m_OpsFocusProcess->focusCurveFit->currentIndex()));
 
 7571    setStarMeasure(
static_cast<StarMeasure
>(m_OpsFocusProcess->focusStarMeasure->currentIndex()));
 
 7572    setWalk(
static_cast<FocusWalk
>(m_OpsFocusMechanics->focusWalk->currentIndex()));
 
 7576bool Focus::syncControl(
const QVariantMap &settings, 
const QString &key, 
QWidget * widget)
 
 7587    if ((pSB = qobject_cast<QSpinBox *>(widget)))
 
 7589        const int value = settings[key].
toInt(&ok);
 
 7596    else if ((pDSB = qobject_cast<QDoubleSpinBox *>(widget)))
 
 7598        const double value = settings[key].toDouble(&ok);
 
 7605    else if ((pCB = qobject_cast<QCheckBox *>(widget)))
 
 7607        const bool value = settings[key].toBool();
 
 7612    else if ((pGB = qobject_cast<QGroupBox *>(widget)))
 
 7614        const bool value = settings[key].toBool();
 
 7619    else if ((pRadioButton = qobject_cast<QRadioButton *>(widget)))
 
 7621        const bool value = settings[key].toBool();
 
 7627    else if ((pComboBox = qobject_cast<QComboBox *>(widget)))
 
 7629        const QString value = settings[key].toString();
 
 7633    else if ((pSplitter = qobject_cast<QSplitter *>(widget)))
 
 7643void Focus::setupOpticalTrainManager()
 
 7645    connect(OpticalTrainManager::Instance(), &OpticalTrainManager::updated, 
this, [
this]()
 
 7648        const int current = opticalTrainCombo->currentIndex();
 
 7651        if (current >= 0 && current < opticalTrainCombo->count())
 
 7652            opticalTrainCombo->setCurrentIndex(current);
 
 7656        OpticalTrainManager::Instance()->openEditor(opticalTrainCombo->currentText());
 
 7660        const int id = OpticalTrainManager::Instance()->id(opticalTrainCombo->itemText(index));
 
 7662        if (m_focuserId == 0)
 
 7664            ProfileSettings::Instance()->setOneSetting(ProfileSettings::FocusOpticalTrain, 
id);
 
 7666        refreshOpticalTrain(
id);
 
 7667        emit trainChanged();
 
 7671void Focus::initOpticalTrain()
 
 7673    opticalTrainCombo->blockSignals(
true);
 
 7674    opticalTrainCombo->clear();
 
 7675    opticalTrainCombo->addItems(OpticalTrainManager::Instance()->getTrainNames());
 
 7676    trainB->setEnabled(
true);
 
 7678    QVariant trainID = ProfileSettings::Instance()->getOneSetting(ProfileSettings::FocusOpticalTrain);
 
 7682        auto id = trainID.
toUInt();
 
 7685        if (OpticalTrainManager::Instance()->exists(
id) == 
false)
 
 7687            qCWarning(KSTARS_EKOS_FOCUS) << 
"Optical train doesn't exist for id" << id;
 
 7688            id = OpticalTrainManager::Instance()->id(opticalTrainCombo->itemText(0));
 
 7690        refreshOpticalTrain(
id);
 
 7693    opticalTrainCombo->blockSignals(
false);
 
 7696void Focus::refreshOpticalTrain(
const int id)
 
 7698    bool validSettings = 
false;
 
 7699    auto name = OpticalTrainManager::Instance()->name(
id);
 
 7701    opticalTrainCombo->setCurrentText(name);
 
 7707    OpticalTrainSettings::Instance()->setOpticalTrainID(
id);
 
 7709    auto focuser = OpticalTrainManager::Instance()->getFocuser(name);
 
 7710    setFocuser(focuser);
 
 7712    auto scope = OpticalTrainManager::Instance()->getScope(name);
 
 7713    double reducer = OpticalTrainManager::Instance()->getReducer(name);
 
 7714    setScopeDetails(scope, reducer);
 
 7716    auto settings = OpticalTrainSettings::Instance()->getOneSetting(OpticalTrainSettings::Focus);
 
 7717    if (settings.isValid())
 
 7719        validSettings = 
true;
 
 7720        auto map = settings.toJsonObject().toVariantMap();
 
 7721        if (map != m_Settings)
 
 7724            setAllSettings(map);
 
 7728    auto camera = OpticalTrainManager::Instance()->getCamera(name);
 
 7731        opticalTrainCombo->setToolTip(
QString(
"%1 @ %2").arg(camera->getDeviceName(), scope[
"name"].toString()));
 
 7734        auto nvp = camera->getNumber(
"CCD_INFO");
 
 7737            m_CcdPixelSizeX = 0.0;
 
 7738            m_CcdWidth = m_CcdHeight = 0;
 
 7742            auto np = nvp->findWidgetByName(
"CCD_PIXEL_SIZE_X");
 
 7744                m_CcdPixelSizeX = np->getValue();
 
 7745            np = nvp->findWidgetByName(
"CCD_MAX_X");
 
 7747                m_CcdWidth = np->getValue();
 
 7748            np = nvp->findWidgetByName(
"CCD_MAX_Y");
 
 7750                m_CcdHeight = np->getValue();
 
 7755    auto filterWheel = OpticalTrainManager::Instance()->getFilterWheel(name);
 
 7756    setFilterWheel(filterWheel);
 
 7764        focusAdvisor->setupParams(name);
 
 7765        focusAdvisor->updateParams();
 
 7772void Focus::setScopeDetails(
const QJsonObject &scope, 
const double reducer)
 
 7774    m_Aperture = scope[
"aperture"].toDouble(-1);
 
 7775    m_FocalLength = scope[
"focal_length"].toDouble(-1);
 
 7776    m_FocalRatio = scope[
"focal_ratio"].toDouble(-1);
 
 7777    m_ScopeType = scope[
"type"].toString();
 
 7778    m_Reducer = reducer;
 
 7781    if (m_Reducer > 0.0)
 
 7782        m_FocalLength *= m_Reducer;
 
 7785    if (m_FocalRatio <= 0.0)
 
 7787        m_FocalRatio = (m_Aperture > 0.001) ? m_FocalLength / m_Aperture : 0.0f;
 
 7788    else if (m_Aperture < 0.0)
 
 7790        m_Aperture = m_FocalLength / m_FocalRatio;
 
void drawPolynomial(PolynomialFit *poly, bool isVShape, bool activate, bool plot=true)
draw the approximating polynomial into the HFR V-graph
 
void toggleVideo(bool enabled)
toggleVideo Turn on and off video streaming if supported by the camera.
 
void checkTemperatureSource(const QString &name=QString())
Check temperature source and make sure information is updated accordingly.
 
Q_SCRIPTABLE bool setFilter(const QString &filter)
DBUS interface function.
 
void startFraming()
startFraming Begins continuous capture of the CCD and calculates HFR every frame.
 
void newHFRPlotPosition(double pos, double hfr, double sigma, bool outlier, int pulseDuration, bool plot=true)
new HFR plot position with sigma
 
void redrawHFRPlot(PolynomialFit *poly, double solutionPosition, double solutionValue)
redraw the entire HFR plot
 
void loadStellarSolverProfiles()
setWeatherData Updates weather data that could be used to extract focus temperature from observatory ...
 
Q_SCRIPTABLE Q_NOREPLY void setBinning(int binX, int binY)
DBUS interface function.
 
void clearDataPoints()
clearDataPoints Remove all data points from HFR plots
 
Q_SCRIPTABLE QString camera()
DBUS interface function.
 
Q_SCRIPTABLE QString focuser()
DBUS interface function.
 
Q_SCRIPTABLE Q_NOREPLY void setAutoStarEnabled(bool enable)
DBUS interface function.
 
void runAutoFocus(const AutofocusReason autofocusReason, const QString &reasonInfo)
Run the autofocus process for the currently selected filter.
 
Q_SCRIPTABLE QString filterWheel()
DBUS interface function.
 
void updateProperty(INDI::Property prop)
updateProperty Read focus number properties of interest as they arrive from the focuser driver and pr...
 
void focusStarSelected(int x, int y)
focusStarSelected The user selected a focus star, save its coordinates and subframe it if subframing ...
 
void reconnectFocuser(const QString &focuser)
reconnectFocuser Add focuser to the list of available focusers.
 
bool setFocuser(ISD::Focuser *device)
addFocuser Add focuser to the list of available focusers.
 
void resetFocuser()
Move the focuser to the initial focus position.
 
void processData(const QSharedPointer< FITSData > &data)
newFITS A new FITS blob is received by the CCD driver.
 
void initHFRPlot(QString str, double starUnits, bool minimum, bool useWeights, bool showPosition)
initialize the HFR V plot
 
void selectFocusStarFraction(double x, double y)
selectFocusStarFraction Select the focus star based by fraction of the overall size.
 
void appendLogText(const QString &logtext)
setFocusStatus Upon completion of the focusing process, set its status (fail or pass) and reset focus...
 
Q_SCRIPTABLE bool useFullField()
DBUS interface function.
 
void adaptiveFocus()
adaptiveFocus moves the focuser between subframes to stay at focus
 
Q_SCRIPTABLE Q_NOREPLY void resetFrame()
DBUS interface function.
 
void meridianFlipStarted()
React when a meridian flip has been started.
 
void processTemperatureSource(INDI::Property prop)
processTemperatureSource Updates focus temperature source.
 
void removeDevice(const QSharedPointer< ISD::GenericDevice > &deviceRemoved)
removeDevice Remove device from Focus module
 
void syncCameraInfo()
syncCameraInfo Read current CCD information and update settings accordingly.
 
void checkFilter()
Check Filter and make sure information is updated accordingly.
 
void drawCFZ(double minPosition, double minValue, int m_cfzSteps, bool plt)
Draw Critical Focus Zone on graph.
 
void finalUpdates(const QString &title, bool plot=true)
final updates after focus run comopletes on the focus plot
 
void minimumFound(double solutionPosition, double solutionValue, bool plot=true)
Focus solution with minimal HFR found.
 
void checkStopFocus(bool abort)
checkStopFocus Perform checks before stopping the autofocus operation.
 
void checkFocuser()
Check Focuser and make sure information is updated accordingly.
 
Q_SCRIPTABLE Q_NOREPLY void setExposure(double value)
DBUS interface function.
 
void setTitle(const QString &title, bool plot=true)
draw a title on the focus plot
 
void drawCurve(CurveFitting *curve, bool isVShape, bool activate, bool plot=true)
draw the curve into the HFR V-graph
 
QStringList getStellarSolverProfiles()
getStellarSolverProfiles
 
Q_SCRIPTABLE Q_NOREPLY void setAutoFocusParameters(int boxSize, int stepSize, int maxTravel, double tolerance)
DBUS interface function.
 
Q_SCRIPTABLE Ekos::FocusState status()
DBUS interface function.
 
bool setFilterWheel(ISD::FilterWheel *device)
addFilter Add filter to the list of available filters.
 
void updateTemperatureSources(const QList< QSharedPointer< ISD::GenericDevice > > &temperatureSources)
updateTemperatureSources Update list of available temperature sources.
 
Q_SCRIPTABLE Q_NOREPLY void setAutoSubFrameEnabled(bool enable)
DBUS interface function.
 
bool setCamera(ISD::Camera *device)
Add CCD to the list of available CCD.
 
void syncCCDControls()
Update camera controls like Gain, ISO, Offset...etc.
 
void checkCamera()
Check CCD and make sure information is updated accordingly.
 
void selectImageMask()
setImageMask Select the currently active image mask filtering the stars relevant for focusing
 
CameraChip class controls a particular chip in camera.
 
Camera class controls an INDI Camera device.
 
@ ERROR_SAVE
INDI Camera error.
 
Focuser class handles control of INDI focuser devices.
 
KPageWidgetItem * addPage(QWidget *page, const QString &itemName, const QString &pixmapName=QString(), const QString &header=QString(), bool manage=true)
 
void setIcon(const QIcon &icon)
 
static KStars * Instance()
 
The sky coordinates of a point in the sky.
 
An angle, stored as degrees, but expressible in many ways.
 
const double & Degrees() const
 
Q_SCRIPTABLE Q_NOREPLY void checkFocus(double requiredHFR)
checkFocus Given the minimum required HFR, check focus and calculate HFR.
 
Q_SCRIPTABLE bool focusOut(int ms=-1, int speedFactor=1)
DBUS interface function.
 
Q_SCRIPTABLE Q_NOREPLY void capture(double settleTime=0.0)
DBUS interface function.
 
Q_SCRIPTABLE bool focusIn(int ms=-1, int speedFactor=1)
DBUS interface function.
 
Q_SCRIPTABLE Q_NOREPLY void start()
DBUS interface function.
 
Q_SCRIPTABLE Q_NOREPLY void abort()
DBUS interface function.
 
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
 
QString i18nc(const char *context, const char *text, const TYPE &arg...)
 
QString i18n(const char *text, const TYPE &arg...)
 
char * toString(const EngineQuery &query)
 
Ekos is an advanced Astrophotography tool for Linux.
 
KIOCORE_EXPORT TransferJob * get(const QUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
 
QString path(const QString &relativePath)
 
KIOCORE_EXPORT QString dir(const QString &fileClass)
 
QString name(StandardAction id)
 
KOSM_EXPORT double distance(const std::vector< const OSM::Node * > &path, Coordinate coord)
 
QByteArray fromBase64(const QByteArray &base64, Base64Options options)
 
QByteArray toBase64(Base64Options options) const const
 
void stateChanged(int state)
 
void activated(int index)
 
void currentIndexChanged(int index)
 
void currentTextChanged(const QString &text)
 
qint64 secsTo(const QDateTime &other) const const
 
QString toString(QStringView format, QCalendar cal) const const
 
QString filePath(const QString &fileName) const const
 
void valueChanged(double d)
 
bool exists(const QString &path)
 
bool isChecked() const const
 
Qt::KeyboardModifiers keyboardModifiers()
 
QIcon fromTheme(const QString &name)
 
const_iterator constBegin() const const
 
const_iterator constEnd() const const
 
qsizetype count() const const
 
qsizetype size() const const
 
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
 
bool disconnect(const QMetaObject::Connection &connection)
 
QList< T > findChildren(Qt::FindChildOptions options) const const
 
bool contains(const QPoint &point, bool proper) const const
 
bool isNull() const const
 
bool restoreState(const QByteArray &state)
 
QByteArray saveState() const const
 
void splitterMoved(int pos, int index)
 
void setEnabled(bool enabled)
 
QStandardItem * item(int row, int column) const const
 
QString & append(QChar ch)
 
QString arg(Args &&... args) const const
 
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
 
QString fromUtf8(QByteArrayView str)
 
bool isEmpty() const const
 
QString number(double n, char format, int precision)
 
QByteArray toLatin1() const const
 
QByteArray toUtf8() const const
 
QTextStream & center(QTextStream &stream)
 
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
 
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
 
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
 
QUrl fromLocalFile(const QString &localFile)
 
bool isValid() const const
 
bool toBool() const const
 
double toDouble(bool *ok) const const
 
int toInt(bool *ok) const const
 
QString toString() const const
 
uint toUInt(bool *ok) const const