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
84 qRegisterMetaType<Ekos::FocusState>(
"Ekos::FocusState");
85 qDBusRegisterMetaType<Ekos::FocusState>();
86 new FocusAdaptor(
this);
102 loadGlobalSettings();
105 connectSyncSettings();
108 adaptFocus.reset(
new AdaptiveFocus(
this));
111 focusAdvisor.reset(
new FocusAdvisor(
this));
113 connect(focusAdvisor.get(), &FocusAdvisor::newStage,
this, &Focus::newFocusAdvisorStage);
114 connect(focusAdvisor.get(), &FocusAdvisor::newMessage,
this, &Focus::newFocusAdvisorMessage);
121 for (
auto &button : qButtons)
122 button->setAutoDefault(
false);
124 appendLogText(
i18n(
"Idle."));
127 m_FocusMotionTimer.setInterval(m_OpsFocusMechanics->focusMotionTimeout->value() * 1000);
128 m_FocusMotionTimer.setSingleShot(
true);
131 m_OpsFocusProcess->editFocusProfile->setIcon(
QIcon::fromTheme(
"document-edit"));
136 KConfigDialog *optionsEditor = new KConfigDialog(this,
"OptionsProfileEditor", Options::self());
137 optionsProfileEditor = new StellarSolverProfileEditor(this, Ekos::FocusProfiles, optionsEditor);
139 optionsEditor->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
141 KPageWidgetItem *mainPage = optionsEditor->addPage(optionsProfileEditor, i18n(
"Focus Options Profile Editor"));
142 mainPage->setIcon(QIcon::fromTheme(
"configure"));
143 connect(optionsProfileEditor, &StellarSolverProfileEditor::optionsProfilesUpdated, this, &Focus::loadStellarSolverProfiles);
144 optionsProfileEditor->loadProfile(m_OpsFocusProcess->focusSEPProfile->currentText());
145 optionsEditor->show();
148 loadStellarSolverProfiles();
162 m_DarkProcessor =
new DarkProcessor(
this);
164 connect(m_DarkProcessor, &DarkProcessor::darkFrameCompleted,
this, [
this](
bool completed)
166 m_OpsFocusSettings->useFocusDarkFrame->setChecked(completed);
167 m_FocusView->setProperty(
"suspended",
false);
170 m_FocusView->rescale(ZOOM_KEEP_LEVEL);
171 m_FocusView->updateFrame();
173 setCaptureComplete();
177 setupOpticalTrainManager();
178 refreshOpticalTrain();
181 connectFilterManager();
185void Focus::prepareGUI()
195 m_OpsFocusSettings =
new OpsFocusSettings();
203 m_OpsFocusProcess =
new OpsFocusProcess();
204 page = dialog->
addPage(m_OpsFocusProcess,
i18n(
"Process"),
nullptr,
i18n(
"Focus Process"),
false);
207 m_OpsFocusMechanics =
new OpsFocusMechanics();
208 page = dialog->
addPage(m_OpsFocusMechanics,
i18n(
"Mechanics"),
nullptr,
i18n(
"Focus Mechanics"),
false);
212 m_CFZDialog =
new QDialog(
this);
213 m_CFZUI.reset(
new Ui::focusCFZDialog());
214 m_CFZUI->setupUi(m_CFZDialog);
220 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
221 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
222 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
223 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
224 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
225 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusThreshold);
226 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
227 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
228 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
229 m_OpsFocusProcess->gridLayoutProcessBucket->removeWidget(m_OpsFocusProcess->focusTolerance);
230 delete m_OpsFocusProcess->gridLayoutProcessBucket;
233 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutStepsLabel,
234 m_OpsFocusMechanics->focusNumStepsLabel);
235 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutSteps,
236 m_OpsFocusMechanics->focusNumSteps);
240 for (
int i = 0; i < m_OpsFocusProcess->focusStarMeasure->count(); i++)
241 m_StarMeasureText.append(m_OpsFocusProcess->focusStarMeasure->itemText(i));
242 for (
int i = 0; i < m_OpsFocusProcess->focusCurveFit->count(); i++)
243 m_CurveFitText.append(m_OpsFocusProcess->focusCurveFit->itemText(i));
244 for (
int i = 0; i < m_OpsFocusMechanics->focusWalk->count(); i++)
245 m_FocusWalkText.append(m_OpsFocusMechanics->focusWalk->itemText(i));
248void Focus::loadStellarSolverProfiles()
250 QString savedOptionsProfiles =
QDir(KSPaths::writableLocation(
254 m_StellarSolverProfiles = StellarSolver::loadSavedOptionsProfiles(savedOptionsProfiles);
255 addMissingStellarSolverProfile(savedOptionsProfiles, FOCUS_DEFAULT_NAME);
256 addMissingStellarSolverProfile(savedOptionsProfiles, FOCUS_DEFAULT_DONUT_NAME);
259 m_StellarSolverProfiles = getDefaultFocusOptionsProfiles();
260 m_OpsFocusProcess->focusSEPProfile->clear();
261 for(
auto ¶m : m_StellarSolverProfiles)
262 m_OpsFocusProcess->focusSEPProfile->addItem(param.listName);
263 auto profile = m_Settings[
"focusSEPProfile"];
264 if (profile.isValid())
265 m_OpsFocusProcess->focusSEPProfile->setCurrentText(profile.toString());
268void Focus::addMissingStellarSolverProfile(
const QString profilePath,
const QString profile)
270 for(
auto params : m_StellarSolverProfiles)
272 if (params.listName == profile)
278 SSolver::Parameters params;
279 if (profile == FOCUS_DEFAULT_DONUT_NAME)
280 params = getFocusOptionsProfileDefaultDonut();
281 else if (profile == FOCUS_DEFAULT_NAME)
282 params = getFocusOptionsProfileDefault();
286 settings.beginGroup(params.listName);
292 settings.setValue(it.key(), it.value());
296 m_StellarSolverProfiles.append(params);
302 for (
auto param : m_StellarSolverProfiles)
303 profiles << param.listName;
311 if (focusingWidget->parent() ==
nullptr)
312 toggleFocusingWidgetFullScreen();
315void Focus::resetFrame()
317 if (m_Camera && m_Camera->isConnected())
319 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
324 targetChip->resetFrame();
327 targetChip->getFrame(&x, &y, &w, &h);
329 qCDebug(KSTARS_EKOS_FOCUS) <<
"Frame is reset. X:" << x <<
"Y:" << y <<
"W:" << w <<
"H:" << h <<
"binX:" << 1 <<
"binY:" <<
332 QVariantMap settings;
337 settings[
"binx"] = 1;
338 settings[
"biny"] = 1;
339 frameSettings[targetChip] = settings;
341 starSelected =
false;
345 m_FocusView->setTrackingBox(
QRect());
346 checkMosaicMaskLimits();
354 return m_Camera->getDeviceName();
359void Focus::checkCamera()
379 case FOCUS_CHANGING_FILTER:
384 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
385 if (targetChip && targetChip->isCapturing())
390 focusBinning->setEnabled(targetChip->canBin());
391 m_OpsFocusSettings->focusSubFrame->setEnabled(targetChip->canSubframe());
392 if (targetChip->canBin())
394 int subBinX = 1, subBinY = 1;
395 focusBinning->clear();
396 targetChip->getMaxBin(&subBinX, &subBinY);
397 for (
int i = 1; i <= subBinX; i++)
398 focusBinning->addItem(
QString(
"%1x%2").arg(i).arg(i));
400 auto binning = m_Settings[
"focusBinning"];
401 if (binning.isValid())
402 focusBinning->setCurrentText(binning.toString());
405 connect(m_Camera, &ISD::Camera::videoStreamToggled,
this, &Ekos::Focus::setVideoStreamEnabled,
Qt::UniqueConnection);
406 liveVideoB->setEnabled(m_Camera->hasVideoStream());
407 if (m_Camera->hasVideoStream())
408 setVideoStreamEnabled(m_Camera->isStreamingEnabled());
418void Focus::syncCCDControls()
420 if (m_Camera ==
nullptr)
423 auto targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
424 if (targetChip ==
nullptr || (targetChip && targetChip->isCapturing()))
427 auto isoList = targetChip->getISOList();
430 if (isoList.isEmpty())
432 focusISO->setEnabled(
false);
433 ISOLabel->setEnabled(
false);
437 focusISO->setEnabled(
true);
438 ISOLabel->setEnabled(
true);
439 focusISO->addItems(isoList);
440 focusISO->setCurrentIndex(targetChip->getISOIndex());
443 bool hasGain = m_Camera->hasGain();
444 gainLabel->setEnabled(hasGain);
445 focusGain->setEnabled(hasGain && m_Camera->getGainPermission() != IP_RO);
448 double gain = 0, min = 0, max = 0, step = 1;
449 m_Camera->getGainMinMaxStep(&min, &max, &step);
450 if (m_Camera->getGain(&gain))
453 GainSpinSpecialValue = min - step;
454 focusGain->setRange(GainSpinSpecialValue, max);
455 focusGain->setSpecialValueText(
i18n(
"--"));
457 focusGain->setSingleStep(step);
459 auto defaultGain = m_Settings[
"focusGain"];
460 if (defaultGain.isValid())
461 focusGain->setValue(defaultGain.toDouble());
463 focusGain->setValue(GainSpinSpecialValue);
470void Focus::syncCameraInfo()
472 if (m_Camera ==
nullptr)
475 auto targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
476 if (targetChip ==
nullptr || (targetChip && targetChip->isCapturing()))
479 m_OpsFocusSettings->focusSubFrame->setEnabled(targetChip->canSubframe());
481 if (frameSettings.contains(targetChip) ==
false)
484 if (targetChip->getFrame(&x, &y, &w, &h))
486 int binx = 1, biny = 1;
487 targetChip->getBinning(&binx, &biny);
490 int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
491 targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
493 QVariantMap settings;
495 settings[
"x"] = m_OpsFocusSettings->focusSubFrame->isChecked() ? x : minX;
496 settings[
"y"] = m_OpsFocusSettings->focusSubFrame->isChecked() ? y : minY;
497 settings[
"w"] = m_OpsFocusSettings->focusSubFrame->isChecked() ? w : maxW;
498 settings[
"h"] = m_OpsFocusSettings->focusSubFrame->isChecked() ? h : maxH;
499 settings[
"binx"] = binx;
500 settings[
"biny"] = biny;
502 frameSettings[targetChip] = settings;
508bool Focus::setFilterWheel(ISD::FilterWheel *device)
510 if (m_FilterWheel && m_FilterWheel == device)
517 m_FilterWheel->disconnect(
this);
519 m_FilterWheel = device;
523 connect(m_FilterWheel, &ISD::ConcreteDevice::Connected,
this, [
this]()
525 FilterPosLabel->setEnabled(
true);
526 focusFilter->setEnabled(
true);
527 filterManagerB->setEnabled(
true);
529 connect(m_FilterWheel, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
531 FilterPosLabel->setEnabled(
false);
532 focusFilter->setEnabled(
false);
533 filterManagerB->setEnabled(
false);
537 auto isConnected = m_FilterWheel && m_FilterWheel->isConnected();
538 FilterPosLabel->setEnabled(isConnected);
539 focusFilter->setEnabled(isConnected);
540 filterManagerB->setEnabled(isConnected);
542 FilterPosLabel->setEnabled(
true);
543 focusFilter->setEnabled(
true);
551 defaultFocusTemperatureSource->blockSignals(
true);
552 m_TemperatureSources = temperatureSources;
554 defaultFocusTemperatureSource->clear();
555 for (
auto device : temperatureSources)
559 defaultFocusTemperatureSource->addItem(device->getDeviceName());
561 defaultFocusTemperatureSource->blockSignals(
false);
563 auto targetSource = m_Settings[
"defaultFocusTemperatureSource"];
564 if (targetSource.isValid())
565 checkTemperatureSource(targetSource.toString());
568void Focus::checkTemperatureSource(
const QString &name )
573 source = defaultFocusTemperatureSource->currentText();
574 if (source.isEmpty())
580 for (
auto &oneSource : m_TemperatureSources)
582 if (oneSource->getDeviceName() == source)
584 currentSource = oneSource;
589 m_LastSourceDeviceAutofocusTemperature = currentSource;
596 for (
const auto &oneSource : m_TemperatureSources)
600 if (findTemperatureElement(currentSource))
602 defaultFocusTemperatureSource->setCurrentText(name);
603 m_LastSourceAutofocusTemperature = currentTemperatureSourceElement->value;
604 absoluteTemperatureLabel->setText(
QString(
"%1 °C").arg(currentTemperatureSourceElement->value, 0,
'f', 2));
605 deltaTemperatureLabel->setText(
QString(
"%1 °C").arg(0.0, 0,
'f', 2));
609 m_LastSourceAutofocusTemperature = INVALID_VALUE;
622 auto temperatureProperty = device->getProperty(
"FOCUS_TEMPERATURE");
623 if (!temperatureProperty)
624 temperatureProperty = device->getProperty(
"CCD_TEMPERATURE");
625 if (temperatureProperty)
627 currentTemperatureSourceElement = temperatureProperty.getNumber()->at(0);
631 temperatureProperty = device->getProperty(
"WEATHER_PARAMETERS");
632 if (temperatureProperty)
634 for (
int i = 0; i < temperatureProperty.getNumber()->count(); i++)
636 if (strstr(temperatureProperty.getNumber()->at(i)->getName(),
"_TEMPERATURE"))
638 currentTemperatureSourceElement = temperatureProperty.getNumber()->at(i);
650 return m_FilterWheel->getDeviceName();
660 focusFilter->setCurrentText(filter);
669 return focusFilter->currentText();
672void Focus::checkFilter()
674 focusFilter->
clear();
678 FilterPosLabel->setEnabled(
false);
679 focusFilter->setEnabled(
false);
680 filterManagerB->setEnabled(
false);
684 m_FilterManager->disconnect(
this);
685 disconnect(m_FilterManager.get());
686 m_FilterManager.reset();
691 FilterPosLabel->setEnabled(
true);
692 focusFilter->setEnabled(
true);
693 filterManagerB->setEnabled(
true);
695 setupFilterManager();
697 focusFilter->addItems(m_FilterManager->getFilterLabels());
699 currentFilterPosition = m_FilterManager->getFilterPosition();
701 focusFilter->setCurrentIndex(currentFilterPosition - 1);
703 focusExposure->setValue(m_FilterManager->getFilterExposure());
708 if (m_Focuser && m_Focuser == device)
715 m_Focuser->disconnect(
this);
721 connect(m_Focuser, &ISD::ConcreteDevice::Connected,
this, [
this]()
725 connect(m_Focuser, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
732 emit focuserChanged(m_focuserId, device !=
nullptr);
739 return m_Focuser->getDeviceName();
744void Focus::checkFocuser()
749 m_FilterManager->setFocusReady(
false);
750 canAbsMove = canRelMove = canTimerMove =
false;
752 setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
757 m_FilterManager->setFocusReady(m_Focuser->isConnected());
759 hasDeviation = m_Focuser->hasDeviation();
761 canAbsMove = m_Focuser->canAbsMove();
765 getAbsFocusPosition();
767 absTicksSpin->setEnabled(
true);
768 absTicksLabel->setEnabled(
true);
769 startGotoB->setEnabled(
true);
772 if (absTicksSpin->value() <= 0)
773 absTicksSpin->setValue(currentPosition);
777 absTicksSpin->setEnabled(
false);
778 absTicksLabel->setEnabled(
false);
779 startGotoB->setEnabled(
false);
782 canRelMove = m_Focuser->canRelMove();
787 if (canAbsMove ==
false && canRelMove ==
true)
789 currentPosition = 50000;
790 absMotionMax = 100000;
794 canTimerMove = m_Focuser->canTimerMove();
800 if (!canAbsMove && !canRelMove && canTimerMove)
802 currentPosition = 50000;
803 absMotionMax = 100000;
807 m_FocusType = (canRelMove || canAbsMove || canTimerMove) ? FOCUS_AUTO : FOCUS_MANUAL;
808 profilePlot->setFocusAuto(m_FocusType == FOCUS_AUTO);
810 bool hasBacklash = m_Focuser->hasBacklash();
811 m_OpsFocusMechanics->focusBacklash->setEnabled(hasBacklash);
812 m_OpsFocusMechanics->focusBacklash->disconnect(
this);
815 double min = 0, max = 0, step = 0;
816 m_Focuser->getMinMaxStep(
"FOCUS_BACKLASH_STEPS",
"FOCUS_BACKLASH_VALUE", &min, &max, &step);
817 m_OpsFocusMechanics->focusBacklash->setMinimum(min);
818 m_OpsFocusMechanics->focusBacklash->setMaximum(max);
819 m_OpsFocusMechanics->focusBacklash->setSingleStep(step);
820 m_OpsFocusMechanics->focusBacklash->setValue(m_Focuser->getBacklash());
822 this, [
this](
int value)
826 if (m_Focuser->getBacklash() == value)
832 m_Focuser->setBacklash(value);
837 connect(m_OpsFocusMechanics->focusBacklash, QOverload<int>::of(&
QSpinBox::valueChanged),
this, &Ekos::Focus::syncSettings);
841 m_OpsFocusMechanics->focusBacklash->setValue(0);
847 setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
852 if (m_Camera && m_Camera == device)
858 m_captureInProgress =
false;
861 m_Camera->disconnect(
this);
867 connect(m_Camera, &ISD::ConcreteDevice::Connected,
this, [
this]()
869 focuserGroup->setEnabled(
true);
870 ccdGroup->setEnabled(
true);
871 toolsGroup->setEnabled(
true);
873 connect(m_Camera, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
875 focuserGroup->setEnabled(
false);
876 ccdGroup->setEnabled(
false);
877 toolsGroup->setEnabled(
false);
881 auto isConnected = m_Camera && m_Camera->isConnected();
882 focuserGroup->setEnabled(isConnected);
883 ccdGroup->setEnabled(isConnected);
884 toolsGroup->setEnabled(isConnected);
892 checkMosaicMaskLimits();
896void Focus::getAbsFocusPosition()
901 auto absMove = m_Focuser->getNumber(
"ABS_FOCUS_POSITION");
905 const auto &it = absMove->at(0);
906 currentPosition =
static_cast<int>(it->getValue());
907 absMotionMax = it->getMax();
908 absMotionMin = it->getMin();
910 absTicksSpin->setMinimum(it->getMin());
911 absTicksSpin->setMaximum(it->getMax());
912 absTicksSpin->setSingleStep(it->getStep());
915 double const travel = std::abs(it->getMax() - it->getMin());
916 m_OpsFocusMechanics->focusMaxTravel->setMaximum(travel);;
920 m_OpsFocusMechanics->focusTicks->setMaximum(it->getMax() / 2);
924void Focus::processTemperatureSource(INDI::Property prop)
926 if (m_LastSourceAutofocusTemperature == INVALID_VALUE && m_LastSourceDeviceAutofocusTemperature
927 && !currentTemperatureSourceElement )
929 if( findTemperatureElement( m_LastSourceDeviceAutofocusTemperature ) )
931 appendLogText(
i18n(
"Finally found temperature source %1",
QString(currentTemperatureSourceElement->nvp->name)));
932 m_LastSourceAutofocusTemperature = currentTemperatureSourceElement->value;
937 if (currentTemperatureSourceElement && currentTemperatureSourceElement->nvp->name == prop.getName())
939 if (m_LastSourceAutofocusTemperature != INVALID_VALUE)
941 delta = currentTemperatureSourceElement->value - m_LastSourceAutofocusTemperature;
942 emit newFocusTemperatureDelta(abs(delta), currentTemperatureSourceElement->value, opticalTrain());
946 emit newFocusTemperatureDelta(0, currentTemperatureSourceElement->value, opticalTrain());
949 absoluteTemperatureLabel->setText(
QString(
"%1 °C").arg(currentTemperatureSourceElement->value, 0,
'f', 2));
950 deltaTemperatureLabel->setText(
QString(
"%1%2 °C").arg((delta > 0.0 ?
"+" :
"")).arg(delta, 0,
'f', 2));
952 deltaTemperatureLabel->setStyleSheet(
"color: lightgreen");
954 deltaTemperatureLabel->setStyleSheet(
"color: lightcoral");
956 deltaTemperatureLabel->setStyleSheet(
"color: lightblue");
960void Focus::setLastFocusTemperature()
962 m_LastSourceAutofocusTemperature = currentTemperatureSourceElement ? currentTemperatureSourceElement->value : INVALID_VALUE;
965 deltaTemperatureLabel->setText(
QString(
"0 °C"));
966 deltaTemperatureLabel->setStyleSheet(
"color: lightgreen");
968 emit newFocusTemperatureDelta(0, -1e6, opticalTrain());
971void Focus::setLastFocusAlt()
973 if (mountAlt < 0.0 || mountAlt > 90.0)
974 m_LastSourceAutofocusAlt = INVALID_VALUE;
976 m_LastSourceAutofocusAlt = mountAlt;
980void Focus::resetAdaptiveFocus(
bool enabled)
983 Options::setFocusAdaptive(enabled);
986 adaptFocus.reset(
new AdaptiveFocus(
this));
987 adaptFocus->resetAdaptiveFocusCounters();
991void Focus::adaptiveFocus()
994 adaptFocus->runAdaptiveFocus(currentPosition, filter());
998void Focus::startAbIns()
1000 m_abInsOn = canAbInsStart();
1001 runAutoFocus(AutofocusReason::FOCUS_ABERRATION_INSPECTOR,
"");
1005void Focus::manualStart()
1007 runAutoFocus(AutofocusReason::FOCUS_MANUAL,
"");
1013 runAutoFocus(AutofocusReason::FOCUS_SCHEDULER,
"");
1017void Focus::runAutoFocus(AutofocusReason autofocusReason,
const QString &reasonInfo)
1019 m_AutofocusReason = autofocusReason;
1020 m_AutofocusReasonInfo = reasonInfo;
1021 if (m_Focuser ==
nullptr)
1023 appendLogText(
i18n(
"No Focuser connected."));
1024 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_FOCUSER);
1028 if (m_Camera ==
nullptr)
1030 appendLogText(
i18n(
"No CCD connected."));
1031 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_CAMERA);
1035 if (!canAbsMove && !canRelMove && m_OpsFocusMechanics->focusTicks->value() <= MINIMUM_PULSE_TIMER)
1037 appendLogText(
i18n(
"Starting pulse step is too low. Increase the step size to %1 or higher...",
1038 MINIMUM_PULSE_TIMER * 5));
1039 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_LOW_PULSE);
1048 appendLogText(
i18n(
"Autofocus is already running, discarding start request."));
1055 appendLogText(
i18n(
"Build Offset is already running, Autofocus rejected."));
1056 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
1063 appendLogText(
i18n(
"In Focus Loop, Autofocus rejected."));
1064 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
1068 if (inAdjustFocus || adaptFocus->inAdaptiveFocus())
1070 QString str = inAdjustFocus ?
i18n(
"Adjust Focus") :
i18n(
"Adaptive Focus");
1071 if (++m_StartRetries < MAXIMUM_RESTART_ITERATIONS)
1073 appendLogText(
i18n(
"Autofocus start request - Waiting 10sec for %1 to complete.", str));
1076 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
1081 appendLogText(
i18n(
"Discarding Autofocus start request - %1 in progress.", str));
1082 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
1086 inBuildOffsets = (autofocusReason == AutofocusReason::FOCUS_FILTER_OFFSETS);
1087 if (autofocusReason == AutofocusReason::FOCUS_USER_REQUEST)
1089 forceInSeqAF->setChecked(
false);
1090 emit inSequenceAF(
false, opticalTrain());
1095 m_LastFocusDirection = FOCUS_NONE;
1097 waitStarSelectTimer.stop();
1100 m_FocusMotionTimerCounter = 0;
1101 m_FocusMotionTimer.stop();
1102 m_FocusMotionTimer.setInterval(m_OpsFocusMechanics->focusMotionTimeout->value() * 1000);
1105 m_FocuserReconnectCounter = 0;
1108 m_FocuserReconnectCounter = 0;
1109 m_DebugFocuserCounter = 0;
1116 m_RestartState = RESTART_NONE;
1124 getAbsFocusPosition();
1125 pulseDuration = m_OpsFocusMechanics->focusTicks->value();
1127 else if (canRelMove)
1131 pulseDuration = m_OpsFocusMechanics->focusTicks->value();
1133 absMotionMax = 100000;
1138 pulseDuration = m_OpsFocusMechanics->focusTicks->value();
1140 absMotionMax = 100000;
1144 focuserAdditionalMovement = 0;
1145 starMeasureFrames.clear();
1157 profilePlot->clear();
1158 FWHMOut->setText(
"");
1160 qCInfo(KSTARS_EKOS_FOCUS) <<
"Starting Autofocus " << m_AFRun
1161 <<
" on" << opticalTrain()
1162 <<
" Reason: " << AutofocusReasonStr[m_AutofocusReason]
1163 <<
" Reason Info: " << m_AutofocusReasonInfo
1164 <<
" CanAbsMove: " << (canAbsMove ?
"yes" :
"no" )
1165 <<
" CanRelMove: " << (canRelMove ?
"yes" :
"no" )
1166 <<
" CanTimerMove: " << (canTimerMove ?
"yes" :
"no" )
1167 <<
" Position:" << currentPosition
1168 <<
" Filter:" << filter()
1169 <<
" Exp:" << focusExposure->value()
1170 <<
" Bin:" << focusBinning->currentText()
1171 <<
" Gain:" << focusGain->value()
1172 <<
" ISO:" << focusISO->currentText();
1173 qCInfo(KSTARS_EKOS_FOCUS) <<
"Settings Tab."
1174 <<
" Auto Select Star:" << ( m_OpsFocusSettings->focusAutoStarEnabled->isChecked() ?
"yes" :
"no" )
1175 <<
" Dark Frame:" << ( m_OpsFocusSettings->useFocusDarkFrame->isChecked() ?
"yes" :
"no" )
1176 <<
" Sub Frame:" << ( m_OpsFocusSettings->focusSubFrame->isChecked() ?
"yes" :
"no" )
1177 <<
" Box:" << m_OpsFocusSettings->focusBoxSize->value()
1178 <<
" Full frame:" << ( m_OpsFocusSettings->focusUseFullField->isChecked() ?
"yes" :
"no " )
1179 <<
" Focus Mask: " << (m_OpsFocusSettings->focusNoMaskRB->isChecked() ?
"Use all stars" :
1180 (m_OpsFocusSettings->focusRingMaskRB->isChecked() ?
QString(
"Ring Mask: [%1%, %2%]").
1181 arg(m_OpsFocusSettings->focusFullFieldInnerRadius->value()).
arg(m_OpsFocusSettings->focusFullFieldOuterRadius->value()) :
1182 QString(
"Mosaic Mask: [%1%, space=%2px]").
1183 arg(m_OpsFocusSettings->focusMosaicTileWidth->value()).
arg(m_OpsFocusSettings->focusMosaicSpace->value())))
1184 <<
" Suspend Guiding:" << ( m_OpsFocusSettings->focusSuspendGuiding->isChecked() ?
"yes" :
"no " )
1185 <<
" Guide Settle:" << m_OpsFocusSettings->focusGuideSettleTime->value()
1186 <<
" Display Units:" << m_OpsFocusSettings->focusUnits->currentText()
1187 <<
" Adaptive Focus:" << ( m_OpsFocusSettings->focusAdaptive->isChecked() ?
"yes" :
"no" )
1188 <<
" Min Move:" << m_OpsFocusSettings->focusAdaptiveMinMove->value()
1189 <<
" Adapt Start:" << ( m_OpsFocusSettings->focusAdaptStart->isChecked() ?
"yes" :
"no" )
1190 <<
" Max Total Move:" << m_OpsFocusSettings->focusAdaptiveMaxMove->value();
1191 qCInfo(KSTARS_EKOS_FOCUS) <<
"Process Tab."
1192 <<
" Detection:" << m_OpsFocusProcess->focusDetection->currentText()
1193 <<
" SEP Profile:" << m_OpsFocusProcess->focusSEPProfile->currentText()
1194 <<
" Algorithm:" << m_OpsFocusProcess->focusAlgorithm->currentText()
1195 <<
" Curve Fit:" << m_OpsFocusProcess->focusCurveFit->currentText()
1196 <<
" Measure:" << m_OpsFocusProcess->focusStarMeasure->currentText()
1197 <<
" PSF:" << m_OpsFocusProcess->focusStarPSF->currentText()
1198 <<
" Use Weights:" << ( m_OpsFocusProcess->focusUseWeights->isChecked() ?
"yes" :
"no" )
1199 <<
" R2 Limit:" << m_OpsFocusProcess->focusR2Limit->value()
1200 <<
" Refine Curve Fit:" << ( m_OpsFocusProcess->focusRefineCurveFit->isChecked() ?
"yes" :
"no" )
1201 <<
" Average Over:" << m_OpsFocusProcess->focusFramesCount->value()
1202 <<
" Average HFR Check Over:" << m_OpsFocusProcess->focusHFRFramesCount->value()
1203 <<
" Num.of Rows:" << m_OpsFocusProcess->focusMultiRowAverage->value()
1204 <<
" Sigma:" << m_OpsFocusProcess->focusGaussianSigma->value()
1205 <<
" Threshold:" << m_OpsFocusProcess->focusThreshold->value()
1206 <<
" Kernel size:" << m_OpsFocusProcess->focusGaussianKernelSize->value()
1207 <<
" Tolerance:" << m_OpsFocusProcess->focusTolerance->value()
1208 <<
" Denoise:" << ( m_OpsFocusProcess->focusDenoise->isChecked() ?
"yes" :
"no" )
1209 <<
" Donut Buster:" << ( m_OpsFocusProcess->focusDonut->isChecked() ?
"yes" :
"no" )
1210 <<
" Donut Time Dilation:" << m_OpsFocusProcess->focusTimeDilation->value()
1211 <<
" Outlier Rejection:" << m_OpsFocusProcess->focusOutlierRejection->value()
1212 <<
" Scan Start Pos:" << ( m_OpsFocusProcess->focusScanStartPos->isChecked() ?
"yes" :
"no" )
1213 <<
" Scan Always On:" << ( m_OpsFocusProcess->focusScanAlwaysOn->isChecked() ?
"yes" :
"no" )
1214 <<
" Num Datapoints:" << m_OpsFocusProcess->focusScanDatapoints->value()
1215 <<
" Scan Step Factor:" << m_OpsFocusProcess->focusScanStepSizeFactor->value();
1216 qCInfo(KSTARS_EKOS_FOCUS) <<
"Mechanics Tab."
1217 <<
" Initial Step Size:" << m_OpsFocusMechanics->focusTicks->value()
1218 <<
" Out Step Multiple:" << m_OpsFocusMechanics->focusOutSteps->value()
1219 <<
" Number Steps:" << m_OpsFocusMechanics->focusNumSteps->value()
1220 <<
" Max Travel:" << m_OpsFocusMechanics->focusMaxTravel->value()
1221 <<
" Max Step Size:" << m_OpsFocusMechanics->focusMaxSingleStep->value()
1222 <<
" Driver Backlash:" << m_OpsFocusMechanics->focusBacklash->value()
1223 <<
" AF Overscan:" << m_OpsFocusMechanics->focusAFOverscan->value()
1224 <<
" Overscan Delay:" << m_OpsFocusMechanics->focusOverscanDelay->value()
1225 <<
" Focuser Settle:" << m_OpsFocusMechanics->focusSettleTime->value()
1226 <<
" Walk:" << m_OpsFocusMechanics->focusWalk->currentText()
1227 <<
" Capture Timeout:" << m_OpsFocusMechanics->focusCaptureTimeout->value()
1228 <<
" Motion Timeout:" << m_OpsFocusMechanics->focusMotionTimeout->value();
1229 qCInfo(KSTARS_EKOS_FOCUS) <<
"CFZ Tab."
1230 <<
" Algorithm:" << m_CFZUI->focusCFZAlgorithm->currentText()
1231 <<
" Tolerance:" << m_CFZUI->focusCFZTolerance->value()
1232 <<
" Tolerance (Ï„):" << m_CFZUI->focusCFZTau->value()
1233 <<
" Display:" << ( m_CFZUI->focusCFZDisplayVCurve->isChecked() ?
"yes" :
"no" )
1234 <<
" Wavelength (λ):" << m_CFZUI->focusCFZWavelength->value()
1235 <<
" Aperture (A):" << m_CFZUI->focusCFZAperture->value()
1236 <<
" Focal Ratio (f):" << m_CFZUI->focusCFZFNumber->value()
1237 <<
" Step Size:" << m_CFZUI->focusCFZStepSize->value()
1238 <<
" FWHM (θ):" << m_CFZUI->focusCFZSeeing->value();
1240 const double temperature = (currentTemperatureSourceElement) ? currentTemperatureSourceElement->value : INVALID_VALUE;
1241 emit autofocusStarting(temperature, filter(), m_AutofocusReason, m_AutofocusReasonInfo);
1243 appendLogText(
i18n(
"Autofocus starting..."));
1248 if (m_GuidingSuspended ==
false && m_OpsFocusSettings->focusSuspendGuiding->isChecked())
1250 m_GuidingSuspended =
true;
1251 emit suspendGuiding();
1255 setState(Ekos::FOCUS_PROGRESS);
1257 KSNotification::event(
QLatin1String(
"FocusStarted"),
i18n(
"Autofocus operation started"), KSNotification::Focus);
1260 if (m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
1262 m_AFfilter = filter();
1263 int position = adaptFocus->adaptStartPosition(currentPosition, m_AFfilter);
1265 curveFitting.reset(
new CurveFitting());
1267 if (m_FocusAlgorithm == FOCUS_LINEAR1PASS)
1270 starFitting.reset(
new CurveFitting());
1271 focusFWHM.reset(
new FocusFWHM(m_ScaleCalc));
1272 focusFourierPower.reset(
new FocusFourierPower(m_ScaleCalc));
1273#if defined(HAVE_OPENCV)
1274 focusBlurriness.reset(
new FocusBlurriness(m_ScaleCalc));
1277 initDonutProcessing();
1279 if (initScanStartPos(
false, currentPosition))
1282 if (m_AutofocusReason == FOCUS_FOCUS_ADVISOR)
1284 focusAdvisor->initControl();
1290 setupLinearFocuser(position);
1291 if (!changeFocus(linearRequestedPosition - currentPosition))
1292 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
1300void Focus::setupLinearFocuser(
int initialPosition)
1302 FocusAlgorithmInterface::FocusParams params(curveFitting.get(),
1303 m_OpsFocusMechanics->focusMaxTravel->value(), m_OpsFocusMechanics->focusTicks->value(), initialPosition, absMotionMin,
1304 absMotionMax, MAXIMUM_ABS_ITERATIONS, m_OpsFocusProcess->focusTolerance->value() / 100.0, m_AFfilter,
1305 currentTemperatureSourceElement ? currentTemperatureSourceElement->value : INVALID_VALUE,
1306 m_OpsFocusMechanics->focusOutSteps->value(), m_OpsFocusMechanics->focusNumSteps->value(),
1307 m_FocusAlgorithm, m_OpsFocusMechanics->focusBacklash->value(), m_CurveFit, m_OpsFocusProcess->focusUseWeights->isChecked(),
1308 m_StarMeasure, m_StarPSF, m_OpsFocusProcess->focusRefineCurveFit->isChecked(), m_FocusWalk,
1309 m_OpsFocusProcess->focusDonut->isChecked(), m_OpsFocusProcess->focusOutlierRejection->value(), m_OptDir, m_ScaleCalc);
1312 initialFocuserAbsPosition = initialPosition;
1313 linearFocuser.reset(MakeLinearFocuser(params));
1314 linearRequestedPosition = linearFocuser->initialPosition();
1318void Focus::initDonutProcessing()
1320 if (!m_OpsFocusProcess->focusDonut->isChecked())
1323 m_donutOrigExposure = focusExposure->value();
1327void Focus::resetDonutProcessing()
1330 if (m_OpsFocusProcess->focusDonut->isChecked() && inAutoFocus)
1331 focusExposure->setValue(m_donutOrigExposure);
1334int Focus::adjustLinearPosition(
int position,
int newPosition,
int overscan,
bool updateDir)
1336 if (overscan > 0 && newPosition > position)
1339 int adjustment = overscan;
1340 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Linear: extending outward movement by overscan %1").
arg(adjustment);
1342 if (newPosition + adjustment > absMotionMax)
1343 adjustment =
static_cast<int>(absMotionMax) - newPosition;
1345 focuserAdditionalMovement = adjustment;
1346 focuserAdditionalMovementUpdateDir = updateDir;
1348 return newPosition + adjustment;
1356void Focus::checkStopFocus(
bool abort)
1358 m_abortInProgress =
true;
1361 resetFocusIteration = MAXIMUM_RESET_ITERATIONS + 1;
1363 if (captureTimer.isActive())
1365 captureTimer.stop();
1367 if (m_captureInProgress)
1369 if (inAutoFocus ==
false && inFocusLoop ==
false)
1371 captureB->setEnabled(
true);
1372 stopFocusB->setEnabled(
false);
1374 appendLogText(
i18n(
"Capture aborted."));
1376 else if (inAutoFocus)
1378 stopFocusB->setEnabled(
false);
1379 appendLogText(
i18n(
"Capture in progress, retrying in 1s..."));
1382 checkStopFocus(abort);
1388 if (m_starDetectInProgress)
1390 stopFocusB->setEnabled(
false);
1391 appendLogText(
i18n(
"Star detection in progress, retrying in 1s..."));
1394 checkStopFocus(abort);
1399 completeFocusProcedure(abort ? Ekos::FOCUS_ABORTED : Ekos::FOCUS_FAILED, Ekos::FOCUS_FAIL_ABORT);
1402void Focus::meridianFlipStarted()
1405 if (state() == FOCUS_IDLE || state() == FOCUS_COMPLETE || state() == FOCUS_FAILED || state() == FOCUS_ABORTED)
1409 int old = resetFocusIteration;
1413 resetFocusIteration = old;
1419 if (state() <= FOCUS_ABORTED)
1423 if (focusAdvisor->inFocusAdvisor())
1425 focusAdvisor->stop();
1431void Focus::processAbort()
1433 bool focusLoop = inFocusLoop;
1434 checkStopFocus(
true);
1435 appendLogText(
i18n(
"Autofocus aborted."));
1442void Focus::stop(Ekos::FocusState completionState)
1444 Q_UNUSED(completionState);
1445 qCDebug(KSTARS_EKOS_FOCUS) <<
"Stopping Focus";
1447 captureTimeout.stop();
1448 m_FocusMotionTimer.stop();
1449 m_FocusMotionTimerCounter = 0;
1450 m_FocuserReconnectCounter = 0;
1452 opticalTrainCombo->setEnabled(
true);
1453 resetDonutProcessing();
1454 inAutoFocus =
false;
1455 inAdjustFocus =
false;
1456 adaptFocus->setInAdaptiveFocus(
false);
1457 inBuildOffsets =
false;
1458 inScanStartPos =
false;
1459 focusAdvisor->reset();
1460 m_AutofocusReason = AutofocusReason::FOCUS_NONE;
1461 m_AutofocusReasonInfo =
"";
1462 focuserAdditionalMovement = 0;
1463 focuserAdditionalMovementUpdateDir =
true;
1464 inFocusLoop =
false;
1465 m_captureInProgress =
false;
1466 m_abortInProgress =
false;
1467 m_starDetectInProgress =
false;
1468 isVShapeSolution =
false;
1469 captureFailureCounter = 0;
1470 minimumRequiredHFR = INVALID_STAR_MEASURE;
1472 starMeasureFrames.clear();
1481 disconnect(m_Camera, &ISD::Camera::error,
this, &Ekos::Focus::processCaptureError);
1483 if (rememberUploadMode != m_Camera->getUploadMode())
1484 m_Camera->setUploadMode(rememberUploadMode);
1487 if (m_RememberCameraFastExposure)
1489 m_RememberCameraFastExposure =
false;
1490 m_Camera->setFastExposureEnabled(
true);
1493 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
1494 targetChip->abortExposure();
1503 if (m_GuidingSuspended)
1505 emit resumeGuiding();
1506 m_GuidingSuspended =
false;
1510void Focus::capture(
double settleTime)
1512 if (m_abortInProgress)
1515 m_captureInProgress =
false;
1516 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding capture request.";
1522 if (settleTime > 0 && m_captureInProgress ==
false)
1524 captureTimer.start(
static_cast<int>(settleTime * 1000));
1528 if (m_captureInProgress)
1530 qCWarning(KSTARS_EKOS_FOCUS) <<
"Capture called while already in progress. Capture is ignored.";
1534 if (m_Camera ==
nullptr)
1536 appendLogText(
i18n(
"Error: No Camera detected."));
1537 checkStopFocus(
true);
1541 if (m_Camera->isConnected() ==
false)
1543 appendLogText(
i18n(
"Error: Lost connection to Camera."));
1544 checkStopFocus(
true);
1549 captureTimeout.stop();
1551 waitStarSelectTimer.stop();
1553 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
1555 if (m_Camera->isBLOBEnabled() ==
false)
1557 m_Camera->setBLOBEnabled(
true);
1560 if (focusFilter->currentIndex() != -1)
1562 if (m_FilterWheel ==
nullptr)
1564 appendLogText(
i18n(
"Error: No Filter Wheel detected."));
1565 checkStopFocus(
true);
1568 if (m_FilterWheel->isConnected() ==
false)
1570 appendLogText(
i18n(
"Error: Lost connection to Filter Wheel."));
1571 checkStopFocus(
true);
1578 int targetPosition = focusFilter->currentIndex() + 1;
1579 if (!inBuildOffsets)
1581 QString lockedFilter = m_FilterManager->getFilterLock(filter());
1586 if (lockedFilter !=
"--" && lockedFilter != filter())
1588 int lockedFilterIndex = focusFilter->findText(lockedFilter);
1589 if (lockedFilterIndex >= 0)
1592 fallbackFilterPending =
true;
1593 fallbackFilterPosition = targetPosition;
1594 targetPosition = lockedFilterIndex + 1;
1599 filterPositionPending = (targetPosition != currentFilterPosition);
1600 if (filterPositionPending)
1605 FilterManager::FilterPolicy policy = (inAutoFocus) ?
1606 static_cast<FilterManager::FilterPolicy
>(FilterManager::CHANGE_POLICY) :
1607 static_cast<FilterManager::FilterPolicy
>(FilterManager::CHANGE_POLICY | FilterManager::OFFSET_POLICY);
1608 m_FilterManager->setFilterPosition(targetPosition, policy);
1611 else if (targetPosition != focusFilter->currentIndex() + 1)
1612 focusFilter->setCurrentIndex(targetPosition - 1);
1615 m_FocusView->setProperty(
"suspended", m_OpsFocusSettings->useFocusDarkFrame->isChecked());
1616 prepareCapture(targetChip);
1619 connect(m_Camera, &ISD::Camera::error,
this, &Ekos::Focus::processCaptureError,
Qt::UniqueConnection);
1621 if (frameSettings.contains(targetChip))
1623 QVariantMap settings = frameSettings[targetChip];
1624 targetChip->setFrame(settings[
"x"].toInt(), settings[
"y"].toInt(), settings[
"w"].toInt(),
1625 settings[
"h"].toInt());
1626 settings[
"binx"] = (focusBinning->currentIndex() + 1);
1627 settings[
"biny"] = (focusBinning->currentIndex() + 1);
1628 frameSettings[targetChip] = settings;
1631 m_captureInProgress =
true;
1632 if (state() != FOCUS_PROGRESS)
1633 setState(FOCUS_PROGRESS);
1635 m_FocusView->setBaseSize(focusingWidget->size());
1637 if (targetChip->capture(focusExposure->value()))
1641 captureTimeout.start( (focusExposure->value() + m_OpsFocusMechanics->focusCaptureTimeout->value()) * 1000);
1643 if (inFocusLoop ==
false)
1644 appendLogText(
i18n(
"Capturing image..."));
1648 else if (inAutoFocus)
1650 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
1656 if (m_Camera->getUploadMode() == ISD::Camera::UPLOAD_LOCAL)
1658 rememberUploadMode = ISD::Camera::UPLOAD_LOCAL;
1659 m_Camera->setUploadMode(ISD::Camera::UPLOAD_CLIENT);
1663 if (m_Camera->isFastExposureEnabled())
1665 m_RememberCameraFastExposure =
true;
1666 m_Camera->setFastExposureEnabled(
false);
1669 m_Camera->setEncodingFormat(
"FITS");
1670 targetChip->setBatchMode(
false);
1671 targetChip->setBinning((focusBinning->currentIndex() + 1), (focusBinning->currentIndex() + 1));
1672 targetChip->setCaptureMode(FITS_FOCUS);
1673 targetChip->setFrameType(FRAME_LIGHT);
1674 targetChip->setCaptureFilter(FITS_NONE);
1676 if (isFocusISOEnabled() && focusISO->currentIndex() != -1 &&
1677 targetChip->getISOIndex() != focusISO->currentIndex())
1678 targetChip->setISOIndex(focusISO->currentIndex());
1680 if (isFocusGainEnabled() && focusGain->value() != GainSpinSpecialValue)
1681 m_Camera->setGain(focusGain->value());
1684bool Focus::focusIn(
int ms)
1686 if (currentPosition == absMotionMin)
1688 appendLogText(
i18n(
"At minimum focus position %1...", absMotionMin));
1691 focusInB->setEnabled(
false);
1692 focusOutB->setEnabled(
false);
1693 startGotoB->setEnabled(
false);
1695 ms = m_OpsFocusMechanics->focusTicks->value();
1696 if (currentPosition - ms <= absMotionMin)
1698 ms = currentPosition - absMotionMin;
1699 appendLogText(
i18n(
"Moving to minimum focus position %1...", absMotionMin));
1701 return changeFocus(-ms);
1704bool Focus::focusOut(
int ms)
1706 if (currentPosition == absMotionMax)
1708 appendLogText(
i18n(
"At maximum focus position %1...", absMotionMax));
1711 focusInB->setEnabled(
false);
1712 focusOutB->setEnabled(
false);
1713 startGotoB->setEnabled(
false);
1715 ms = m_OpsFocusMechanics->focusTicks->value();
1716 if (currentPosition + ms >= absMotionMax)
1718 ms = absMotionMax - currentPosition;
1719 appendLogText(
i18n(
"Moving to maximum focus position %1...", absMotionMax));
1721 return changeFocus(ms);
1726bool Focus::changeFocus(
int amount,
bool updateDir)
1730 if (inAutoFocus && abs(amount) <= 1)
1732 if (m_RestartState == RESTART_NOW)
1739 capture(m_OpsFocusMechanics->focusSettleTime->value());
1744 if (m_Focuser ==
nullptr)
1746 appendLogText(
i18n(
"Error: No Focuser detected."));
1747 checkStopFocus(
true);
1751 if (m_Focuser->isConnected() ==
false)
1753 appendLogText(
i18n(
"Error: Lost connection to Focuser."));
1754 checkStopFocus(
true);
1758 const int newPosition = adjustLinearPosition(currentPosition, currentPosition + amount,
1759 m_OpsFocusMechanics->focusAFOverscan->value(),
1761 if (newPosition == currentPosition)
1764 const int newAmount = newPosition - currentPosition;
1765 const int absNewAmount = abs(newAmount);
1766 const bool focusingOut = newAmount > 0;
1767 const QString dirStr = focusingOut ?
i18n(
"outward") :
i18n(
"inward");
1770 m_LastFocusDirection = (focusingOut) ? FOCUS_OUT : FOCUS_IN;
1773 m_Focuser->focusOut();
1775 m_Focuser->focusIn();
1778 m_FocusMotionTimer.start();
1782 m_LastFocusSteps = newPosition;
1783 m_Focuser->moveAbs(newPosition);
1784 appendLogText(
i18n(
"Focusing %2 by %1 steps...", abs(absNewAmount), dirStr));
1786 else if (canRelMove)
1788 m_LastFocusSteps = absNewAmount;
1789 m_Focuser->moveRel(absNewAmount);
1790 appendLogText(
i18np(
"Focusing %2 by %1 step...",
"Focusing %2 by %1 steps...", absNewAmount, dirStr));
1794 m_LastFocusSteps = absNewAmount;
1795 m_Focuser->moveByTimer(absNewAmount);
1796 appendLogText(
i18n(
"Focusing %2 by %1 ms...", absNewAmount, dirStr));
1802void Focus::handleFocusMotionTimeout()
1822 qCDebug(KSTARS_EKOS_FOCUS) <<
"handleFocusMotionTimeout() called while not in AutoFocus";
1826 m_FocusMotionTimerCounter++;
1828 if (m_FocusMotionTimerCounter > 4)
1831 appendLogText(
i18n(
"Focuser is still timing out. Aborting..."));
1832 stop(Ekos::FOCUS_ABORTED);
1835 else if (m_FocusMotionTimerCounter > 2)
1837 QString focuser = m_Focuser->getDeviceName();
1838 appendLogText(
i18n(
"Focus motion timed out (%1). Restarting focus driver %2", m_FocusMotionTimerCounter, focuser));
1839 emit focuserTimedout(focuser);
1843 Focus::reconnectFocuser(focuser);
1848 if (!changeFocus(m_LastFocusSteps - currentPosition))
1849 appendLogText(
i18n(
"Focus motion timed out (%1). Focusing to %2 steps...", m_FocusMotionTimerCounter, m_LastFocusSteps));
1852void Focus::selectImageMask()
1854 const bool useFullField = m_OpsFocusSettings->focusUseFullField->isChecked();
1855 ImageMaskType masktype;
1856 if (m_OpsFocusSettings->focusRingMaskRB->isChecked())
1857 masktype = FOCUS_MASK_RING;
1858 else if (m_OpsFocusSettings->focusMosaicMaskRB->isChecked())
1859 masktype = FOCUS_MASK_MOSAIC;
1861 masktype = FOCUS_MASK_NONE;
1864 m_OpsFocusSettings->focusRingMaskRB->setEnabled(useFullField);
1865 m_OpsFocusSettings->focusMosaicMaskRB->setEnabled(useFullField);
1867 m_OpsFocusSettings->focusFullFieldInnerRadius->setEnabled(useFullField && masktype == FOCUS_MASK_RING);
1868 m_OpsFocusSettings->focusFullFieldOuterRadius->setEnabled(useFullField && masktype == FOCUS_MASK_RING);
1870 m_OpsFocusSettings->focusMosaicTileWidth->setEnabled(useFullField && masktype == FOCUS_MASK_MOSAIC);
1871 m_OpsFocusSettings->focusSpacerLabel->setEnabled(useFullField && masktype == FOCUS_MASK_MOSAIC);
1872 m_OpsFocusSettings->focusMosaicSpace->setEnabled(useFullField && masktype == FOCUS_MASK_MOSAIC);
1875 if (masktype == FOCUS_MASK_RING)
1876 m_FocusView->setImageMask(
new ImageRingMask(m_OpsFocusSettings->focusFullFieldInnerRadius->value() / 100.0,
1877 m_OpsFocusSettings->focusFullFieldOuterRadius->value() / 100.0));
1878 else if (masktype == FOCUS_MASK_MOSAIC)
1879 m_FocusView->setImageMask(
new ImageMosaicMask(m_OpsFocusSettings->focusMosaicTileWidth->value(),
1880 m_OpsFocusSettings->focusMosaicSpace->value()));
1882 m_FocusView->setImageMask(
nullptr);
1884 checkMosaicMaskLimits();
1885 m_currentImageMask = masktype;
1886 startAbInsB->setEnabled(canAbInsStart());
1889void Focus::reconnectFocuser(
const QString &focuser)
1891 m_FocuserReconnectCounter++;
1893 if (m_Focuser && m_Focuser->getDeviceName() == focuser)
1895 appendLogText(
i18n(
"Attempting to reconnect focuser: %1", focuser));
1896 refreshOpticalTrain();
1897 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_ERROR);
1901 if (m_FocuserReconnectCounter > 12)
1904 appendLogText(
i18n(
"Cannot reconnect focuser: %1. Aborting...", focuser));
1905 stop(Ekos::FOCUS_ABORTED);
1911 reconnectFocuser(focuser);
1918 if (data->property(
"chip").toInt() == ISD::CameraChip::GUIDE_CCD)
1923 m_FocusView->loadData(data);
1927 m_ImageData.reset();
1929 captureTimeout.stop();
1930 captureTimeoutCounter = 0;
1931 m_MissingCameraCounter = 0;
1933 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
1935 disconnect(m_Camera, &ISD::Camera::error,
this, &Ekos::Focus::processCaptureError);
1937 if (m_ImageData && m_OpsFocusSettings->useFocusDarkFrame->isChecked())
1939 QVariantMap settings = frameSettings[targetChip];
1940 uint16_t offsetX = settings[
"x"].toInt() / settings[
"binx"].toInt();
1941 uint16_t offsetY = settings[
"y"].toInt() / settings[
"biny"].toInt();
1943 m_DarkProcessor->denoise(OpticalTrainManager::Instance()->
id(opticalTrainCombo->currentText()),
1944 targetChip, m_ImageData, focusExposure->value(), offsetX, offsetY);
1948 setCaptureComplete();
1952void Focus::starDetectionFinished()
1954 m_starDetectInProgress =
false;
1955 if (m_abortInProgress)
1958 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding results from " << __FUNCTION__;
1962 appendLogText(
i18n(
"Detection complete."));
1965 double hfr = INVALID_STAR_MEASURE;
1967 if (isStarMeasureStarBased())
1969 appendLogText(
i18n(
"Detection complete."));
1971 if (m_StarFinderWatcher.result() ==
false)
1973 qCWarning(KSTARS_EKOS_FOCUS) <<
"Failed to extract any stars.";
1977 if (m_OpsFocusSettings->focusUseFullField->isChecked())
1979 m_FocusView->filterStars();
1982 hfr = m_ImageData->getHFR(m_StarMeasure == FOCUS_STAR_HFR_ADJ ? HFR_ADJ_AVERAGE : HFR_AVERAGE);
1986 m_FocusView->setTrackingBoxEnabled(
true);
1991 if (starCenter.isNull() ==
false)
1992 hfr = m_ImageData->getHFR(starCenter.x(), starCenter.y());
1996 hfr = m_ImageData->getHFR(m_FocusDetection == ALGORITHM_SEP ? HFR_HIGH : HFR_MAX);
2002 currentNumStars = m_ImageData->getDetectedStars();
2006 currentMeasure = currentHFR;
2009 if (m_StarMeasure == FOCUS_STAR_NUM_STARS)
2011 currentMeasure = currentNumStars;
2012 currentWeight = 1.0;
2014 else if (m_StarMeasure == FOCUS_STAR_FWHM)
2016 getFWHM(m_ImageData->getStarCenters(), ¤tFWHM, ¤tWeight);
2017 currentMeasure = currentFWHM;
2019 else if (m_StarMeasure == FOCUS_STAR_FOURIER_POWER)
2021 getFourierPower(¤tFourierPower, ¤tWeight);
2022 currentMeasure = currentFourierPower;
2024 else if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
2025 m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
2028 if (m_OpsFocusSettings->focusSubFrame->isChecked())
2029 roi = m_FocusView->isTrackingBoxEnabled() ? m_FocusView->getTrackingBox() :
QRect();
2030 getBlurriness(m_StarMeasure, m_OpsFocusProcess->focusDenoise->isChecked(), ¤tBlurriness, ¤tWeight, roi);
2031 currentMeasure = currentBlurriness;
2035 currentMeasure = currentHFR;
2037 std::vector<double> hfrs(stars.
size());
2042 currentWeight = calculateStarWeight(m_OpsFocusProcess->focusUseWeights->isChecked(), hfrs);
2045 setCurrentMeasure();
2051bool Focus::isStarMeasureStarBased()
2053 if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL || m_StarMeasure == FOCUS_STAR_LAPLASSIAN
2054 || m_StarMeasure == FOCUS_STAR_CANNY)
2060void Focus::getFWHM(
const QList<Edge *> &stars,
double *FWHM,
double *weight)
2062 *FWHM = INVALID_STAR_MEASURE;
2065 auto imageBuffer = m_ImageData->getImageBuffer();
2067 switch (m_ImageData->getStatistics().dataType)
2070 focusFWHM->processFWHM(
reinterpret_cast<uint8_t
const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2074 focusFWHM->processFWHM(
reinterpret_cast<short const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2078 focusFWHM->processFWHM(
reinterpret_cast<unsigned short const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM,
2083 focusFWHM->processFWHM(
reinterpret_cast<long const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2087 focusFWHM->processFWHM(
reinterpret_cast<unsigned long const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2091 focusFWHM->processFWHM(
reinterpret_cast<float const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2095 focusFWHM->processFWHM(
reinterpret_cast<long long const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2099 focusFWHM->processFWHM(
reinterpret_cast<double const *
>(imageBuffer), stars, m_ImageData, starFitting, FWHM, weight);
2103 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unknown image buffer datatype " << m_ImageData->getStatistics().dataType <<
2104 " Cannot calc FWHM";
2110void Focus::getFourierPower(
double *fourierPower,
double *weight,
const int mosaicTile)
2112 *fourierPower = INVALID_STAR_MEASURE;
2115 auto imageBuffer = m_ImageData->getImageBuffer();
2117 switch (m_ImageData->getStatistics().dataType)
2120 focusFourierPower->processFourierPower(
reinterpret_cast<uint8_t
const *
>(imageBuffer), m_ImageData,
2121 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2125 focusFourierPower->processFourierPower(
reinterpret_cast<short const *
>(imageBuffer), m_ImageData,
2126 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2130 focusFourierPower->processFourierPower(
reinterpret_cast<unsigned short const *
>(imageBuffer), m_ImageData,
2131 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2135 focusFourierPower->processFourierPower(
reinterpret_cast<long const *
>(imageBuffer), m_ImageData,
2136 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2140 focusFourierPower->processFourierPower(
reinterpret_cast<unsigned long const *
>(imageBuffer), m_ImageData,
2141 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2145 focusFourierPower->processFourierPower(
reinterpret_cast<float const *
>(imageBuffer), m_ImageData,
2146 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2150 focusFourierPower->processFourierPower(
reinterpret_cast<long long const *
>(imageBuffer), m_ImageData,
2151 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2155 focusFourierPower->processFourierPower(
reinterpret_cast<double const *
>(imageBuffer), m_ImageData,
2156 m_FocusView->imageMask(), mosaicTile, fourierPower, weight);
2160 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unknown image buffer datatype " << m_ImageData->getStatistics().dataType <<
2161 " Cannot calc Fourier Power";
2167void Focus::getBlurriness(
const StarMeasure starMeasure,
const bool denoise,
double *blurriness,
double *weight,
2168 const QRect &roi,
const int mosaicTile)
2170 *blurriness = INVALID_STAR_MEASURE;
2173#if defined(HAVE_OPENCV)
2175 auto imageBuffer = m_ImageData->getImageBuffer();
2177 switch (m_ImageData->getStatistics().dataType)
2180 focusBlurriness->processBlurriness(
reinterpret_cast<uint8_t
const *
>(imageBuffer), m_ImageData, denoise,
2181 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2185 focusBlurriness->processBlurriness(
reinterpret_cast<short const *
>(imageBuffer), m_ImageData, denoise,
2186 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2190 focusBlurriness->processBlurriness(
reinterpret_cast<unsigned short const *
>(imageBuffer), m_ImageData, denoise,
2191 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2195 focusBlurriness->processBlurriness(
reinterpret_cast<long const *
>(imageBuffer), m_ImageData, denoise,
2196 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2200 focusBlurriness->processBlurriness(
reinterpret_cast<unsigned long const *
>(imageBuffer), m_ImageData, denoise,
2201 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2205 focusBlurriness->processBlurriness(
reinterpret_cast<float const *
>(imageBuffer), m_ImageData, denoise,
2206 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2210 focusBlurriness->processBlurriness(
reinterpret_cast<long long const *
>(imageBuffer), m_ImageData, denoise,
2211 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2215 focusBlurriness->processBlurriness(
reinterpret_cast<double const *
>(imageBuffer), m_ImageData, denoise,
2216 m_FocusView->imageMask(), mosaicTile, roi, starMeasure, blurriness, weight);
2220 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unknown image buffer datatype " << m_ImageData->getStatistics().dataType <<
2221 " Cannot calc Blurriness";
2225 Q_UNUSED(starMeasure);
2228 Q_UNUSED(mosaicTile);
2230 qCDebug(KSTARS_EKOS_FOCUS) <<
"getBlurriness called when openCV not installed";
2234double Focus::calculateStarWeight(
const bool useWeights,
const std::vector<double> values)
2236 if (!useWeights || values.size() <= 0)
2241 return Mathematics::RobustStatistics::ComputeWeight(m_ScaleCalc, values);
2244void Focus::analyzeSources()
2246 appendLogText(
i18n(
"Detecting sources..."));
2247 m_starDetectInProgress =
true;
2249 QVariantMap extractionSettings;
2250 extractionSettings[
"optionsProfileIndex"] = m_OpsFocusProcess->focusSEPProfile->currentIndex();
2251 extractionSettings[
"optionsProfileGroup"] =
static_cast<int>(Ekos::FocusProfiles);
2252 m_ImageData->setSourceExtractorSettings(extractionSettings);
2256 if (m_OpsFocusSettings->focusUseFullField->isChecked())
2258 m_FocusView->setTrackingBoxEnabled(
false);
2260 if (m_FocusDetection != ALGORITHM_CENTROID && m_FocusDetection != ALGORITHM_SEP)
2261 m_StarFinderWatcher.setFuture(m_ImageData->findStars(ALGORITHM_CENTROID));
2263 m_StarFinderWatcher.setFuture(m_ImageData->findStars(m_FocusDetection));
2267 QRect searchBox = m_FocusView->isTrackingBoxEnabled() ? m_FocusView->getTrackingBox() :
QRect();
2271 m_StarFinderWatcher.setFuture(m_ImageData->findStars(m_FocusDetection, searchBox));
2276 m_FocusView->setTrackingBoxEnabled(
false);
2280 if (m_FocusDetection != ALGORITHM_CENTROID && m_FocusDetection != ALGORITHM_SEP)
2281 m_StarFinderWatcher.setFuture(m_ImageData->findStars(ALGORITHM_CENTROID));
2284 m_StarFinderWatcher.setFuture(m_ImageData->findStars(m_FocusDetection, searchBox));
2289bool Focus::appendMeasure(
double newMeasure)
2292 starMeasureFrames.append(newMeasure);
2295 QVector <double> samples(starMeasureFrames);
2296 samples.erase(std::remove_if(samples.begin(), samples.end(), [](
const double measure)
2298 return measure == INVALID_STAR_MEASURE;
2302 if (!samples.isEmpty())
2304 currentMeasure = Mathematics::RobustStatistics::ComputeLocation(
2305 Mathematics::RobustStatistics::LOCATION_SIGMACLIPPING, std::vector<double>(samples.begin(), samples.end()));
2307 switch(m_StarMeasure)
2309 case FOCUS_STAR_HFR:
2310 case FOCUS_STAR_HFR_ADJ:
2311 currentHFR = currentMeasure;
2313 case FOCUS_STAR_FWHM:
2314 currentFWHM = currentMeasure;
2316 case FOCUS_STAR_NUM_STARS:
2317 currentNumStars = currentMeasure;
2319 case FOCUS_STAR_FOURIER_POWER:
2320 currentFourierPower = currentMeasure;
2322 case FOCUS_STAR_STDDEV:
2323 case FOCUS_STAR_SOBEL:
2324 case FOCUS_STAR_LAPLASSIAN:
2325 case FOCUS_STAR_CANNY:
2326 currentBlurriness = currentMeasure;
2337 int framesCount = m_OpsFocusProcess->focusFramesCount->value();
2338 if ((minimumRequiredHFR > 0) || (inAutoFocus && !inBuildOffsets && !inScanStartPos && !focusAdvisor->inFocusAdvisor()
2339 && m_FocusAlgorithm == FOCUS_LINEAR1PASS
2340 && linearFocuser && !linearFocuser->isInFirstPass()))
2342 framesCount = m_OpsFocusProcess->focusHFRFramesCount->value();
2344 return starMeasureFrames.count() < framesCount;
2347void Focus::settle(
const FocusState completionState,
const bool autoFocusUsed,
const bool buildOffsetsUsed,
2348 const AutofocusFailReason failCode,
const QString failCodeInfo)
2352 if (completionState == Ekos::FOCUS_COMPLETE)
2354 if (failCode != FOCUS_FAIL_ADVISOR_COMPLETE)
2355 KSNotification::event(
QLatin1String(
"FocusSuccessful"),
i18n(
"Autofocus operation completed successfully"),
2356 KSNotification::Focus);
2358 if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && curveFitting !=
nullptr)
2359 emit autofocusComplete(m_LastSourceAutofocusTemperature,
filter(), getAnalyzeData(),
2360 m_OpsFocusProcess->focusUseWeights->isChecked(),
2361 curveFitting->serialize(), linearFocuser->getTextStatus(R2));
2363 emit autofocusComplete(m_LastSourceAutofocusTemperature,
filter(), getAnalyzeData(),
2364 m_OpsFocusProcess->focusUseWeights->isChecked());
2368 if (failCode != FOCUS_FAIL_ADVISOR_COMPLETE)
2369 KSNotification::event(
QLatin1String(
"FocusFailed"),
i18n(
"Autofocus operation failed"),
2370 KSNotification::Focus, KSNotification::Alert);
2371 emit autofocusAborted(
filter(), getAnalyzeData(), m_OpsFocusProcess->focusUseWeights->isChecked(), failCode, failCodeInfo);
2375 if (completionState == Ekos::FOCUS_COMPLETE)
2377 if (autoFocusUsed && fallbackFilterPending)
2382 m_FilterManager->setFilterAbsoluteFocusDetails(focusFilter->currentIndex(), currentPosition,
2383 m_LastSourceAutofocusTemperature, m_LastSourceAutofocusAlt);
2388 if (fallbackFilterPending)
2390 m_pendingState = completionState;
2391 FilterManager::FilterPolicy policy =
static_cast<FilterManager::FilterPolicy
>(FilterManager::CHANGE_POLICY |
2392 FilterManager::OFFSET_POLICY);
2393 m_FilterManager->setFilterPosition(fallbackFilterPosition, policy);
2396 setState(completionState);
2398 if (autoFocusUsed && buildOffsetsUsed)
2400 m_FilterManager->autoFocusComplete(completionState, currentPosition, m_LastSourceAutofocusTemperature,
2401 m_LastSourceAutofocusAlt);
2406QString Focus::getAnalyzeData()
2408 QString analysis_results =
"";
2410 for (
int i = 0; i < plot_position.size(); ++i)
2413 .arg(i == 0 ?
"" :
"|" )
2419 return analysis_results;
2422void Focus::completeFocusProcedure(FocusState completionState, AutofocusFailReason failCode,
QString failCodeInfo,
2426 if (inAutoFocus && failCode != Ekos::FOCUS_FAIL_ADVISOR_COMPLETE)
2429 updatePlotPosition();
2431 if (completionState == Ekos::FOCUS_COMPLETE)
2435 emit redrawHFRPlot(polynomialFit.get(), currentPosition, currentHFR);
2437 appendLogText(
i18np(
"Focus procedure completed after %1 iteration.",
2438 "Focus procedure completed after %1 iterations.", plot_position.count()));
2440 setLastFocusTemperature();
2442 resetAdaptiveFocus(m_OpsFocusSettings->focusAdaptive->isChecked());
2446 qCInfo(KSTARS_EKOS_FOCUS) <<
"Autofocus values: position," << currentPosition <<
", temperature,"
2447 << m_LastSourceAutofocusTemperature <<
", filter," <<
filter()
2448 <<
", HFR," << currentHFR <<
", altitude," << m_LastSourceAutofocusAlt;
2450 if (m_FocusAlgorithm == FOCUS_POLYNOMIAL)
2453 plot_position.append(currentPosition);
2454 plot_value.append(currentHFR);
2455 plot_weight.append(1.0);
2456 plot_outlier.append(
false);
2459 appendFocusLogText(
QString(
"%1, %2, %3, %4, %5\n")
2466 absTicksSpin->setValue(currentPosition);
2469 else if (canAbsMove && initialFocuserAbsPosition >= 0 && resetFocusIteration <= MAXIMUM_RESET_ITERATIONS &&
2470 m_RestartState != RESTART_ABORT)
2473 bool const retry_focusing = m_RestartState == RESTART_NONE &&
2474 (failCode == Ekos::FOCUS_FAIL_ADVISOR_RERUN || ++resetFocusIteration < MAXIMUM_RESET_ITERATIONS);
2479 m_RestartState = RESTART_NOW;
2488 emit autofocusAborted(
filter(), getAnalyzeData(), m_OpsFocusProcess->focusUseWeights->isChecked(), failCode, failCodeInfo);
2500 m_RestartState = RESTART_ABORT;
2506 resetFocusIteration = 0;
2509 const bool autoFocusUsed = inAutoFocus;
2510 const bool inBuildOffsetsUsed = inBuildOffsets;
2513 if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && plot)
2514 emit drawPolynomial(polynomialFit.get(), isVShapeSolution,
true);
2517 int const settleTime = m_GuidingSuspended ? m_OpsFocusSettings->focusGuideSettleTime->value() : 0;
2520 stop(completionState);
2523 appendLogText(
i18n(
"Settling for %1s...", settleTime));
2525 QTimer::singleShot(settleTime * 1000,
this, [ &, settleTime, completionState, autoFocusUsed, inBuildOffsetsUsed, failCode,
2528 settle(completionState, autoFocusUsed, inBuildOffsetsUsed, failCode, failCodeInfo);
2531 appendLogText(
i18n(
"Settling complete."));
2535void Focus::resetFocuser()
2538 if (m_Focuser && m_Focuser->isConnected() && initialFocuserAbsPosition >= 0)
2541 if (currentPosition == initialFocuserAbsPosition)
2544 appendLogText(
i18n(
"Autofocus failed, moving back to initial focus position %1.", initialFocuserAbsPosition));
2545 changeFocus(initialFocuserAbsPosition - currentPosition);
2550void Focus::setCurrentMeasure()
2553 qCDebug(KSTARS_EKOS_FOCUS) <<
"Focus newFITS #" << starMeasureFrames.count() + 1 <<
": Current HFR " << currentHFR <<
2555 << (starSelected ? 1 : currentNumStars);
2558 if (appendMeasure(currentMeasure))
2563 else starMeasureFrames.clear();
2568 emit newHFR(currentHFR, currentPosition, inAutoFocus, opticalTrain());
2570 emit newHFR(currentHFR, -1, inAutoFocus, opticalTrain());
2573 HFROut->setText(
QString(
"%1").arg(currentHFR * getStarUnits(m_StarMeasure, m_StarUnits), 0,
'f', 2));
2574 if (m_StarMeasure == FOCUS_STAR_FWHM)
2575 FWHMOut->setText(
QString(
"%1").arg(currentFWHM * getStarUnits(m_StarMeasure, m_StarUnits), 0,
'f', 2));
2576 starsOut->setText(
QString(
"%1").arg(m_ImageData->getDetectedStars()));
2577 iterOut->setText(
QString(
"%1").arg(absIterations + 1));
2580 if (lastHFR == INVALID_STAR_MEASURE)
2581 appendLogText(
i18n(
"FITS received. No stars detected."));
2587 if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && isVShapeSolution)
2589 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
2593 Edge selectedHFRStarHFR = m_ImageData->getSelectedHFRStar();
2600 if (starCenter.isNull() ==
false && (inAutoFocus || minimumRequiredHFR >= 0))
2603 starSelected =
true;
2604 starCenter.setX(qMax(0,
static_cast<int>(selectedHFRStarHFR.x)));
2605 starCenter.setY(qMax(0,
static_cast<int>(selectedHFRStarHFR.y)));
2607 syncTrackingBoxPosition();
2611 oneStar.
setZ(currentHFR);
2612 starsHFR.append(oneStar);
2617 QVector3D oneStar(starCenter.x(), starCenter.y(), currentHFR);
2618 starsHFR.append(oneStar);
2621 if (currentHFR > maxHFR)
2622 maxHFR = currentHFR;
2630 if (inFocusLoop || (inAutoFocus && ! isPositionBased()))
2632 int pos = plot_position.empty() ? 1 : plot_position.last() + 1;
2633 addPlotPosition(pos, currentHFR);
2639 QVector3D oneStar(starCenter.x(), starCenter.y(), INVALID_STAR_MEASURE);
2640 starsHFR.append(oneStar);
2645 m_FocusView->updateFrame();
2649 if (m_abInsOn && !inScanStartPos && !focusAdvisor->inFocusAdvisor())
2650 calculateAbInsData();
2654void Focus::saveFocusFrame()
2656 if (inAutoFocus && Options::focusLogging() && Options::saveFocusImages())
2667 if (focusAdvisor->inFocusAdvisor())
2668 prefix = focusAdvisor->getFocusFramePrefix();
2669 else if (inScanStartPos)
2670 prefix =
QString(
"_ssp_%1_%2").
arg(m_AFRun).
arg(absIterations + 1);
2671 else if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && linearFocuser)
2673 const int currentStep = linearFocuser->currentStep() + 1;
2679 prefix.
append(
QString(
"_%1").arg(starMeasureFrames.count()));
2685 m_ImageData->saveImage(filename);
2689void Focus::calculateAbInsData()
2691 ImageMosaicMask *mosaicmask =
dynamic_cast<ImageMosaicMask *
>(m_FocusView->imageMask().
get());
2693 auto stars = m_ImageData->getStarCenters();
2696 for (
int star = 0; star < stars.
count(); star++)
2698 const int x = stars[star]->x;
2699 const int y = stars[star]->y;
2700 for (
int tile = 0; tile < NUM_TILES; tile++)
2702 QRect thisTile = tiles[tile];
2705 tileStars[tile].append(stars[star]);
2712 for (
int tile = 0; tile < tileStars.count(); tile++)
2714 double measure, weight;
2715 std::vector<double> HFRs;
2717 switch (m_StarMeasure)
2719 case FOCUS_STAR_HFR:
2720 case FOCUS_STAR_HFR_ADJ:
2721 for (
int star = 0; star < tileStars[tile].count(); star++)
2723 HFRs.push_back(tileStars[tile][star]->HFR);
2725 measure = Mathematics::RobustStatistics::ComputeLocation(Mathematics::RobustStatistics::LOCATION_SIGMACLIPPING, HFRs, 2);
2726 weight = calculateStarWeight(m_OpsFocusProcess->focusUseWeights->isChecked(), HFRs);
2728 case FOCUS_STAR_FWHM:
2729 getFWHM(tileStars[tile], &measure, &weight);
2731 case FOCUS_STAR_NUM_STARS:
2732 measure = tileStars[tile].count();
2735 case FOCUS_STAR_FOURIER_POWER:
2736 getFourierPower(&measure, &weight, tile);
2738 case FOCUS_STAR_STDDEV:
2739 case FOCUS_STAR_SOBEL:
2740 case FOCUS_STAR_LAPLASSIAN:
2741 case FOCUS_STAR_CANNY:
2742 getBlurriness(m_StarMeasure, m_OpsFocusProcess->focusDenoise->isChecked(), &measure, &weight,
QRect(), tile);
2745 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unable to calculate Aberration Inspector data";
2749 m_abInsMeasure[tile].append(measure);
2750 m_abInsWeight[tile].append(weight);
2751 m_abInsNumStars[tile].append(tileStars[tile].count());
2753 if (!linearFocuser->isInFirstPass())
2758 int xAv = 0, yAv = 0;
2759 if (m_StarMeasure != FOCUS_STAR_FOURIER_POWER)
2761 QPoint tileCenter = tiles[tile].center();
2762 int xSum = 0.0, ySum = 0.0;
2763 for (
int star = 0; star < tileStars[tile].count(); star++)
2765 xSum += tileStars[tile][star]->x - tileCenter.
x();
2766 ySum += tileStars[tile][star]->y - tileCenter.
y();
2769 xAv = (tileStars[tile].count() <= 0) ? 0 : xSum / tileStars[tile].count();
2770 yAv = (tileStars[tile].count() <= 0) ? 0 : ySum / tileStars[tile].count();
2772 m_abInsTileCenterOffset.append(
QPoint(xAv, yAv));
2775 m_abInsPosition.append(currentPosition);
2778void Focus::setCaptureComplete()
2780 DarkLibrary::Instance()->disconnect(
this);
2783 syncTrackingBoxPosition();
2786 if (inFocusLoop ==
false)
2787 appendLogText(
i18n(
"Image received."));
2789 if (m_captureInProgress && inFocusLoop ==
false && inAutoFocus ==
false)
2790 m_Camera->setUploadMode(rememberUploadMode);
2792 if (m_RememberCameraFastExposure && inFocusLoop ==
false && inAutoFocus ==
false)
2794 m_RememberCameraFastExposure =
false;
2795 m_Camera->setFastExposureEnabled(
true);
2798 m_captureInProgress =
false;
2799 if (m_abortInProgress)
2803 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding frame results in " << __FUNCTION__;
2808 checkMosaicMaskLimits();
2811 emit newImage(m_FocusView);
2813 emit newStarPixmap(m_FocusView->getTrackingBoxPixmap(10));
2821 if (!isStarMeasureStarBased())
2822 starDetectionFinished();
2823 else if (inFocusLoop ==
false || (inFocusLoop && (m_FocusView->isTrackingBoxEnabled()
2824 || m_OpsFocusSettings->focusUseFullField->isChecked())))
2830void Focus::setHFRComplete()
2840 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
2843 int subBinX = 1, subBinY = 1;
2844 if (!targetChip->getBinning(&subBinX, &subBinY))
2845 qCDebug(KSTARS_EKOS_FOCUS) <<
"Warning: target chip is reporting no binning property, using 1x1.";
2848 if (m_OpsFocusSettings->focusSubFrame->isChecked() && !isStarMeasureStarBased() && !starSelected)
2850 appendLogText(
i18n(
"Capture complete. Select a region of interest."));
2852 syncTrackingBoxPosition();
2855 setState(Ekos::FOCUS_WAITING);
2858 waitStarSelectTimer.start();
2861 else if (m_OpsFocusSettings->focusSubFrame->isChecked() && isStarMeasureStarBased() && starCenter.isNull())
2868 int x = 0, y = 0, w = 0, h = 0;
2871 if (frameSettings.contains(targetChip))
2873 QVariantMap settings = frameSettings[targetChip];
2874 x = settings[
"x"].toInt();
2875 y = settings[
"y"].toInt();
2876 w = settings[
"w"].toInt();
2877 h = settings[
"h"].toInt();
2881 targetChip->getFrame(&x, &y, &w, &h);
2884 if (m_OpsFocusSettings->focusAutoStarEnabled->isChecked())
2887 const Edge selectedHFRStar = m_ImageData->getSelectedHFRStar();
2889 if (selectedHFRStar.x == -1)
2891 appendLogText(
i18n(
"Failed to automatically select a star. Please select a star manually."));
2894 m_FocusView->setTrackingBox(
QRect(w - m_OpsFocusSettings->focusBoxSize->value() / (subBinX * 2),
2895 h - m_OpsFocusSettings->focusBoxSize->value() / (subBinY * 2),
2896 m_OpsFocusSettings->focusBoxSize->value() / subBinX, m_OpsFocusSettings->focusBoxSize->value() / subBinY));
2897 m_FocusView->setTrackingBoxEnabled(
true);
2900 setState(Ekos::FOCUS_WAITING);
2903 waitStarSelectTimer.start();
2909 starCenter.setX(selectedHFRStar.x);
2910 starCenter.setY(selectedHFRStar.y);
2911 starCenter.setZ(subBinX);
2912 starSelected =
true;
2913 syncTrackingBoxPosition();
2916 if (subFramed ==
false && isFocusSubFrameEnabled() && m_OpsFocusSettings->focusSubFrame->isChecked())
2918 int offset = (
static_cast<double>(m_OpsFocusSettings->focusBoxSize->value()) / subBinX) * 1.5;
2919 int subX = (selectedHFRStar.x - offset) * subBinX;
2920 int subY = (selectedHFRStar.y - offset) * subBinY;
2921 int subW = offset * 2 * subBinX;
2922 int subH = offset * 2 * subBinY;
2924 int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
2925 targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
2932 if ((subW + subX) > maxW)
2934 if ((subH + subY) > maxH)
2939 QVariantMap settings = frameSettings[targetChip];
2940 settings[
"x"] = subX;
2941 settings[
"y"] = subY;
2942 settings[
"w"] = subW;
2943 settings[
"h"] = subH;
2944 settings[
"binx"] = subBinX;
2945 settings[
"biny"] = subBinY;
2947 qCDebug(KSTARS_EKOS_FOCUS) <<
"Frame is subframed. X:" << subX <<
"Y:" << subY <<
"W:" << subW <<
"H:" << subH <<
"binX:" <<
2948 subBinX <<
"binY:" << subBinY;
2952 frameSettings[targetChip] = settings;
2955 starCenter.setX(subW / (2 * subBinX));
2956 starCenter.setY(subH / (2 * subBinY));
2957 starCenter.setZ(subBinX);
2961 m_FocusView->setFirstLoad(
true);
2970 starCenter.setX(selectedHFRStar.x);
2971 starCenter.setY(selectedHFRStar.y);
2972 starCenter.setZ(subBinX);
2985 appendLogText(
i18n(
"Capture complete. Select a star to focus."));
2987 starSelected =
false;
2991 int subBinX = 1, subBinY = 1;
2992 targetChip->getBinning(&subBinX, &subBinY);
2994 m_FocusView->setTrackingBox(
QRect((w - m_OpsFocusSettings->focusBoxSize->value()) / (subBinX * 2),
2995 (h - m_OpsFocusSettings->focusBoxSize->value()) / (2 * subBinY),
2996 m_OpsFocusSettings->focusBoxSize->value() / subBinX, m_OpsFocusSettings->focusBoxSize->value() / subBinY));
2997 m_FocusView->setTrackingBoxEnabled(
true);
3000 setState(Ekos::FOCUS_WAITING);
3003 waitStarSelectTimer.start();
3009 if (minimumRequiredHFR >= 0)
3012 if (currentHFR == INVALID_STAR_MEASURE)
3014 if (noStarCount++ < MAX_RECAPTURE_RETRIES)
3016 appendLogText(
i18n(
"No stars detected while testing HFR, capturing again..."));
3018 if (noStarCount == MAX_RECAPTURE_RETRIES)
3027 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
3032 else if (currentHFR > minimumRequiredHFR)
3034 qCDebug(KSTARS_EKOS_FOCUS) <<
"Current HFR:" << currentHFR <<
"is above required minimum HFR:" << minimumRequiredHFR <<
3035 ". Starting AutoFocus...";
3038 minimumRequiredHFR = INVALID_STAR_MEASURE;
3039 runAutoFocus(AutofocusReason::FOCUS_HFR_CHECK, reasonInfo);
3044 qCDebug(KSTARS_EKOS_FOCUS) <<
"Current HFR:" << currentHFR <<
"is below required minimum HFR:" << minimumRequiredHFR <<
3045 ". Autofocus successful.";
3046 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
3054 if (inAutoFocus ==
false)
3058 if (state() != Ekos::FOCUS_IDLE)
3059 setState(Ekos::FOCUS_IDLE);
3066 if (state() != Ekos::FOCUS_PROGRESS)
3067 setState(Ekos::FOCUS_PROGRESS);
3072 else if(focusAdvisor->inFocusAdvisor())
3073 focusAdvisor->control();
3074 else if(m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
3076 else if (canAbsMove || canRelMove)
3084QString Focus::getyAxisLabel(StarMeasure starMeasure)
3087 m_StarUnits == FOCUS_UNITS_ARCSEC ? str +=
" (\")" : str +=
" (pix)";
3091 switch (starMeasure)
3093 case FOCUS_STAR_HFR:
3095 case FOCUS_STAR_HFR_ADJ:
3097 m_StarUnits == FOCUS_UNITS_ARCSEC ? str +=
" (\")" : str +=
" (pix)";
3099 case FOCUS_STAR_FWHM:
3101 m_StarUnits == FOCUS_UNITS_ARCSEC ? str +=
" (\")" : str +=
" (pix)";
3103 case FOCUS_STAR_NUM_STARS:
3106 case FOCUS_STAR_FOURIER_POWER:
3107 str =
"Fourier Power";
3109 case FOCUS_STAR_STDDEV:
3112 case FOCUS_STAR_SOBEL:
3113 str =
"Sobel Factor";
3115 case FOCUS_STAR_LAPLASSIAN:
3116 str =
"Laplassian Factor";
3118 case FOCUS_STAR_CANNY:
3119 str =
"Canny Factor";
3128void Focus::clearDataPoints()
3131 polynomialFit.reset();
3132 plot_position.
clear();
3134 plot_weight.clear();
3135 plot_outlier.clear();
3136 isVShapeSolution =
false;
3137 m_abInsPosition.clear();
3138 m_abInsTileCenterOffset.clear();
3139 if (m_abInsMeasure.count() != NUM_TILES)
3141 m_abInsMeasure.resize(NUM_TILES);
3142 m_abInsWeight.resize(NUM_TILES);
3143 m_abInsNumStars.resize(NUM_TILES);
3147 for (
int i = 0; i < m_abInsMeasure.count(); i++)
3149 m_abInsMeasure[i].clear();
3150 m_abInsWeight[i].clear();
3151 m_abInsNumStars[i].clear();
3155 emit initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits),
3156 m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, m_OpsFocusProcess->focusUseWeights->isChecked(),
3157 inFocusLoop ==
false && isPositionBased());
3160bool Focus::autoFocusChecks()
3162 if (++absIterations > MAXIMUM_ABS_ITERATIONS)
3164 appendLogText(
i18n(
"Autofocus failed: exceeded max iterations %1", MAXIMUM_ABS_ITERATIONS));
3165 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_MAX_ITERS);
3170 if (isStarMeasureStarBased() && currentHFR == INVALID_STAR_MEASURE)
3172 if (noStarCount < MAX_RECAPTURE_RETRIES)
3175 appendLogText(
i18n(
"No stars detected, capturing again..."));
3179 else if (m_FocusAlgorithm == FOCUS_LINEAR)
3181 appendLogText(
i18n(
"Failed to detect any stars at position %1. Continuing...", currentPosition));
3184 else if(!m_OpsFocusProcess->focusDonut->isChecked())
3187 appendLogText(
i18n(
"Failed to detect any stars. Reset frame and try again."));
3188 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
3198void Focus::plotLinearFocus()
3207 linearFocuser->getMeasurements(&positions, &values, &weights);
3208 const FocusAlgorithmInterface::FocusParams ¶ms = linearFocuser->getParams();
3215 bool incrementalChange =
false;
3216 if (positions.
size() > 1 && positions.
size() == lastPositions.
size() + 1)
3219 for (
int i = 0; i < positions.
size() - 1; ++i)
3220 if (positions[i] != lastPositions[i] || values[i] != lastValues[i])
3225 incrementalChange =
ok;
3227 lastPositions = positions;
3228 lastValues = values;
3230 const bool outlier =
false;
3231 if (incrementalChange)
3232 emit newHFRPlotPosition(
static_cast<double>(positions.
last()), values.
last(), (pow(weights.
last(), -0.5)),
3233 outlier, params.initialStepSize, plt);
3236 emit initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits),
3237 m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, params.useWeights, plt);
3238 for (
int i = 0; i < positions.
size(); ++i)
3239 emit newHFRPlotPosition(
static_cast<double>(positions[i]), values[i], (pow(weights.
last(), -0.5)),
3240 outlier, params.initialStepSize, plt);
3244 if (values.
size() > 3)
3250 double minPosition, minValue;
3251 double searchMin = std::max(params.minPositionAllowed, params.startPosition - params.maxTravel);
3252 double searchMax = std::min(params.maxPositionAllowed, params.startPosition + params.maxTravel);
3254 linearFocuser->getPass1Measurements(&pass1Positions, &pass1Values, &pass1Weights, &pass1Outliers);
3255 if (m_FocusAlgorithm == FOCUS_LINEAR || m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
3259 polynomialFit.reset(
new PolynomialFit(2, pass1Positions, pass1Values));
3261 if (polynomialFit->findMinimum(params.startPosition, searchMin, searchMax, &minPosition, &minValue))
3263 emit drawPolynomial(polynomialFit.get(),
true,
true, plt);
3267 if (linearFocuser->isDone())
3268 emit minimumFound(-1, -1, plt);
3270 emit minimumFound(minPosition, minValue, plt);
3275 emit drawPolynomial(polynomialFit.get(),
false,
false, plt);
3276 emit minimumFound(-1, -1, plt);
3282 if (curveFitting->findMinMax(params.startPosition, searchMin, searchMax, &minPosition, &minValue, params.curveFit,
3283 params.optimisationDirection))
3285 R2 = curveFitting->calculateR2(
static_cast<CurveFitting::CurveFit
>(params.curveFit));
3286 emit drawCurve(curveFitting.get(),
true,
true, plt);
3289 emit minimumFound(minPosition, minValue, plt);
3294 emit drawCurve(curveFitting.get(),
false,
false, plt);
3295 emit minimumFound(-1, -1, plt);
3301 HFROut->setText(
QString(
"%1").arg(currentHFR * getStarUnits(m_StarMeasure, m_StarUnits), 0,
'f', 2));
3303 emit setTitle(linearFocuser->getTextStatus(R2));
3305 if (!plt) HFRPlot->replot();
3309CurveFitting::FittingGoal Focus::getGoal(
int numSteps)
3312 if (m_FocusWalk == FOCUS_WALK_CLASSIC)
3313 return CurveFitting::FittingGoal::STANDARD;
3316 return (numSteps >= m_OpsFocusMechanics->focusNumSteps->value()) ? CurveFitting::FittingGoal::BEST :
3317 CurveFitting::FittingGoal::STANDARD;
3323void Focus::plotLinearFinalUpdates()
3326 if (!m_OpsFocusProcess->focusRefineCurveFit->isChecked())
3329 emit drawCFZ(linearFocuser->solution(), linearFocuser->solutionValue(), m_cfzSteps,
3330 m_CFZUI->focusCFZDisplayVCurve->isChecked());
3332 emit finalUpdates(linearFocuser->getTextStatus(R2), plt);
3342 linearFocuser->getPass1Measurements(&pass1Positions, &pass1Values, &pass1Weights, &pass1Outliers);
3343 const FocusAlgorithmInterface::FocusParams ¶ms = linearFocuser->getParams();
3345 emit initHFRPlot(getyAxisLabel(m_StarMeasure), getStarUnits(m_StarMeasure, m_StarUnits),
3346 m_OptDir == CurveFitting::OPTIMISATION_MINIMISE, m_OpsFocusProcess->focusUseWeights->isChecked(), plt);
3348 for (
int i = 0; i < pass1Positions.
size(); ++i)
3349 emit newHFRPlotPosition(
static_cast<double>(pass1Positions[i]), pass1Values[i], (pow(pass1Weights[i], -0.5)),
3350 pass1Outliers[i], params.initialStepSize, plt);
3352 R2 = curveFitting->calculateR2(
static_cast<CurveFitting::CurveFit
>(params.curveFit));
3353 emit drawCurve(curveFitting.get(),
true,
true,
false);
3356 emit minimumFound(linearFocuser->solution(), linearFocuser->solutionValue(), plt);
3358 emit drawCFZ(linearFocuser->solution(), linearFocuser->solutionValue(), m_cfzSteps,
3359 m_CFZUI->focusCFZDisplayVCurve->isChecked());
3361 emit setTitle(linearFocuser->getTextStatus(R2), plt);
3365void Focus::startAberrationInspector()
3367#ifdef HAVE_DATAVISUALIZATION
3369 AberrationInspector::abInsData data;
3371 ImageMosaicMask *mosaicmask =
dynamic_cast<ImageMosaicMask *
>(m_FocusView->imageMask().
get());
3374 appendLogText(
i18n(
"Unable to launch Aberration Inspector run %1...", m_abInsRun));
3379 data.run = ++m_abInsRun;
3380 data.curveFit = m_CurveFit;
3381 data.useWeights = m_OpsFocusProcess->focusUseWeights->isChecked();
3382 data.optDir = m_OptDir;
3383 data.sensorWidth = m_CcdWidth;
3384 data.sensorHeight = m_CcdHeight;
3385 data.pixelSize = m_CcdPixelSizeX;
3386 data.tileWidth = mosaicmask->tiles()[0].width();
3387 data.focuserStepMicrons = m_CFZUI->focusCFZStepSize->value();
3388 data.yAxisLabel = getyAxisLabel(m_StarMeasure);
3389 data.starUnits = getStarUnits(m_StarMeasure, m_StarUnits);
3390 data.cfzSteps = m_cfzSteps;
3391 data.isPositionBased = isPositionBased();
3394 appendLogText(
i18n(
"Launching Aberration Inspector run %1...", m_abInsRun));
3396 m_abInsNumStars, m_abInsTileCenterOffset));
3403bool Focus::initScanStartPos(
const bool force,
const int initialPosition)
3407 if (!m_OpsFocusProcess->focusScanStartPos->isChecked())
3410 if (!m_OpsFocusProcess->focusScanAlwaysOn->isChecked() && !m_AFRerun)
3415 inScanStartPos =
true;
3416 initialFocuserAbsPosition = initialPosition;
3417 m_scanMeasure.clear();
3418 m_scanPosition.clear();
3420 appendLogText(
i18n(
"Starting scan for initial focuser position."));
3421 emit setTitle(
QString(
i18n(
"Scanning for starting position...")),
true);
3423 if (!changeFocus(initialPosition - currentPosition))
3424 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
3429void Focus::scanStartPos()
3432 if (currentHFR == INVALID_STAR_MEASURE)
3434 if (noStarCount < MAX_RECAPTURE_RETRIES)
3437 appendLogText(
i18n(
"No stars detected, capturing again..."));
3443 appendLogText(
i18n(
"Failed to detect any stars. Aborting..."));
3444 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
3450 if (++absIterations > MAXIMUM_ABS_ITERATIONS)
3452 appendLogText(
i18n(
"Scan Start Pos: exceeded max iterations %1", MAXIMUM_ABS_ITERATIONS));
3453 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_MAX_ITERS);
3458 m_scanPosition.push_back(currentPosition);
3459 m_scanMeasure.push_back(currentMeasure);
3462 const int step = m_scanPosition.size();
3463 const int maxSteps = m_OpsFocusProcess->focusScanDatapoints->value();
3464 const int stepSize = m_OpsFocusMechanics->focusTicks->value() * m_OpsFocusProcess->focusScanStepSizeFactor->value();
3465 emit newHFRPlotPosition(
static_cast<double>(currentPosition), currentMeasure, pow(currentWeight, -0.5),
false, stepSize,
3467 if (step < maxSteps)
3470 emit setTitle(
QString(
i18n(
"Scanning for starting position %1/%2", step, maxSteps)),
true);
3471 deltaPos = step * stepSize * std::pow(-1, step + 1);
3476 auto it = std::min_element(std::begin(m_scanMeasure), std::end(m_scanMeasure));
3477 auto min = std::distance(std::begin(m_scanMeasure), it);
3478 if (min >= m_OpsFocusProcess->focusScanDatapoints->value() - 2)
3481 deltaPos = m_scanPosition[min] - currentPosition;
3482 m_scanPosition.clear();
3483 m_scanMeasure.clear();
3484 emit setTitle(
QString(
i18n(
"No scan minimum - widening search...")),
true);
3489 if (m_AutofocusReason == FOCUS_FOCUS_ADVISOR)
3490 focusAdvisor->setInFocusAdvisor(
false);
3492 const int initialPosition = m_scanPosition[min];
3493 setupLinearFocuser(initialPosition);
3494 inScanStartPos =
false;
3496 deltaPos = linearRequestedPosition - currentPosition;
3497 emit setTitle(
QString(
i18n(
"Scan Start Position %1 Found", initialPosition)),
true);
3498 appendLogText(
i18n(
"Scan Start Position %1 found", initialPosition));
3501 if (!changeFocus(deltaPos))
3502 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
3505void Focus::autoFocusLinear()
3507 if (!autoFocusChecks())
3510 if (!canAbsMove && !canRelMove && canTimerMove)
3513 if (linearRequestedPosition != currentPosition)
3516 qCDebug(KSTARS_EKOS_FOCUS) <<
"Linear: warning, changing position " << currentPosition <<
" to "
3517 << linearRequestedPosition;
3519 currentPosition = linearRequestedPosition;
3524 bool useFocusStarsHFR = m_OpsFocusSettings->focusUseFullField->isChecked()
3525 && m_OpsFocusProcess->focusFramesCount->value() == 1;
3526 auto focusStars = useFocusStarsHFR || (m_FocusAlgorithm == FOCUS_LINEAR1PASS) ? &(m_ImageData->getStarCenters()) :
nullptr;
3528 linearRequestedPosition = linearFocuser->newMeasurement(currentPosition, currentMeasure, currentWeight, focusStars);
3529 if (m_FocusAlgorithm == FOCUS_LINEAR1PASS && linearFocuser->isDone() && linearFocuser->solution() != -1)
3532 plotLinearFinalUpdates();
3534 startAberrationInspector();
3540 if (linearFocuser->isDone())
3542 if (linearFocuser->solution() != -1)
3545 if (m_AutofocusReason == FOCUS_FOCUS_ADVISOR)
3547 if (focusAdvisor->analyseAF())
3548 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_ADVISOR_RERUN,
"",
false);
3550 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE,
"",
false);
3552 else if (m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
3554 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE,
"",
false);
3555 else if (R2 >= m_OpsFocusProcess->focusR2Limit->value())
3559 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Linear Curve Fit check passed R2=%1 focusR2Limit=%2").
arg(R2).
arg(
3560 m_OpsFocusProcess->focusR2Limit->value());
3561 completeFocusProcedure(Ekos::FOCUS_COMPLETE, FOCUS_FAIL_NONE,
"",
false);
3564 else if (R2Retries == 0)
3567 appendLogText(
i18n(
"Curve Fit check failed R2=%1 focusR2Limit=%2 retrying...", R2,
3568 m_OpsFocusProcess->focusR2Limit->value()));
3571 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_R2, failCodeInfo,
false);
3577 appendLogText(
i18n(
"Curve Fit check failed again R2=%1 focusR2Limit=%2 but continuing...", R2,
3578 m_OpsFocusProcess->focusR2Limit->value()));
3579 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE,
"",
false);
3585 qCDebug(KSTARS_EKOS_FOCUS) << linearFocuser->doneReason();
3586 AutofocusFailReason failCode = linearFocuser->getFailCode();
3587 appendLogText(
i18n(
"Linear autofocus algorithm aborted: %1", AutofocusFailReasonStr[failCode]));
3588 completeFocusProcedure(Ekos::FOCUS_ABORTED, failCode,
"",
false);
3594 const int delta = linearRequestedPosition - currentPosition;
3596 if (!changeFocus(delta))
3597 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE,
"",
false);
3603void Focus::autoFocusAbs()
3607 static int minHFRPos = 0, focusOutLimit = 0, focusInLimit = 0, lastHFRPos = 0, fluctuations = 0;
3608 static double minHFR = 0, lastDelta = 0;
3609 double targetPosition = 0;
3610 bool ignoreLimitedDelta =
false;
3612 QString deltaTxt =
QString(
"%1").
arg(fabs(currentHFR - minHFR) * 100.0, 0,
'g', 3);
3615 qCDebug(KSTARS_EKOS_FOCUS) <<
"===============================";
3616 qCDebug(KSTARS_EKOS_FOCUS) <<
"Current HFR: " << currentHFR <<
" Current Position: " << currentPosition;
3617 qCDebug(KSTARS_EKOS_FOCUS) <<
"Last minHFR: " << minHFR <<
" Last MinHFR Pos: " << minHFRPos;
3618 qCDebug(KSTARS_EKOS_FOCUS) <<
"Delta: " << deltaTxt <<
"%";
3619 qCDebug(KSTARS_EKOS_FOCUS) <<
"========================================";
3622 appendLogText(
i18n(
"FITS received. HFR %1 @ %2. Delta (%3%)", HFRText, currentPosition, deltaTxt));
3624 appendLogText(
i18n(
"FITS received. HFR %1 @ %2.", HFRText, currentPosition));
3626 if (!autoFocusChecks())
3629 addPlotPosition(currentPosition, currentHFR);
3631 switch (m_LastFocusDirection)
3634 lastHFR = currentHFR;
3635 initialFocuserAbsPosition = currentPosition;
3636 minHFR = currentHFR;
3637 minHFRPos = currentPosition;
3647 if (absMotionMax < currentPosition + pulseDuration)
3649 if (currentPosition < absMotionMax)
3651 pulseDuration = absMotionMax - currentPosition;
3656 m_LastFocusDirection = FOCUS_IN;
3659 else if (currentPosition + pulseDuration < absMotionMin)
3661 if (absMotionMin < currentPosition)
3663 pulseDuration = currentPosition - absMotionMin;
3668 m_LastFocusDirection = FOCUS_OUT;
3672 m_LastFocusDirection = (pulseDuration > 0) ? FOCUS_OUT : FOCUS_IN;
3673 if (!changeFocus(pulseDuration,
false))
3674 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
3680 if (reverseDir && focusInLimit && focusOutLimit &&
3681 fabs(currentHFR - minHFR) < (m_OpsFocusProcess->focusTolerance->value() / 100.0) && HFRInc == 0)
3683 if (absIterations <= 2)
3685 QString message =
i18n(
"Change in HFR is too small. Try increasing the step size or decreasing the tolerance.");
3686 appendLogText(message);
3687 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3688 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_SMALL_HFR);
3690 else if (noStarCount > 0)
3692 QString message =
i18n(
"Failed to detect focus star in frame. Capture and select a focus star.");
3693 appendLogText(message);
3694 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3695 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
3699 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
3703 else if (currentHFR < lastHFR)
3706 if (HFRInc >= 1 && m_LastFocusDirection == FOCUS_OUT && lastHFRPos < focusInLimit && fabs(currentHFR - lastHFR) > 0.1)
3708 focusInLimit = lastHFRPos;
3709 qCDebug(KSTARS_EKOS_FOCUS) <<
"New FocusInLimit " << focusInLimit;
3711 else if (HFRInc >= 1 && m_LastFocusDirection == FOCUS_IN && lastHFRPos > focusOutLimit &&
3712 fabs(currentHFR - lastHFR) > 0.1)
3714 focusOutLimit = lastHFRPos;
3715 qCDebug(KSTARS_EKOS_FOCUS) <<
"New FocusOutLimit " << focusOutLimit;
3718 double factor = std::max(1.0, HFRDec / 2.0);
3719 if (m_LastFocusDirection == FOCUS_IN)
3720 targetPosition = currentPosition - (pulseDuration * factor);
3722 targetPosition = currentPosition + (pulseDuration * factor);
3724 qCDebug(KSTARS_EKOS_FOCUS) <<
"current Position" << currentPosition <<
" targetPosition " << targetPosition;
3726 lastHFR = currentHFR;
3729 if (lastHFR < minHFR)
3732 minHFRPos = currentPosition;
3733 qCDebug(KSTARS_EKOS_FOCUS) <<
"new minHFR " << minHFR <<
" @ position " << minHFRPos;
3736 lastHFRPos = currentPosition;
3743 if (plot_position.count() >= 2)
3745 plot_position.remove(plot_position.count() - 2);
3746 plot_value.remove(plot_value.count() - 2);
3760 lastHFR = currentHFR;
3761 lastHFRPos = currentPosition;
3770 qCDebug(KSTARS_EKOS_FOCUS) <<
"Focus is moving away from optimal HFR.";
3773 if (m_LastFocusDirection == FOCUS_IN)
3775 focusInLimit = currentPosition;
3776 qCDebug(KSTARS_EKOS_FOCUS) <<
"Setting focus IN limit to " << focusInLimit;
3780 focusOutLimit = currentPosition;
3781 qCDebug(KSTARS_EKOS_FOCUS) <<
"Setting focus OUT limit to " << focusOutLimit;
3784 if (m_FocusAlgorithm == FOCUS_POLYNOMIAL && plot_position.count() > 4)
3786 polynomialFit.reset(
new PolynomialFit(2, 5, plot_position, plot_value));
3787 double a = *std::min_element(plot_position.constBegin(), plot_position.constEnd());
3788 double b = *std::max_element(plot_position.constBegin(), plot_position.constEnd());
3789 double min_position = 0, min_hfr = 0;
3790 isVShapeSolution = polynomialFit->findMinimum(minHFRPos, a, b, &min_position, &min_hfr);
3791 qCDebug(KSTARS_EKOS_FOCUS) <<
"Found Minimum?" << (isVShapeSolution ?
"Yes" :
"No");
3792 if (isVShapeSolution)
3794 ignoreLimitedDelta =
true;
3795 qCDebug(KSTARS_EKOS_FOCUS) <<
"Minimum Solution:" << min_hfr <<
"@" << min_position;
3796 targetPosition = round(min_position);
3797 appendLogText(
i18n(
"Found polynomial solution @ %1",
QString::number(min_position,
'f', 0)));
3799 emit drawPolynomial(polynomialFit.get(), isVShapeSolution,
true);
3800 emit minimumFound(min_position, min_hfr);
3804 emit drawPolynomial(polynomialFit.get(), isVShapeSolution,
false);
3813 if (std::abs(lastDelta) > 0)
3814 targetPosition = currentPosition + lastDelta;
3816 targetPosition = currentPosition + pulseDuration;
3818 else if (isVShapeSolution ==
false)
3820 ignoreLimitedDelta =
true;
3822 if (m_LastFocusDirection == FOCUS_OUT)
3823 targetPosition = minHFRPos - pulseDuration / 2;
3825 targetPosition = minHFRPos + pulseDuration / 2;
3828 qCDebug(KSTARS_EKOS_FOCUS) <<
"new targetPosition " << targetPosition;
3832 if (focusInLimit != 0 && m_LastFocusDirection == FOCUS_IN && targetPosition < focusInLimit)
3834 targetPosition = focusInLimit;
3835 qCDebug(KSTARS_EKOS_FOCUS) <<
"Limiting target pulse to focus in limit " << targetPosition;
3837 else if (focusOutLimit != 0 && m_LastFocusDirection == FOCUS_OUT && targetPosition > focusOutLimit)
3839 targetPosition = focusOutLimit;
3840 qCDebug(KSTARS_EKOS_FOCUS) <<
"Limiting target pulse to focus out limit " << targetPosition;
3844 if (targetPosition < absMotionMin)
3845 targetPosition = absMotionMin;
3846 else if (targetPosition > absMotionMax)
3847 targetPosition = absMotionMax;
3850 if (targetPosition == currentPosition)
3854 if (targetPosition == minHFRPos || isVShapeSolution)
3856 appendLogText(
"Stopping at minimum recorded HFR position.");
3857 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
3861 QString message =
i18n(
"Focuser cannot move further, device limits reached. Autofocus aborted.");
3862 appendLogText(message);
3863 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3864 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_OOB);
3870 if (fluctuations >= MAXIMUM_FLUCTUATIONS)
3872 QString message =
i18n(
"Unstable fluctuations. Try increasing initial step size or exposure time.");
3873 appendLogText(message);
3874 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3875 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FLUCTUATIONS);
3880 if (focusOutLimit && focusOutLimit == focusInLimit)
3882 QString message =
i18n(
"Deadlock reached. Please try again with different settings.");
3883 appendLogText(message);
3884 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3885 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_DEADLOCK);
3890 if (fabs(targetPosition - initialFocuserAbsPosition) > m_OpsFocusMechanics->focusMaxTravel->value())
3892 int minTravelLimit = qMax(0.0, initialFocuserAbsPosition - m_OpsFocusMechanics->focusMaxTravel->value());
3893 int maxTravelLimit = qMin(absMotionMax, initialFocuserAbsPosition + m_OpsFocusMechanics->focusMaxTravel->value());
3897 if (fabs(currentPosition - minTravelLimit) > 10 && targetPosition < minTravelLimit)
3899 targetPosition = minTravelLimit;
3902 else if (fabs(currentPosition - maxTravelLimit) > 10 && targetPosition > maxTravelLimit)
3904 targetPosition = maxTravelLimit;
3908 qCDebug(KSTARS_EKOS_FOCUS) <<
"targetPosition (" << targetPosition <<
") - initHFRAbsPos ("
3909 << initialFocuserAbsPosition <<
") exceeds maxTravel distance of " << m_OpsFocusMechanics->focusMaxTravel->value();
3911 QString message =
i18n(
"Maximum travel limit reached. Autofocus aborted.");
3912 appendLogText(message);
3913 KSNotification::event(
QLatin1String(
"FocusFailed"), message, KSNotification::Focus, KSNotification::Alert);
3914 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_OOB);
3920 lastDelta = (targetPosition - currentPosition);
3922 qCDebug(KSTARS_EKOS_FOCUS) <<
"delta (targetPosition - currentPosition) " << lastDelta;
3925 if (ignoreLimitedDelta ==
false)
3927 double limitedDelta = qMax(-1.0 * m_OpsFocusMechanics->focusMaxSingleStep->value(),
3928 qMin(1.0 * m_OpsFocusMechanics->focusMaxSingleStep->value(), lastDelta));
3929 if (std::fabs(limitedDelta - lastDelta) > 0)
3931 qCDebug(KSTARS_EKOS_FOCUS) <<
"Limited delta to maximum permitted single step " <<
3932 m_OpsFocusMechanics->focusMaxSingleStep->value();
3933 lastDelta = limitedDelta;
3937 m_LastFocusDirection = (lastDelta > 0) ? FOCUS_OUT : FOCUS_IN;
3938 if (!changeFocus(lastDelta,
false))
3939 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
3945void Focus::addPlotPosition(
int pos,
double value,
bool plot)
3947 plot_position.append(pos);
3948 plot_value.append(value);
3950 emit newHFRPlotPosition(
static_cast<double>(pos), value, 1.0,
false, pulseDuration);
3956void Focus::updatePlotPosition()
3958 if (m_FocusAlgorithm == FOCUS_LINEAR1PASS)
3961 if (inScanStartPos || focusAdvisor->inFocusAdvisor())
3964 plot_position.clear();
3966 plot_weight.clear();
3967 plot_outlier.clear();
3971 linearFocuser->getPass1Measurements(&positions, &plot_value, &plot_weight, &plot_outlier);
3972 plot_position.clear();
3973 for (
int i = 0; i < positions.
count(); i++)
3974 plot_position.append(positions[i]);
3977 if (linearFocuser && linearFocuser->isDone() && linearFocuser->solution() != -1)
3979 plot_position.append(linearFocuser->solution());
3980 plot_value.append(linearFocuser->solutionValue());
3981 plot_weight.append(linearFocuser->solutionWeight());
3982 plot_outlier.append(
false);
3986 else if (m_FocusAlgorithm == FOCUS_LINEAR)
3989 linearFocuser->getMeasurements(&positions, &plot_value, &plot_weight);
3990 plot_position.
clear();
3991 plot_outlier.clear();
3992 for (
int i = 0; i < positions.
count(); i++)
3994 plot_position.append(positions[i]);
3996 plot_outlier.append(
false);
4002 for (
int i = 0; i < plot_position.count(); i++)
4004 plot_weight.append(1.0);
4005 plot_outlier.append(
false);
4010void Focus::autoFocusRel()
4012 static int noStarCount = 0;
4013 static double minHFR = 1e6;
4014 QString deltaTxt =
QString(
"%1").
arg(fabs(currentHFR - minHFR) * 100.0, 0,
'g', 2);
4018 appendLogText(
i18n(
"FITS received. HFR %1. Delta (%2%) Min HFR (%3)", HFRText, deltaTxt, minHFRText));
4020 if (pulseDuration <= MINIMUM_PULSE_TIMER)
4022 appendLogText(
i18n(
"Autofocus failed to reach proper focus. Try adjusting the tolerance value."));
4023 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_TOLERANCE);
4028 if (currentHFR == INVALID_STAR_MEASURE)
4030 if (noStarCount < MAX_RECAPTURE_RETRIES)
4033 appendLogText(
i18n(
"No stars detected, capturing again..."));
4037 else if (m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
4039 appendLogText(
i18n(
"Failed to detect any stars at position %1. Continuing...", currentPosition));
4042 else if(!m_OpsFocusProcess->focusDonut->isChecked())
4045 appendLogText(
i18n(
"Failed to detect any stars. Reset frame and try again."));
4046 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
4053 switch (m_LastFocusDirection)
4056 lastHFR = currentHFR;
4058 m_LastFocusDirection = FOCUS_IN;
4059 changeFocus(-pulseDuration,
false);
4064 if (fabs(currentHFR - minHFR) < (m_OpsFocusProcess->focusTolerance->value() / 100.0) && HFRInc == 0)
4066 completeFocusProcedure(Ekos::FOCUS_COMPLETE, Ekos::FOCUS_FAIL_NONE);
4068 else if (currentHFR < lastHFR)
4070 if (currentHFR < minHFR)
4071 minHFR = currentHFR;
4073 lastHFR = currentHFR;
4074 changeFocus(m_LastFocusDirection == FOCUS_IN ? -pulseDuration : pulseDuration,
false);
4081 lastHFR = currentHFR;
4085 pulseDuration *= 0.75;
4087 if (!changeFocus(m_LastFocusDirection == FOCUS_IN ? pulseDuration : -pulseDuration,
false))
4088 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
4091 m_LastFocusDirection = (m_LastFocusDirection == FOCUS_IN) ? FOCUS_OUT : FOCUS_IN;
4097void Focus::autoFocusProcessPositionChange(IPState state)
4099 if (state == IPS_OK)
4105 if (focuserAdditionalMovement > 0)
4107 int temp = focuserAdditionalMovement;
4108 focuserAdditionalMovement = 0;
4110 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Undoing overscan extension. Moving back in by %1 ticks in %2s")
4111 .
arg(temp).
arg(m_OpsFocusMechanics->focusOverscanDelay->value());
4113 QTimer::singleShot(m_OpsFocusMechanics->focusOverscanDelay->value() * 1000,
this, [
this, temp]()
4115 if (!changeFocus(-temp, focuserAdditionalMovementUpdateDir))
4117 appendLogText(i18n(
"Focuser error, check INDI panel."));
4118 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_NO_MOVE);
4122 else if (inAutoFocus)
4125 if (m_FocusAlgorithm == FOCUS_LINEAR || m_FocusAlgorithm == FOCUS_LINEAR1PASS)
4126 if (abs(linearRequestedPosition - currentPosition) > m_OpsFocusMechanics->focusTicks->value())
4127 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Focus positioning error: requested position %1, current position %2")
4128 .
arg(linearRequestedPosition).
arg(currentPosition);
4130 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Focus position reached at %1, starting capture in %2 seconds.").
arg(
4131 currentPosition).
arg(m_OpsFocusMechanics->focusSettleTime->value());
4133 if (m_OpsFocusProcess->focusDonut->isChecked())
4134 donutTimeDilation();
4135 capture(m_OpsFocusMechanics->focusSettleTime->value());
4138 else if (state == IPS_ALERT)
4140 appendLogText(
i18n(
"Focuser error, check INDI panel."));
4141 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FOCUSER_ERROR);
4144 qCDebug(KSTARS_EKOS_FOCUS) <<
4145 QString(
"autoFocusProcessPositionChange called with state %1 (%2), focuserAdditionalMovement=%3, inAutoFocus=%4, m_captureInProgress=%5, currentPosition=%6")
4146 .
arg(state).
arg(pstateStr(state)).
arg(focuserAdditionalMovement).
arg(inAutoFocus).
arg(m_captureInProgress)
4147 .
arg(currentPosition);
4151void Focus::donutTimeDilation()
4153 if (m_OpsFocusProcess->focusTimeDilation->value() == 1.0 || inScanStartPos || focusAdvisor->inFocusAdvisor())
4157 const double centre = (m_OpsFocusMechanics->focusNumSteps->value() + 1.0) / 2.0;
4159 const int currentStep = linearFocuser->currentStep() + 1;
4161 if (currentStep <= m_OpsFocusMechanics->focusNumSteps->value())
4162 distance = std::abs(centre - currentStep);
4166 double multiplier =
distance / (centre - 1.0) * m_OpsFocusProcess->focusTimeDilation->value();
4167 multiplier = std::max(multiplier, 1.0);
4168 const double exposure = multiplier * m_donutOrigExposure;
4169 focusExposure->setValue(exposure);
4170 qCDebug(KSTARS_EKOS_FOCUS) <<
"Donut time dilation for point " << currentStep <<
" from " << m_donutOrigExposure <<
" to "
4175void Focus::updateProperty(INDI::Property prop)
4177 if (m_Focuser ==
nullptr || prop.getType() != INDI_NUMBER || prop.getDeviceName() != m_Focuser->getDeviceName())
4180 auto nvp = prop.getNumber();
4186 if (nvp->isNameMatch(
"FOCUS_BACKLASH_STEPS"))
4188 m_OpsFocusMechanics->focusBacklash->setValue(nvp->np[0].value);
4192 if (nvp->isNameMatch(
"ABS_FOCUS_POSITION"))
4197 if (m_DebugFocuserCounter++ >= 10 && m_DebugFocuserCounter <= 14)
4199 if (m_DebugFocuserCounter == 14)
4200 m_DebugFocuserCounter = 0;
4201 appendLogText(
i18n(
"Simulate focuser comms failure..."));
4206 m_FocusMotionTimer.stop();
4207 INumber *pos = IUFindNumber(nvp,
"FOCUS_ABSOLUTE_POSITION");
4208 IPState newState = nvp->s;
4213 int newPosition =
static_cast<int>(pos->value);
4218 if (currentPosition == newPosition && currentPositionState == newState)
4220 if (logPositionAndState)
4222 qCDebug(KSTARS_EKOS_FOCUS) <<
"Focuser position " << currentPosition <<
" and state:"
4223 << pstateStr(currentPositionState) <<
" unchanged";
4224 logPositionAndState =
false;
4230 logPositionAndState =
true;
4233 currentPositionState = newState;
4235 if (currentPosition != newPosition)
4237 currentPosition = newPosition;
4238 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abs Focuser position changed to " << currentPosition <<
"State:" << pstateStr(
4239 currentPositionState);
4241 emit absolutePositionChanged(currentPosition);
4245 qCDebug(KSTARS_EKOS_FOCUS) <<
"Can't access FOCUS_ABSOLUTE_POSITION. Current state:"
4246 << pstateStr(currentPositionState) <<
" New state:" << pstateStr(newState);
4248 if (newState != IPS_OK)
4250 if (inAutoFocus || inAdjustFocus || adaptFocus->inAdaptiveFocus())
4254 qCDebug(KSTARS_EKOS_FOCUS) <<
"Restarting focus motion timer, state " << pstateStr(newState);
4255 m_FocusMotionTimer.start();
4261 if (focuserAdditionalMovement == 0)
4266 if (focuserAdditionalMovement == 0)
4268 inAdjustFocus =
false;
4269 emit focusPositionAdjusted();
4274 if (adaptFocus->inAdaptiveFocus())
4276 if (focuserAdditionalMovement == 0)
4278 adaptFocus->adaptiveFocusAdmin(currentPosition,
true,
true);
4283 if (m_RestartState == RESTART_NOW && status() != Ekos::FOCUS_ABORTED)
4285 if (focuserAdditionalMovement == 0)
4287 m_RestartState = RESTART_NONE;
4289 inAutoFocus = inBuildOffsets = inAdjustFocus = inScanStartPos =
false;
4290 adaptFocus->setInAdaptiveFocus(
false);
4291 focusAdvisor->setInFocusAdvisor(
false);
4292 appendLogText(
i18n(
"Restarting autofocus process..."));
4293 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
4297 else if (m_RestartState == RESTART_ABORT && focuserAdditionalMovement == 0)
4303 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
4304 m_RestartState = RESTART_NONE;
4305 inAutoFocus = inBuildOffsets = inAdjustFocus = inScanStartPos =
false;
4306 adaptFocus->setInAdaptiveFocus(
false);
4307 focusAdvisor->setInFocusAdvisor(
false);
4313 autoFocusProcessPositionChange(newState);
4314 else if (newState == IPS_ALERT)
4315 appendLogText(
i18n(
"Focuser error, check INDI panel."));
4322 if (nvp->isNameMatch(
"manualfocusdrive"))
4327 if (m_DebugFocuserCounter++ >= 10 && m_DebugFocuserCounter <= 14)
4329 if (m_DebugFocuserCounter == 14)
4330 m_DebugFocuserCounter = 0;
4331 appendLogText(
i18n(
"Simulate focuser comms failure..."));
4336 m_FocusMotionTimer.stop();
4338 INumber *pos = IUFindNumber(nvp,
"manualfocusdrive");
4339 IPState newState = nvp->s;
4340 if (pos && newState == IPS_OK)
4342 if (focuserAdditionalMovement == 0)
4345 currentPosition += pos->value;
4346 absTicksLabel->setText(
QString::number(
static_cast<int>(currentPosition)));
4347 emit absolutePositionChanged(currentPosition);
4350 if (inAdjustFocus && newState == IPS_OK)
4352 if (focuserAdditionalMovement == 0)
4354 inAdjustFocus =
false;
4355 emit focusPositionAdjusted();
4360 if (adaptFocus->inAdaptiveFocus() && newState == IPS_OK)
4362 if (focuserAdditionalMovement == 0)
4364 adaptFocus->adaptiveFocusAdmin(currentPosition,
true,
true);
4370 if (m_RestartState == RESTART_NOW && newState == IPS_OK && status() != Ekos::FOCUS_ABORTED)
4372 if (focuserAdditionalMovement == 0)
4374 m_RestartState = RESTART_NONE;
4376 inAutoFocus = inBuildOffsets = inAdjustFocus = inScanStartPos =
false;
4377 adaptFocus->setInAdaptiveFocus(
false);
4378 focusAdvisor->setInFocusAdvisor(
false);
4379 appendLogText(
i18n(
"Restarting autofocus process..."));
4380 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
4384 else if (m_RestartState == RESTART_ABORT && newState == IPS_OK)
4387 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
4388 m_RestartState = RESTART_NONE;
4389 inAutoFocus = inBuildOffsets = inAdjustFocus = inScanStartPos =
false;
4390 adaptFocus->setInAdaptiveFocus(
false);
4391 focusAdvisor->setInFocusAdvisor(
false);
4396 autoFocusProcessPositionChange(newState);
4397 else if (newState == IPS_ALERT)
4398 appendLogText(
i18n(
"Focuser error, check INDI panel."));
4403 if (nvp->isNameMatch(
"REL_FOCUS_POSITION"))
4405 m_FocusMotionTimer.stop();
4407 INumber *pos = IUFindNumber(nvp,
"FOCUS_RELATIVE_POSITION");
4408 IPState newState = nvp->s;
4409 if (pos && newState == IPS_OK)
4411 if (focuserAdditionalMovement == 0)
4414 currentPosition += pos->value * (m_LastFocusDirection == FOCUS_IN ? -1 : 1);
4415 qCDebug(KSTARS_EKOS_FOCUS)
4416 <<
QString(
"Rel Focuser position moved %1 by %2 to %3")
4417 .
arg((m_LastFocusDirection == FOCUS_IN) ?
"in" :
"out").
arg(pos->value).
arg(currentPosition);
4418 absTicksLabel->setText(
QString::number(
static_cast<int>(currentPosition)));
4419 emit absolutePositionChanged(currentPosition);
4422 if (inAdjustFocus && newState == IPS_OK)
4424 if (focuserAdditionalMovement == 0)
4426 inAdjustFocus =
false;
4427 emit focusPositionAdjusted();
4432 if (adaptFocus->inAdaptiveFocus() && newState == IPS_OK)
4434 if (focuserAdditionalMovement == 0)
4436 adaptFocus->adaptiveFocusAdmin(currentPosition,
true,
true);
4442 if (m_RestartState == RESTART_NOW && newState == IPS_OK && status() != Ekos::FOCUS_ABORTED)
4444 if (focuserAdditionalMovement == 0)
4446 m_RestartState = RESTART_NONE;
4448 inAutoFocus = inBuildOffsets = inAdjustFocus = inScanStartPos =
false;
4449 adaptFocus->setInAdaptiveFocus(
false);
4450 focusAdvisor->setInFocusAdvisor(
false);
4451 appendLogText(
i18n(
"Restarting autofocus process..."));
4452 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
4456 else if (m_RestartState == RESTART_ABORT && newState == IPS_OK)
4459 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
4460 m_RestartState = RESTART_NONE;
4461 inAutoFocus = inBuildOffsets = inAdjustFocus = inScanStartPos =
false;
4462 adaptFocus->setInAdaptiveFocus(
false);
4463 focusAdvisor->setInFocusAdvisor(
false);
4468 autoFocusProcessPositionChange(newState);
4469 else if (newState == IPS_ALERT)
4470 appendLogText(
i18n(
"Focuser error, check INDI panel."));
4478 if (nvp->isNameMatch(
"FOCUS_TIMER"))
4480 IPState newState = nvp->s;
4481 m_FocusMotionTimer.stop();
4483 if (m_RestartState == RESTART_NOW && newState == IPS_OK && status() != Ekos::FOCUS_ABORTED)
4485 if (focuserAdditionalMovement == 0)
4487 m_RestartState = RESTART_NONE;
4489 inAutoFocus = inBuildOffsets = inAdjustFocus = inScanStartPos =
false;
4490 adaptFocus->setInAdaptiveFocus(
false);
4491 focusAdvisor->setInFocusAdvisor(
false);
4492 appendLogText(
i18n(
"Restarting autofocus process..."));
4493 runAutoFocus(m_AutofocusReason, m_AutofocusReasonInfo);
4497 else if (m_RestartState == RESTART_ABORT && newState == IPS_OK)
4500 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FORCE_ABORT);
4501 m_RestartState = RESTART_NONE;
4502 inAutoFocus = inBuildOffsets = inAdjustFocus = inScanStartPos =
false;
4503 adaptFocus->setInAdaptiveFocus(
false);
4504 focusAdvisor->setInFocusAdvisor(
false);
4508 if (canAbsMove ==
false && canRelMove ==
false)
4511 INumber *pos = IUFindNumber(nvp,
"FOCUS_TIMER_VALUE");
4514 currentPosition += pos->value * (m_LastFocusDirection == FOCUS_IN ? -1 : 1);
4515 qCDebug(KSTARS_EKOS_FOCUS)
4516 <<
QString(
"Timer Focuser position moved %1 by %2 to %3")
4517 .
arg((m_LastFocusDirection == FOCUS_IN) ?
"in" :
"out").
arg(pos->value).
arg(currentPosition);
4520 if (pos && newState == IPS_OK && focuserAdditionalMovement == 0)
4523 if (inAdjustFocus && newState == IPS_OK)
4525 if (focuserAdditionalMovement == 0)
4527 inAdjustFocus =
false;
4528 emit focusPositionAdjusted();
4533 if (adaptFocus->inAdaptiveFocus() && newState == IPS_OK)
4535 if (focuserAdditionalMovement == 0)
4537 adaptFocus->adaptiveFocusAdmin(
true,
true,
true);
4542 autoFocusProcessPositionChange(newState);
4544 else if (newState == IPS_ALERT)
4545 appendLogText(
i18n(
"Focuser error, check INDI panel."));
4553 const QString logtext(m_Focuser ==
nullptr ? text :
QString(
"[%1] %2").arg(m_Focuser->getDeviceName()).
arg(text));
4554 emit newLog(logtext);
4557void Focus::appendFocusLogText(
const QString &text)
4559 if (Options::focusLogging())
4561 const QString logtext(m_Focuser ==
nullptr ? text :
QString(
"[%1] %2").arg(m_Focuser->getDeviceName()).
arg(text));
4562 emit newFocusLog(logtext);
4566void Focus::startFraming()
4568 if (m_Camera ==
nullptr)
4570 appendLogText(
i18n(
"No CCD connected."));
4574 waitStarSelectTimer.stop();
4577 starMeasureFrames.clear();
4582 setState(Ekos::FOCUS_FRAMING);
4586 appendLogText(
i18n(
"Starting continuous exposure..."));
4591void Focus::resetButtons()
4595 startFocusB->setEnabled(
false);
4596 startAbInsB->setEnabled(
false);
4597 startLoopB->setEnabled(
false);
4598 focusOutB->setEnabled(
true);
4599 focusInB->setEnabled(
true);
4600 startGotoB->setEnabled(canAbsMove);
4601 stopFocusB->setEnabled(
true);
4602 captureB->setEnabled(
false);
4603 opticalTrainCombo->setEnabled(
false);
4604 trainB->setEnabled(
false);
4618 if (disabledWidgets.empty())
4620 AFDisable(trainLabel,
false);
4621 AFDisable(opticalTrainCombo,
false);
4622 AFDisable(trainB,
false);
4623 AFDisable(focuserGroup,
true);
4624 AFDisable(clearDataB,
false);
4627 m_FocusGainAFEnabled = focusGain->isEnabled();
4628 m_FocusISOAFEnabled = focusISO->isEnabled();
4629 AFDisable(ccdGroup,
false);
4631 AFDisable(toolsGroup,
false);
4634 m_FocusSubFrameAFEnabled = m_OpsFocusSettings->focusSubFrame->isEnabled();
4637 AFDisable(m_OpsFocusSettings,
false);
4638 AFDisable(m_OpsFocusProcess,
false);
4639 AFDisable(m_OpsFocusMechanics,
false);
4640 AFDisable(focusAdvisor->focusAdvGroupBox,
false);
4641 AFDisable(m_CFZDialog,
false);
4644 stopFocusB->setEnabled(
true);
4650 for(
int i = 0 ; i < disabledWidgets.size() ; i++)
4651 disabledWidgets[i]->setEnabled(
true);
4652 disabledWidgets.clear();
4654 auto enableCaptureButtons = (m_captureInProgress ==
false && m_starDetectInProgress ==
false);
4656 captureB->setEnabled(enableCaptureButtons);
4657 resetFrameB->setEnabled(enableCaptureButtons);
4658 startLoopB->setEnabled(enableCaptureButtons);
4660 if (m_Focuser && m_Focuser->isConnected())
4662 focusOutB->setEnabled(
true);
4663 focusInB->setEnabled(
true);
4665 startFocusB->setEnabled(m_FocusType == FOCUS_AUTO);
4666 startAbInsB->setEnabled(canAbInsStart());
4667 stopFocusB->setEnabled(!enableCaptureButtons);
4668 startGotoB->setEnabled(canAbsMove);
4669 stopGotoB->setEnabled(
true);
4673 focusOutB->setEnabled(
false);
4674 focusInB->setEnabled(
false);
4676 startFocusB->setEnabled(
false);
4677 startAbInsB->setEnabled(
false);
4678 stopFocusB->setEnabled(
false);
4679 startGotoB->setEnabled(
false);
4680 stopGotoB->setEnabled(
false);
4688bool Focus::canAbInsStart()
4690 return canAbsMove && m_FocusAlgorithm == FOCUS_LINEAR1PASS && m_currentImageMask == FOCUS_MASK_MOSAIC;
4694void Focus::AFDisable(
QWidget * widget,
const bool children)
4701 if (wid->isEnabled())
4703 wid->setEnabled(
false);
4704 disabledWidgets.push_back(wid);
4713 disabledWidgets.push_back(widget);
4717bool Focus::isFocusGainEnabled()
4719 return (inAutoFocus) ? m_FocusGainAFEnabled : focusGain->isEnabled();
4722bool Focus::isFocusISOEnabled()
4724 return (inAutoFocus) ? m_FocusISOAFEnabled : focusISO->isEnabled();
4727bool Focus::isFocusSubFrameEnabled()
4729 return (inAutoFocus) ? m_FocusSubFrameAFEnabled : m_OpsFocusSettings->focusSubFrame->isEnabled();
4732void Focus::updateBoxSize(
int value)
4734 if (m_Camera ==
nullptr)
4737 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
4739 if (targetChip ==
nullptr)
4742 int subBinX, subBinY;
4743 targetChip->getBinning(&subBinX, &subBinY);
4745 QRect trackBox = m_FocusView->getTrackingBox();
4749 QRect(
center.x() - value / (2 * subBinX),
center.y() - value / (2 * subBinY), value / subBinX, value / subBinY);
4751 m_FocusView->setTrackingBox(trackBox);
4754void Focus::selectFocusStarFraction(
double x,
double y)
4756 if (m_ImageData.isNull())
4759 focusStarSelected(x * m_ImageData->width(), y * m_ImageData->height());
4763 emit newImage(m_FocusView);
4767void Focus::focusStarSelected(
int x,
int y)
4769 if (state() == Ekos::FOCUS_PROGRESS)
4772 if (subFramed ==
false)
4774 rememberStarCenter.setX(x);
4775 rememberStarCenter.setY(y);
4778 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
4780 int subBinX, subBinY;
4781 targetChip->getBinning(&subBinX, &subBinY);
4784 if (subBinX != (focusBinning->currentIndex() + 1))
4790 int offset = (
static_cast<double>(m_OpsFocusSettings->focusBoxSize->value()) / subBinX) * 1.5;
4794 bool squareMovedOutside =
false;
4796 if (subFramed ==
false && m_OpsFocusSettings->focusSubFrame->isChecked() && targetChip->canSubframe())
4799 if (!isStarMeasureStarBased())
4805 int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
4807 targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
4810 x = (x - offset) * subBinX;
4811 y = (y - offset) * subBinY;
4812 int w = offset * 2 * subBinX;
4813 int h = offset * 2 * subBinY;
4832 QVariantMap settings = frameSettings[targetChip];
4837 settings[
"binx"] = subBinX;
4838 settings[
"biny"] = subBinY;
4840 frameSettings[targetChip] = settings;
4844 qCDebug(KSTARS_EKOS_FOCUS) <<
"Frame is subframed. X:" << x <<
"Y:" << y <<
"W:" << w <<
"H:" << h <<
"binX:" << subBinX <<
4847 m_FocusView->setFirstLoad(
true);
4851 if (isStarMeasureStarBased())
4853 starCenter.setX(w / (2 * subBinX));
4854 starCenter.setY(h / (2 * subBinY));
4861 double dist = sqrt((starCenter.x() - x) * (starCenter.x() - x) + (starCenter.y() - y) * (starCenter.y() - y));
4863 squareMovedOutside = (dist > (
static_cast<double>(m_OpsFocusSettings->focusBoxSize->value()) / subBinX));
4867 starRect =
QRect(starCenter.x() - m_OpsFocusSettings->focusBoxSize->value() / (2 * subBinX),
4868 starCenter.y() - m_OpsFocusSettings->focusBoxSize->value() / (2 * subBinY),
4869 m_OpsFocusSettings->focusBoxSize->value() / subBinX,
4870 m_OpsFocusSettings->focusBoxSize->value() / subBinY);
4871 m_FocusView->setTrackingBox(starRect);
4876 starCenter.setZ(subBinX);
4878 if (squareMovedOutside && inAutoFocus ==
false && m_OpsFocusSettings->focusAutoStarEnabled->isChecked())
4880 m_OpsFocusSettings->focusAutoStarEnabled->blockSignals(
true);
4881 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
4882 m_OpsFocusSettings->focusAutoStarEnabled->blockSignals(
false);
4883 appendLogText(
i18n(
"Disabling Auto Star Selection as star selection box was moved manually."));
4884 starSelected =
false;
4886 else if (starSelected ==
false)
4888 if (isStarMeasureStarBased())
4889 appendLogText(
i18n(
"Focus star is selected."));
4891 appendLogText(
i18n(
"Region of interest is selected."));
4893 starSelected =
true;
4897 waitStarSelectTimer.stop();
4898 FocusState nextState = inAutoFocus ? FOCUS_PROGRESS : FOCUS_IDLE;
4899 if (nextState != state())
4901 setState(nextState);
4905void Focus::checkFocus(
double requiredHFR)
4907 if (inAutoFocus || inAdjustFocus || adaptFocus->inAdaptiveFocus())
4911 str =
i18n(
"Autofocus");
4912 else if (inAdjustFocus)
4913 str =
i18n(
"Adjust Focus");
4915 str =
i18n(
"Adaptive Focus");
4917 if (++m_StartRetries < MAXIMUM_RESTART_ITERATIONS)
4919 appendLogText(
i18n(
"Check focus request - Waiting 10sec for %1 to complete.", str));
4922 checkFocus(requiredHFR);
4927 appendLogText(
i18n(
"Discarding Check Focus request - %1 in progress.", str));
4928 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_INTERNAL);
4934 if (inFocusLoop || inBuildOffsets)
4936 QString str = inFocusLoop ?
"Focus Looping" :
" Build Offsets";
4937 qCDebug(KSTARS_EKOS_FOCUS) <<
QString(
"Check Focus rejected, %1 is already running.").
arg(str);
4939 else if (!isStarMeasureStarBased())
4940 appendLogText(
i18n(
"Check Focus ignored - Star Measure must be star based"));
4943 qCDebug(KSTARS_EKOS_FOCUS) <<
"Check Focus requested with minimum required HFR" << requiredHFR;
4944 minimumRequiredHFR = requiredHFR;
4945 appendLogText(
i18n(
"Capturing to check HFR..."));
4950void Focus::toggleSubframe(
bool enable)
4952 if (enable ==
false)
4956 m_FocusView->setTrackingBoxEnabled(enable);
4957 starSelected =
false;
4962 m_OpsFocusSettings->focusNoMaskRB->setChecked(
true);
4967 m_OpsFocusSettings->focusRingMaskRB->setEnabled(!enable);
4968 m_OpsFocusSettings->focusMosaicMaskRB->setEnabled(!enable);
4972 setAutoStarAndBox();
4979void Focus::setUseWeights()
4981 if (m_CurveFit == CurveFitting::FOCUS_QUADRATIC || !m_OpsFocusSettings->focusUseFullField->isChecked()
4982 || m_StarMeasure == FOCUS_STAR_NUM_STARS || m_StarMeasure == FOCUS_STAR_FOURIER_POWER ||
4983 m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
4984 m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
4986 m_OpsFocusProcess->focusUseWeights->setEnabled(
false);
4987 m_OpsFocusProcess->focusUseWeights->setChecked(
false);
4990 m_OpsFocusProcess->focusUseWeights->setEnabled(
true);
4997void Focus::setDenoise()
4999 if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
5000 m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
5001 m_OpsFocusProcess->focusDenoise->setEnabled(
true);
5004 m_OpsFocusProcess->focusDenoise->setEnabled(
false);
5005 m_OpsFocusProcess->focusDenoise->setChecked(
false);
5014void Focus::setDonutBuster()
5016 if (m_FocusAlgorithm != FOCUS_LINEAR1PASS)
5018 m_OpsFocusProcess->focusDonut->hide();
5019 m_OpsFocusProcess->focusDonut->setEnabled(
false);
5020 m_OpsFocusProcess->focusDonut->setChecked(
false);
5024 m_OpsFocusProcess->focusDonut->show();
5025 if ((m_StarMeasure == FOCUS_STAR_HFR || m_StarMeasure == FOCUS_STAR_HFR_ADJ || m_StarMeasure == FOCUS_STAR_FWHM) &&
5026 (m_FocusWalk == FOCUS_WALK_FIXED_STEPS || m_FocusWalk == FOCUS_WALK_CFZ_SHUFFLE) &&
5027 (m_CurveFit != CurveFitting::FOCUS_QUADRATIC))
5028 m_OpsFocusProcess->focusDonut->setEnabled(
true);
5031 m_OpsFocusProcess->focusDonut->setEnabled(
false);
5032 m_OpsFocusProcess->focusDonut->setChecked(
false);
5037void Focus::setExposure(
double value)
5039 focusExposure->setValue(value);
5042void Focus::setBinning(
int subBinX,
int subBinY)
5044 INDI_UNUSED(subBinY);
5045 focusBinning->setCurrentIndex(subBinX - 1);
5048void Focus::setAutoStarEnabled(
bool enable)
5050 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(enable);
5053void Focus::setAutoSubFrameEnabled(
bool enable)
5055 m_OpsFocusSettings->focusSubFrame->setChecked(enable);
5058void Focus::setAutoFocusParameters(
int boxSize,
int stepSize,
int maxTravel,
double tolerance)
5060 m_OpsFocusSettings->focusBoxSize->setValue(boxSize);
5061 m_OpsFocusMechanics->focusTicks->setValue(stepSize);
5062 m_OpsFocusMechanics->focusMaxTravel->setValue(maxTravel);
5063 m_OpsFocusProcess->focusTolerance->setValue(tolerance);
5066void Focus::checkAutoStarTimeout()
5069 if (starCenter.isNull() && (inAutoFocus || minimumRequiredHFR > 0))
5073 if (rememberStarCenter.isNull() ==
false)
5075 focusStarSelected(rememberStarCenter.x(), rememberStarCenter.y());
5076 appendLogText(
i18n(
"No star was selected. Using last known position..."));
5081 initialFocuserAbsPosition = -1;
5082 appendLogText(
i18n(
"No star was selected. Aborting..."));
5083 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_NO_STARS);
5085 else if (state() == FOCUS_WAITING)
5086 setState(FOCUS_IDLE);
5089void Focus::setAbsoluteFocusTicks()
5091 if (absTicksSpin->value() == currentPosition)
5093 appendLogText(
i18n(
"Focuser already at %1...", currentPosition));
5096 focusInB->setEnabled(
false);
5097 focusOutB->setEnabled(
false);
5098 startGotoB->setEnabled(
false);
5099 if (!changeFocus(absTicksSpin->value() - currentPosition))
5100 qCDebug(KSTARS_EKOS_FOCUS) <<
"setAbsoluteFocusTicks unable to move focuser.";
5103void Focus::syncTrackingBoxPosition()
5106 if (m_OpsFocusSettings->focusUseFullField->isChecked() || starCenter.isNull())
5109 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
5110 Q_ASSERT(targetChip);
5112 int subBinX = 1, subBinY = 1;
5113 targetChip->getBinning(&subBinX, &subBinY);
5115 double boxSize = m_OpsFocusSettings->focusBoxSize->value();
5117 targetChip->getFrame(&x, &y, &w, &h);
5119 if (boxSize / subBinX >= w || boxSize / subBinY >= h)
5121 m_OpsFocusSettings->focusBoxSize->setValue((boxSize / subBinX >= w) ? w : h);
5126 if (subBinX != starCenter.z())
5128 if (starCenter.z() > 0)
5130 starCenter.setX(starCenter.x() * (starCenter.z() / subBinX));
5131 starCenter.setY(starCenter.y() * (starCenter.z() / subBinY));
5134 starCenter.setZ(subBinX);
5139 if (isStarMeasureStarBased())
5140 starRect =
QRect(starCenter.x() - boxSize / (2 * subBinX), starCenter.y() - boxSize / (2 * subBinY),
5141 boxSize / subBinX, boxSize / subBinY);
5145 int minX, maxX, minY, maxY, minW, maxW, minH, maxH;
5146 targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
5147 int boxTLX = starCenter.x() - boxSize / (2 * subBinX);
5148 boxTLX = std::max(boxTLX, minX);
5149 int boxTLY = starCenter.y() - boxSize / (2 * subBinY);
5150 boxTLY = std::max(boxTLY, minY);
5151 const int boxBRX = boxTLX + (boxSize / subBinX);
5153 boxTLX -= boxBRX - maxX;
5154 const int boxBRY = boxTLY + (boxSize / subBinY);
5156 boxTLY -= boxBRY - maxY;
5158 starRect =
QRect(boxTLX, boxTLY, boxSize / subBinX, boxSize / subBinY);
5160 m_FocusView->setTrackingBoxEnabled(
true);
5161 m_FocusView->setTrackingBox(starRect);
5164void Focus::showFITSViewer()
5166 static int lastFVTabID = -1;
5173 fv->loadData(m_ImageData, url, &lastFVTabID);
5174 connect(fv.get(), &FITSViewer::terminated,
this, [
this]()
5179 else if (fv->updateData(m_ImageData, url, lastFVTabID, &lastFVTabID) ==
false)
5180 fv->loadData(m_ImageData, url, &lastFVTabID);
5186void Focus::adjustFocusOffset(
int value,
bool useAbsoluteOffset)
5189 if (inAdjustFocus || adaptFocus->inAdaptiveFocus())
5191 QString str = inAdjustFocus ?
i18n(
"Adjust Focus") :
i18n(
"Adaptive Focus");
5192 if (++m_StartRetries < MAXIMUM_RESTART_ITERATIONS)
5194 appendLogText(
i18n(
"Adjust focus request - Waiting 10sec for %1 to complete.", str));
5197 adjustFocusOffset(value, useAbsoluteOffset);
5202 qCDebug(KSTARS_EKOS_FOCUS) <<
"adjustFocusOffset called whilst" << str <<
"in progress. Ignoring...";
5203 emit focusPositionAdjusted();
5208 inAdjustFocus =
true;
5211 int newPosition = (useAbsoluteOffset) ? value : value + currentPosition;
5213 if (!changeFocus(newPosition - currentPosition))
5214 qCDebug(KSTARS_EKOS_FOCUS) <<
"adjustFocusOffset unable to move focuser";
5217void Focus::toggleFocusingWidgetFullScreen()
5219 if (focusingWidget->parent() ==
nullptr)
5221 focusingWidget->setParent(
this);
5222 rightLayout->insertWidget(0, focusingWidget);
5223 focusingWidget->showNormal();
5227 focusingWidget->setParent(
nullptr);
5228 focusingWidget->setWindowTitle(
i18nc(
"@title:window",
"Focus Frame"));
5230 focusingWidget->showMaximized();
5231 focusingWidget->show();
5235void Focus::setMountStatus(ISD::Mount::Status newState)
5239 case ISD::Mount::MOUNT_PARKING:
5240 case ISD::Mount::MOUNT_SLEWING:
5241 case ISD::Mount::MOUNT_MOVING:
5242 captureB->setEnabled(
false);
5243 startFocusB->setEnabled(
false);
5244 startAbInsB->setEnabled(
false);
5245 startLoopB->setEnabled(
false);
5260void Focus::setMountCoords(
const SkyPoint &position, ISD::Mount::PierSide pierSide,
const dms &ha)
5269 auto name = deviceRemoved->getDeviceName();
5273 if (m_Focuser && m_Focuser->getDeviceName() == name)
5275 m_Focuser->disconnect(
this);
5276 m_Focuser =
nullptr;
5285 for (
auto &oneSource : m_TemperatureSources)
5287 if (oneSource->getDeviceName() == name)
5290 if (m_LastSourceDeviceAutofocusTemperature && m_LastSourceDeviceAutofocusTemperature->getDeviceName() == name)
5291 m_LastSourceDeviceAutofocusTemperature.reset(
nullptr);
5293 m_TemperatureSources.removeAll(oneSource);
5296 defaultFocusTemperatureSource->removeItem(defaultFocusTemperatureSource->findText(name));
5303 if (m_Camera && m_Camera->getDeviceName() == name)
5305 m_Camera->disconnect(
this);
5316 if (m_FilterWheel && m_FilterWheel->getDeviceName() == name)
5318 m_FilterWheel->disconnect(
this);
5319 m_FilterWheel =
nullptr;
5329void Focus::setupFilterManager()
5332 if (m_FilterManager)
5333 m_FilterManager->disconnect(
this);
5336 Ekos::Manager::Instance()->createFilterManager(m_FilterWheel);
5339 Ekos::Manager::Instance()->getFilterManager(m_FilterWheel->getDeviceName(), m_FilterManager);
5344 connect(
this, &Focus::absolutePositionChanged, m_FilterManager.get(), &FilterManager::setFocusAbsolutePosition);
5347 connect(
this, &Focus::newStatus,
this, [
this](Ekos::FocusState state)
5349 if (m_FilterManager)
5351 m_FilterManager->setFocusStatus(state);
5352 if (focusFilter->currentIndex() != -1 && canAbsMove && state == Ekos::FOCUS_COMPLETE)
5354 m_FilterManager->setFilterAbsoluteFocusDetails(focusFilter->currentIndex(), currentPosition,
5355 m_LastSourceAutofocusTemperature, m_LastSourceAutofocusAlt);
5363 connect(m_FilterManager.get(), &FilterManager::newStatus,
this, [
this](Ekos::FilterState filterState)
5366 if (filterState == FILTER_OFFSET && state() != Ekos::FOCUS_PROGRESS)
5368 if (m_GuidingSuspended == false && m_OpsFocusSettings->focusSuspendGuiding->isChecked())
5370 m_GuidingSuspended = true;
5371 emit suspendGuiding();
5377 connect(m_FilterManager.get(), &FilterManager::ready,
this, [
this]()
5380 if (focusFilter->currentIndex() != currentFilterPosition - 1)
5381 focusFilter->setCurrentIndex(currentFilterPosition - 1);
5383 if (filterPositionPending)
5385 filterPositionPending = false;
5388 else if (fallbackFilterPending)
5390 fallbackFilterPending =
false;
5391 setState(m_pendingState);
5392 m_pendingState = FOCUS_IDLE;
5397 connect(m_FilterManager.get(), &FilterManager::failed,
this, [
this]()
5399 if (filterPositionPending)
5401 appendLogText(i18n(
"Filter operation failed."));
5402 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_FILTER_MANAGER);
5407 connect(m_FilterManager.get(), &FilterManager::runAutoFocus,
this, &Focus::runAutoFocus);
5410 connect(m_FilterManager.get(), &FilterManager::abortAutoFocus,
this, &Focus::abort);
5413 connect(m_FilterManager.get(), &FilterManager::newFocusOffset,
this, &Focus::adjustFocusOffset);
5416 connect(m_FilterManager.get(), &FilterManager::labelsChanged,
this, [
this]()
5418 focusFilter->clear();
5419 focusFilter->addItems(m_FilterManager->getFilterLabels());
5420 currentFilterPosition = m_FilterManager->getFilterPosition();
5421 focusFilter->setCurrentIndex(currentFilterPosition - 1);
5425 connect(m_FilterManager.get(), &FilterManager::positionChanged,
this, [
this]()
5427 currentFilterPosition = m_FilterManager->getFilterPosition();
5428 focusFilter->setCurrentIndex(currentFilterPosition - 1);
5432 connect(m_FilterManager.get(), &FilterManager::exposureChanged,
this, [
this]()
5434 focusExposure->setValue(m_FilterManager->getFilterExposure());
5438 connect(m_FilterManager.get(), &FilterManager::wavelengthChanged,
this, [
this]()
5440 wavelengthChanged();
5444void Focus::connectFilterManager()
5449 if (m_FilterManager)
5451 m_FilterManager->refreshFilterModel();
5452 m_FilterManager->show();
5453 m_FilterManager->raise();
5458 connect(
this, &Focus::focusPositionAdjusted,
this, [
this]()
5460 if (m_FilterManager)
5461 m_FilterManager->setFocusOffsetComplete();
5462 if (m_GuidingSuspended && state() != Ekos::FOCUS_PROGRESS)
5464 QTimer::singleShot(m_OpsFocusMechanics->focusSettleTime->value() * 1000,
this, [
this]()
5466 m_GuidingSuspended = false;
5467 emit resumeGuiding();
5476 if (inAutoFocus && m_OpsFocusProcess->focusDonut->isEnabled())
5479 if (m_FilterManager)
5480 m_FilterManager->setFilterExposure(focusFilter->currentIndex(), focusExposure->value());
5486 if (m_FilterManager)
5488 focusExposure->setValue(m_FilterManager->getFilterExposure(text));
5496void Focus::toggleVideo(
bool enabled)
5498 if (m_Camera ==
nullptr)
5501 if (m_Camera->isBLOBEnabled() ==
false)
5504 if (Options::guiderType() != Ekos::Guide::GUIDE_INTERNAL)
5505 m_Camera->setBLOBEnabled(
true);
5512 m_Camera->setVideoStreamEnabled(enabled);
5514 KSMessageBox::Instance()->questionYesNo(
i18n(
"Image transfer is disabled for this camera. Would you like to enable it?"));
5518 m_Camera->setVideoStreamEnabled(enabled);
5534void Focus::setVideoStreamEnabled(
bool enabled)
5538 liveVideoB->setChecked(
true);
5543 liveVideoB->setChecked(
false);
5548void Focus::processCaptureTimeout()
5550 m_captureInProgress =
false;
5552 if (m_abortInProgress)
5555 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding frame in " << __FUNCTION__;
5559 captureTimeoutCounter++;
5561 if (captureTimeoutCounter >= 3)
5563 captureTimeoutCounter = 0;
5564 m_MissingCameraCounter = 0;
5565 captureTimeout.stop();
5566 appendLogText(
i18n(
"Exposure timeout. Aborting..."));
5567 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_TIMEOUT);
5571 appendLogText(
i18n(
"Exposure timeout. Restarting exposure..."));
5572 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
5573 targetChip->abortExposure();
5575 capture(focusExposure->value());
5579 else if (m_MissingCameraCounter < 40)
5581 m_MissingCameraCounter++;
5582 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unable to restart focus exposure as camera is missing, trying again in 5 seconds...";
5587 m_MissingCameraCounter = 0;
5588 captureTimeoutCounter = 0;
5589 captureTimeout.stop();
5590 appendLogText(
i18n(
"Exposure timeout. Aborting..."));
5591 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_TIMEOUT);
5596void Focus::processCaptureErrorDefault()
5598 processCaptureError(ISD::Camera::ERROR_CAPTURE);
5603 m_captureInProgress =
false;
5604 captureTimeout.stop();
5606 if (m_abortInProgress)
5608 qCDebug(KSTARS_EKOS_FOCUS) <<
"Abort AF: discarding frame in " << __FUNCTION__;
5614 appendLogText(
i18n(
"Failed to save image. Aborting..."));
5615 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
5622 captureFailureCounter++;
5624 if (captureFailureCounter >= 3)
5626 captureFailureCounter = 0;
5627 captureTimeoutCounter = 0;
5628 m_MissingCameraCounter = 0;
5629 appendLogText(
i18n(
"Exposure failure. Aborting..."));
5630 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
5634 ISD::CameraChip *targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
5635 targetChip->abortExposure();
5636 capture(focusExposure->value());
5640 else if (m_MissingCameraCounter < 40)
5642 m_MissingCameraCounter++;
5643 qCDebug(KSTARS_EKOS_FOCUS) <<
"Unable to restart focus exposure as camera is missing, trying again in 5 seconds...";
5650 m_MissingCameraCounter = 0;
5651 captureFailureCounter = 0;
5652 captureTimeoutCounter = 0;
5653 captureTimeout.stop();
5654 appendLogText(
i18n(
"Exposure failure. Aborting..."));
5655 completeFocusProcedure(Ekos::FOCUS_ABORTED, Ekos::FOCUS_FAIL_CAPTURE_FAILED);
5659void Focus::syncSettings()
5672 if ( (dsb = qobject_cast<QDoubleSpinBox*>(sender())))
5675 value = dsb->
value();
5678 else if ( (sb = qobject_cast<QSpinBox*>(sender())))
5681 value = sb->
value();
5683 else if ( (cb = qobject_cast<QCheckBox*>(sender())))
5688 else if ( (gb = qobject_cast<QGroupBox*>(sender())))
5693 else if ( (rb = qobject_cast<QRadioButton*>(sender())))
5699 m_Settings.remove(key);
5704 else if ( (cbox = qobject_cast<QComboBox*>(sender())))
5709 else if ( (s = qobject_cast<QSplitter*>(sender())))
5717 Options::self()->setProperty(key.
toLatin1(), value);
5719 m_Settings[key] = value;
5720 m_GlobalSettings[key] = value;
5724 m_DebounceTimer.start();
5730void Focus::settleSettings()
5732 emit settingsUpdated(getAllSettings());
5734 OpticalTrainSettings::Instance()->setOpticalTrainID(OpticalTrainManager::Instance()->
id(opticalTrainCombo->currentText()));
5735 OpticalTrainSettings::Instance()->setOneSetting(OpticalTrainSettings::Focus, m_Settings);
5738void Focus::loadGlobalSettings()
5743 QVariantMap settings;
5745 for (
auto &oneWidget : findChildren<QComboBox*>())
5747 if (oneWidget->objectName() ==
"opticalTrainCombo")
5750 key = oneWidget->objectName();
5751 value = Options::self()->property(key.
toLatin1());
5752 if (value.
isValid() && oneWidget->count() > 0)
5754 oneWidget->setCurrentText(value.
toString());
5755 settings[key] = value;
5758 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
5762 for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
5764 key = oneWidget->objectName();
5765 value = Options::self()->property(key.
toLatin1());
5768 oneWidget->setValue(value.
toDouble());
5769 settings[key] = value;
5772 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
5776 for (
auto &oneWidget : findChildren<QSpinBox*>())
5778 key = oneWidget->objectName();
5779 value = Options::self()->property(key.
toLatin1());
5782 oneWidget->setValue(value.
toInt());
5783 settings[key] = value;
5786 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
5790 for (
auto &oneWidget : findChildren<QCheckBox*>())
5792 key = oneWidget->objectName();
5793 value = Options::self()->property(key.
toLatin1());
5796 oneWidget->setChecked(value.
toBool());
5797 settings[key] = value;
5799 else if (key != forceInSeqAF->objectName())
5800 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
5804 for (
auto &oneWidget : findChildren<QGroupBox*>())
5806 if (oneWidget->isCheckable())
5808 key = oneWidget->objectName();
5809 value = Options::self()->property(key.
toLatin1());
5812 oneWidget->setChecked(value.
toBool());
5813 settings[key] = value;
5816 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
5821 for (
auto &oneWidget : findChildren<QSplitter*>())
5823 key = oneWidget->objectName();
5824 value = Options::self()->property(key.
toLatin1());
5829 oneWidget->restoreState(valueBA);
5830 settings[key] = valueBA;
5833 qCDebug(KSTARS_EKOS_FOCUS) <<
"Option" << key <<
"not found!";
5837 for (
auto &oneWidget : findChildren<QRadioButton*>())
5839 key = oneWidget->objectName();
5840 value = Options::self()->property(key.
toLatin1());
5843 oneWidget->setChecked(value.
toBool());
5844 settings[key] = value;
5849 m_GlobalSettings = m_Settings = settings;
5852void Focus::checkMosaicMaskLimits()
5854 if (m_Camera ==
nullptr || m_Camera->isConnected() ==
false)
5856 auto targetChip = m_Camera->getChip(ISD::CameraChip::PRIMARY_CCD);
5857 if (targetChip ==
nullptr || frameSettings.contains(targetChip) ==
false)
5859 auto settings = frameSettings[targetChip];
5862 auto width = settings[
"w"].toInt();
5863 auto height = settings[
"h"].toInt();
5864 if (width == 0 || height == 0)
5868 auto min = std::min(width, height);
5870 m_OpsFocusSettings->focusMosaicTileWidth->setMaximum(100 * min / (3 * width));
5873void Focus::connectSyncSettings()
5876 for (
auto &oneWidget : findChildren<QComboBox*>())
5878 if (oneWidget != opticalTrainCombo)
5882 for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
5886 for (
auto &oneWidget : findChildren<QSpinBox*>())
5890 for (
auto &oneWidget : findChildren<QCheckBox*>())
5894 for (
auto &oneWidget : findChildren<QGroupBox*>())
5895 if (oneWidget->isCheckable())
5899 for (
auto &oneWidget : findChildren<QSplitter*>())
5903 for (
auto &oneWidget : findChildren<QRadioButton*>())
5907void Focus::disconnectSyncSettings()
5910 for (
auto &oneWidget : findChildren<QComboBox*>())
5911 disconnect(oneWidget, QOverload<int>::of(&
QComboBox::activated),
this, &Ekos::Focus::syncSettings);
5914 for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
5918 for (
auto &oneWidget : findChildren<QSpinBox*>())
5922 for (
auto &oneWidget : findChildren<QCheckBox*>())
5926 for (
auto &oneWidget : findChildren<QGroupBox*>())
5927 if (oneWidget->isCheckable())
5931 for (
auto &oneWidget : findChildren<QSplitter*>())
5935 for (
auto &oneWidget : findChildren<QRadioButton*>())
5939void Focus::initPlots()
5943 profileDialog =
new QDialog(
this);
5946 profileDialog->setWindowTitle(
i18nc(
"@title:window",
"Relative Profile"));
5947 profilePlot =
new FocusProfilePlot(profileDialog);
5950 profileDialog->setLayout(profileLayout);
5951 profileDialog->resize(400, 300);
5954 connect(
this, &Ekos::Focus::newHFR, [
this](
double currentHFR,
int pos)
5956 Q_UNUSED(pos) profilePlot->drawProfilePlot(currentHFR);
5960void Focus::initConnections()
5963 waitStarSelectTimer.setInterval(AUTO_STAR_TIMEOUT);
5968 m_DebounceTimer.setInterval(500);
5969 m_DebounceTimer.setSingleShot(
true);
5984 captureTimer.setSingleShot(
true);
5991 captureTimeout.setSingleShot(
true);
6026 &Ekos::Focus::updateBoxSize);
6032 m_CFZDialog->show();
6033 m_CFZDialog->raise();
6039 focusAdvisor->setButtons(
false);
6040 focusAdvisor->show();
6041 focusAdvisor->raise();
6047 emit inSequenceAF(enabled, opticalTrain());
6053 setFocusDetection(static_cast<StarAlgorithm>(index));
6059 setFocusAlgorithm(static_cast<Algorithm>(index));
6065 this, [&](
int index)
6067 setCurveFit(static_cast<CurveFitting::CurveFit>(index));
6072 this, [&](
int index)
6074 setStarMeasure(static_cast<StarMeasure>(index));
6079 this, [&](
int index)
6081 setStarPSF(static_cast<StarPSF>(index));
6086 this, [&](
int index)
6088 setStarUnits(static_cast<StarUnits>(index));
6093 this, [&](
int index)
6095 setWalk(static_cast<FocusWalk>(index));
6106 starCenter = QVector3D();
6107 starSelected = false;
6108 m_FocusView->setTrackingBox(QRect());
6116 &Ekos::Focus::calcCFZ);
6119 &Ekos::Focus::calcCFZ);
6160void Focus::setFocusDetection(StarAlgorithm starAlgorithm)
6162 static bool first =
true;
6163 if (!first && m_FocusDetection == starAlgorithm)
6168 m_FocusDetection = starAlgorithm;
6171 setFocusAlgorithm(m_FocusAlgorithm);
6172 setAutoStarAndBox();
6180void Focus::setAutoStarAndBox()
6182 if (m_FocusDetection == ALGORITHM_BAHTINOV)
6184 m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
false);
6185 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
6186 m_OpsFocusSettings->focusBoxSize->setEnabled(m_OpsFocusSettings->focusSubFrame->isChecked());
6187 m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(m_OpsFocusSettings->focusSubFrame->isChecked());
6188 m_OpsFocusSettings->focusBoxSize->setMaximum(512);
6189 if (m_OpsFocusSettings->focusBoxSize->value() > 512)
6190 m_OpsFocusSettings->focusBoxSize->setValue(m_OpsFocusSettings->focusBoxSize->value());
6192 else if(m_OpsFocusSettings->focusSubFrame->isChecked())
6194 if(isStarMeasureStarBased())
6196 m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
true);
6198 m_OpsFocusSettings->focusBoxSize->setEnabled(
true);
6199 m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(
true);
6200 if (m_OpsFocusSettings->focusBoxSize->value() > 256)
6201 m_OpsFocusSettings->focusBoxSize->setValue(m_OpsFocusSettings->focusBoxSize->value());
6202 m_OpsFocusSettings->focusBoxSize->setMaximum(256);
6206 m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
false);
6207 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
6210 m_OpsFocusSettings->focusBoxSize->setEnabled(
true);
6211 m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(
true);
6212 int maxSize = std::min(m_CcdWidth, m_CcdHeight);
6213 int step = m_OpsFocusSettings->focusBoxSize->singleStep();
6214 maxSize = std::max(256, (maxSize / step) * step);
6215 m_OpsFocusSettings->focusBoxSize->setMaximum(maxSize);
6221 m_OpsFocusSettings->focusAutoStarEnabled->setEnabled(
false);
6222 m_OpsFocusSettings->focusAutoStarEnabled->setChecked(
false);
6223 m_OpsFocusSettings->focusBoxSize->setEnabled(
false);
6224 m_OpsFocusSettings->focusBoxSizeLabel->setEnabled(
false);
6229void Focus::setFocusAlgorithm(Algorithm algorithm)
6231 m_FocusAlgorithm = algorithm;
6234 case FOCUS_ITERATIVE:
6236 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
6237 m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
6238 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
6239 m_OpsFocusProcess->focusMultiRowAverage->hide();
6241 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
6242 m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
6243 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
6244 m_OpsFocusProcess->focusGaussianSigma->hide();
6246 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
6247 m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
6248 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
6249 m_OpsFocusProcess->focusGaussianKernelSize->hide();
6251 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarMeasureLabel);
6252 m_OpsFocusProcess->focusStarMeasureLabel->hide();
6253 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarMeasure);
6254 m_OpsFocusProcess->focusStarMeasure->hide();
6256 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6257 m_OpsFocusProcess->focusStarPSFLabel->hide();
6258 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6259 m_OpsFocusProcess->focusStarPSF->hide();
6261 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
6262 m_OpsFocusProcess->focusUseWeights->hide();
6264 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2LimitLabel);
6265 m_OpsFocusProcess->focusR2LimitLabel->hide();
6266 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2Limit);
6267 m_OpsFocusProcess->focusR2Limit->hide();
6269 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusRefineCurveFit);
6270 m_OpsFocusProcess->focusRefineCurveFit->hide();
6271 m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
6273 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
6274 m_OpsFocusProcess->focusToleranceLabel->hide();
6275 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusTolerance);
6276 m_OpsFocusProcess->focusTolerance->hide();
6278 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
6279 m_OpsFocusProcess->focusThresholdLabel->hide();
6280 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
6281 m_OpsFocusProcess->focusThreshold->hide();
6283 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusCurveFitLabel);
6284 m_OpsFocusProcess->focusCurveFitLabel->hide();
6285 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusCurveFit);
6286 m_OpsFocusProcess->focusCurveFit->hide();
6288 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
6289 m_OpsFocusProcess->focusDenoise->hide();
6292 m_OpsFocusProcess->focusDonut->hide();
6293 m_OpsFocusProcess->focusDonut->setChecked(
false);
6296 m_OpsFocusProcess->focusScanStartPos->hide();
6297 m_OpsFocusProcess->focusScanStartPos->setChecked(
false);
6300 m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_QUADRATIC);
6303 if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
6305 m_OpsFocusProcess->focusStarMeasure->clear();
6306 m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
6307 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6311 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusToleranceLabel, 3, 0);
6312 m_OpsFocusProcess->focusToleranceLabel->show();
6313 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusTolerance, 3, 1);
6314 m_OpsFocusProcess->focusTolerance->show();
6316 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 3, 2);
6317 m_OpsFocusProcess->focusFramesCountLabel->show();
6318 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 3, 3);
6319 m_OpsFocusProcess->focusFramesCount->show();
6321 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 4, 2);
6322 m_OpsFocusProcess->focusHFRFramesCountLabel->show();
6323 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 4, 3);
6324 m_OpsFocusProcess->focusHFRFramesCount->show();
6326 if (m_FocusDetection == ALGORITHM_THRESHOLD)
6328 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 5, 0);
6329 m_OpsFocusProcess->focusThresholdLabel->show();
6330 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 5, 1);
6331 m_OpsFocusProcess->focusThreshold->show();
6333 else if (m_FocusDetection == ALGORITHM_BAHTINOV)
6335 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 5, 0);
6336 m_OpsFocusProcess->focusMultiRowAverageLabel->show();
6337 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 5, 1);
6338 m_OpsFocusProcess->focusMultiRowAverage->show();
6340 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 5, 2);
6341 m_OpsFocusProcess->focusGaussianSigmaLabel->show();
6342 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 5, 3);
6343 m_OpsFocusProcess->focusGaussianSigma->show();
6345 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 6, 0);
6346 m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
6347 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 6, 1);
6348 m_OpsFocusProcess->focusGaussianKernelSize->show();
6352 startAbInsB->setEnabled(canAbInsStart());
6356 m_OpsFocusSettings->focusAdaptive->setChecked(
false);
6357 m_OpsFocusSettings->focusAdaptStart->setChecked(
false);
6358 m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(
false);
6361 m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
true);
6362 m_OpsFocusMechanics->focusOutSteps->setEnabled(
false);
6365 if (m_OpsFocusMechanics->focusWalk->count() != 1)
6367 m_OpsFocusMechanics->focusWalk->clear();
6368 m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
6369 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
6373 case FOCUS_POLYNOMIAL:
6375 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
6376 m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
6377 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
6378 m_OpsFocusProcess->focusMultiRowAverage->hide();
6380 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
6381 m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
6382 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
6383 m_OpsFocusProcess->focusGaussianSigma->hide();
6385 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
6386 m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
6387 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
6388 m_OpsFocusProcess->focusGaussianKernelSize->hide();
6390 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6391 m_OpsFocusProcess->focusStarPSFLabel->hide();
6392 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6393 m_OpsFocusProcess->focusStarPSF->hide();
6395 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
6396 m_OpsFocusProcess->focusUseWeights->hide();
6398 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2LimitLabel);
6399 m_OpsFocusProcess->focusR2LimitLabel->hide();
6400 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2Limit);
6401 m_OpsFocusProcess->focusR2Limit->hide();
6403 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusRefineCurveFit);
6404 m_OpsFocusProcess->focusRefineCurveFit->hide();
6405 m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
6407 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
6408 m_OpsFocusProcess->focusToleranceLabel->hide();
6409 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusTolerance);
6410 m_OpsFocusProcess->focusTolerance->hide();
6412 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
6413 m_OpsFocusProcess->focusThresholdLabel->hide();
6414 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
6415 m_OpsFocusProcess->focusThreshold->hide();
6417 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
6418 m_OpsFocusProcess->focusDenoise->hide();
6421 m_OpsFocusProcess->focusDonut->hide();
6422 m_OpsFocusProcess->focusDonut->setChecked(
false);
6425 m_OpsFocusProcess->focusScanStartPos->hide();
6426 m_OpsFocusProcess->focusScanStartPos->setChecked(
false);
6429 if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
6431 m_OpsFocusProcess->focusStarMeasure->clear();
6432 m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
6433 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6438 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFitLabel, 1, 2);
6439 m_OpsFocusProcess->focusCurveFitLabel->show();
6440 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFit, 1, 3);
6441 m_OpsFocusProcess->focusCurveFit->show();
6442 if (m_OpsFocusProcess->focusCurveFit->count() != 1)
6444 m_OpsFocusProcess->focusCurveFit->clear();
6445 m_OpsFocusProcess->focusCurveFit->addItem(m_CurveFitText.at(CurveFitting::FOCUS_QUADRATIC));
6446 m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_QUADRATIC);
6449 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusToleranceLabel, 3, 0);
6450 m_OpsFocusProcess->focusToleranceLabel->show();
6451 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusTolerance, 3, 1);
6452 m_OpsFocusProcess->focusTolerance->show();
6454 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 3, 2);
6455 m_OpsFocusProcess->focusFramesCountLabel->show();
6456 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 3, 3);
6457 m_OpsFocusProcess->focusFramesCount->show();
6459 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 4, 2);
6460 m_OpsFocusProcess->focusHFRFramesCountLabel->show();
6461 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 4, 3);
6462 m_OpsFocusProcess->focusHFRFramesCount->show();
6464 if (m_FocusDetection == ALGORITHM_THRESHOLD)
6466 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 5, 0);
6467 m_OpsFocusProcess->focusThresholdLabel->show();
6468 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 5, 1);
6469 m_OpsFocusProcess->focusThreshold->show();
6471 else if (m_FocusDetection == ALGORITHM_BAHTINOV)
6473 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 5, 0);
6474 m_OpsFocusProcess->focusMultiRowAverageLabel->show();
6475 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 5, 1);
6476 m_OpsFocusProcess->focusMultiRowAverage->show();
6478 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 5, 2);
6479 m_OpsFocusProcess->focusGaussianSigmaLabel->show();
6480 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 5, 3);
6481 m_OpsFocusProcess->focusGaussianSigma->show();
6483 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 6, 0);
6484 m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
6485 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 6, 1);
6486 m_OpsFocusProcess->focusGaussianKernelSize->show();
6490 startAbInsB->setEnabled(canAbInsStart());
6494 m_OpsFocusSettings->focusAdaptive->setChecked(
false);
6495 m_OpsFocusSettings->focusAdaptStart->setChecked(
false);
6496 m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(
false);
6499 m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
true);
6500 m_OpsFocusMechanics->focusOutSteps->setEnabled(
false);
6503 if (m_OpsFocusMechanics->focusWalk->count() != 1)
6505 m_OpsFocusMechanics->focusWalk->clear();
6506 m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
6507 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
6513 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
6514 m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
6515 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
6516 m_OpsFocusProcess->focusMultiRowAverage->hide();
6518 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
6519 m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
6520 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
6521 m_OpsFocusProcess->focusGaussianSigma->hide();
6523 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
6524 m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
6525 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
6526 m_OpsFocusProcess->focusGaussianKernelSize->hide();
6528 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
6529 m_OpsFocusProcess->focusThresholdLabel->hide();
6530 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
6531 m_OpsFocusProcess->focusThreshold->hide();
6533 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6534 m_OpsFocusProcess->focusStarPSFLabel->hide();
6535 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6536 m_OpsFocusProcess->focusStarPSF->hide();
6538 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
6539 m_OpsFocusProcess->focusUseWeights->hide();
6541 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2LimitLabel);
6542 m_OpsFocusProcess->focusR2LimitLabel->hide();
6543 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusR2Limit);
6544 m_OpsFocusProcess->focusR2Limit->hide();
6546 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusRefineCurveFit);
6547 m_OpsFocusProcess->focusRefineCurveFit->hide();
6548 m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
6550 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
6551 m_OpsFocusProcess->focusDenoise->hide();
6554 m_OpsFocusProcess->focusDonut->hide();
6555 m_OpsFocusProcess->focusDonut->setChecked(
false);
6558 m_OpsFocusProcess->focusScanStartPos->hide();
6559 m_OpsFocusProcess->focusScanStartPos->setChecked(
false);
6562 if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
6564 m_OpsFocusProcess->focusStarMeasure->clear();
6565 m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
6566 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6571 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFitLabel, 1, 2);
6572 m_OpsFocusProcess->focusCurveFitLabel->show();
6573 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFit, 1, 3);
6574 m_OpsFocusProcess->focusCurveFit->show();
6575 if (m_OpsFocusProcess->focusCurveFit->count() != 1)
6577 m_OpsFocusProcess->focusCurveFit->clear();
6578 m_OpsFocusProcess->focusCurveFit->addItem(m_CurveFitText.at(CurveFitting::FOCUS_QUADRATIC));
6579 m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_QUADRATIC);
6582 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusToleranceLabel, 3, 0);
6583 m_OpsFocusProcess->focusToleranceLabel->show();
6584 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusTolerance, 3, 1);
6585 m_OpsFocusProcess->focusTolerance->show();
6587 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 3, 2);
6588 m_OpsFocusProcess->focusFramesCountLabel->show();
6589 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 3, 3);
6590 m_OpsFocusProcess->focusFramesCount->show();
6592 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 4, 2);
6593 m_OpsFocusProcess->focusHFRFramesCountLabel->show();
6594 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 4, 3);
6595 m_OpsFocusProcess->focusHFRFramesCount->show();
6597 if (m_FocusDetection == ALGORITHM_THRESHOLD)
6599 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 5, 0);
6600 m_OpsFocusProcess->focusThresholdLabel->show();
6601 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 5, 1);
6602 m_OpsFocusProcess->focusThreshold->show();
6604 else if (m_FocusDetection == ALGORITHM_BAHTINOV)
6606 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 5, 0);
6607 m_OpsFocusProcess->focusMultiRowAverageLabel->show();
6608 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 5, 1);
6609 m_OpsFocusProcess->focusMultiRowAverage->show();
6611 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 5, 2);
6612 m_OpsFocusProcess->focusGaussianSigmaLabel->show();
6613 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 5, 3);
6614 m_OpsFocusProcess->focusGaussianSigma->show();
6616 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 6, 0);
6617 m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
6618 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 6, 1);
6619 m_OpsFocusProcess->focusGaussianKernelSize->show();
6623 startAbInsB->setEnabled(canAbInsStart());
6627 m_OpsFocusSettings->focusAdaptive->setChecked(
false);
6628 m_OpsFocusSettings->focusAdaptStart->setChecked(
false);
6629 m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(
false);
6632 m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
false);
6633 m_OpsFocusMechanics->focusOutSteps->setEnabled(
true);
6636 if (m_OpsFocusMechanics->focusWalk->count() != 1)
6638 m_OpsFocusMechanics->focusWalk->clear();
6639 m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
6640 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
6644 case FOCUS_LINEAR1PASS:
6646 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverageLabel);
6647 m_OpsFocusProcess->focusMultiRowAverageLabel->hide();
6648 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusMultiRowAverage);
6649 m_OpsFocusProcess->focusMultiRowAverage->hide();
6651 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigmaLabel);
6652 m_OpsFocusProcess->focusGaussianSigmaLabel->hide();
6653 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianSigma);
6654 m_OpsFocusProcess->focusGaussianSigma->hide();
6656 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel);
6657 m_OpsFocusProcess->focusGaussianKernelSizeLabel->hide();
6658 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusGaussianKernelSize);
6659 m_OpsFocusProcess->focusGaussianKernelSize->hide();
6661 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThresholdLabel);
6662 m_OpsFocusProcess->focusThresholdLabel->hide();
6663 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusThreshold);
6664 m_OpsFocusProcess->focusThreshold->hide();
6666 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusToleranceLabel);
6667 m_OpsFocusProcess->focusToleranceLabel->hide();
6668 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusTolerance);
6669 m_OpsFocusProcess->focusTolerance->hide();
6673 if (m_FocusDetection == ALGORITHM_SEP && m_CurveFit != CurveFitting::FOCUS_QUADRATIC)
6675 if (m_OpsFocusProcess->focusStarMeasure->count() != m_StarMeasureText.count())
6677 m_OpsFocusProcess->focusStarMeasure->clear();
6678 m_OpsFocusProcess->focusStarMeasure->addItems(m_StarMeasureText);
6679 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6683#if !defined(HAVE_OPENCV)
6691 else if (m_FocusDetection != ALGORITHM_SEP || m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
6693 if (m_OpsFocusProcess->focusStarMeasure->count() != 1)
6695 m_OpsFocusProcess->focusStarMeasure->clear();
6696 m_OpsFocusProcess->focusStarMeasure->addItem(m_StarMeasureText.at(FOCUS_STAR_HFR));
6697 m_OpsFocusProcess->focusStarMeasure->setCurrentIndex(FOCUS_STAR_HFR);
6703 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFitLabel, 1, 2);
6704 m_OpsFocusProcess->focusCurveFitLabel->show();
6705 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusCurveFit, 1, 3);
6706 m_OpsFocusProcess->focusCurveFit->show();
6707 if (m_OpsFocusProcess->focusCurveFit->count() != m_CurveFitText.count())
6709 m_OpsFocusProcess->focusCurveFit->clear();
6710 m_OpsFocusProcess->focusCurveFit->addItems(m_CurveFitText);
6711 m_OpsFocusProcess->focusCurveFit->setCurrentIndex(CurveFitting::FOCUS_HYPERBOLA);
6714 if (m_StarMeasure == FOCUS_STAR_STDDEV || m_StarMeasure == FOCUS_STAR_SOBEL ||
6715 m_StarMeasure == FOCUS_STAR_LAPLASSIAN || m_StarMeasure == FOCUS_STAR_CANNY)
6717 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusUseWeights);
6718 m_OpsFocusProcess->focusUseWeights->hide();
6719 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusDenoise, 3, 0, 1, 2);
6720 m_OpsFocusProcess->focusDenoise->show();
6724 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusDenoise);
6725 m_OpsFocusProcess->focusDenoise->hide();
6726 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusUseWeights, 3, 0, 1, 2);
6727 m_OpsFocusProcess->focusUseWeights->show();
6730 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusR2LimitLabel, 3, 2);
6731 m_OpsFocusProcess->focusR2LimitLabel->show();
6732 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusR2Limit, 3, 3);
6733 m_OpsFocusProcess->focusR2Limit->show();
6735 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusRefineCurveFit, 4, 0, 1, 2);
6736 m_OpsFocusProcess->focusRefineCurveFit->show();
6738 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCountLabel, 4, 2);
6739 m_OpsFocusProcess->focusFramesCountLabel->show();
6740 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusFramesCount, 4, 3);
6741 m_OpsFocusProcess->focusFramesCount->show();
6743 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCountLabel, 5, 2);
6744 m_OpsFocusProcess->focusHFRFramesCountLabel->show();
6745 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusHFRFramesCount, 5, 3);
6746 m_OpsFocusProcess->focusHFRFramesCount->show();
6748 if (m_FocusDetection == ALGORITHM_THRESHOLD)
6750 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThresholdLabel, 6, 0);
6751 m_OpsFocusProcess->focusThresholdLabel->show();
6752 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusThreshold, 6, 1);
6753 m_OpsFocusProcess->focusThreshold->show();
6755 else if (m_FocusDetection == ALGORITHM_BAHTINOV)
6757 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverageLabel, 6, 0);
6758 m_OpsFocusProcess->focusMultiRowAverageLabel->show();
6759 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusMultiRowAverage, 6, 1);
6760 m_OpsFocusProcess->focusMultiRowAverage->show();
6762 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigmaLabel, 6, 2);
6763 m_OpsFocusProcess->focusGaussianSigmaLabel->show();
6764 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianSigma, 6, 3);
6765 m_OpsFocusProcess->focusGaussianSigma->show();
6767 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSizeLabel, 7, 0);
6768 m_OpsFocusProcess->focusGaussianKernelSizeLabel->show();
6769 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusGaussianKernelSize, 7, 1);
6770 m_OpsFocusProcess->focusGaussianKernelSize->show();
6774 m_OpsFocusProcess->focusDonut->show();
6775 m_OpsFocusProcess->focusDonut->setEnabled(
true);
6778 m_OpsFocusProcess->focusScanStartPos->show();
6779 m_OpsFocusProcess->focusScanStartPos->setEnabled(
true);
6782 startAbInsB->setEnabled(canAbInsStart());
6786 m_OpsFocusSettings->adaptiveFocusGroup->setEnabled(canAbsMove);
6790 m_OpsFocusMechanics->focusMaxSingleStep->setEnabled(
false);
6791 m_OpsFocusMechanics->focusOutSteps->setEnabled(
true);
6794 if (m_CurveFit == CurveFitting::FOCUS_QUADRATIC)
6796 if (m_OpsFocusMechanics->focusWalk->count() != 1)
6798 m_OpsFocusMechanics->focusWalk->clear();
6799 m_OpsFocusMechanics->focusWalk->addItem(m_FocusWalkText.at(FOCUS_WALK_CLASSIC));
6800 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
6805 if (m_OpsFocusMechanics->focusWalk->count() != m_FocusWalkText.count())
6807 m_OpsFocusMechanics->focusWalk->clear();
6808 m_OpsFocusMechanics->focusWalk->addItems(m_FocusWalkText);
6809 m_OpsFocusMechanics->focusWalk->setCurrentIndex(FOCUS_WALK_CLASSIC);
6816void Focus::setCurveFit(CurveFitting::CurveFit curve)
6818 if (m_OpsFocusProcess->focusCurveFit->currentIndex() == -1)
6821 static bool first =
true;
6822 if (!first && m_CurveFit == curve)
6828 setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
6835 case CurveFitting::FOCUS_QUADRATIC:
6836 m_OpsFocusProcess->focusR2Limit->setEnabled(
false);
6837 m_OpsFocusProcess->focusRefineCurveFit->setChecked(
false);
6838 m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
false);
6841 case CurveFitting::FOCUS_HYPERBOLA:
6842 m_OpsFocusProcess->focusR2Limit->setEnabled(
true);
6843 m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
true);
6846 case CurveFitting::FOCUS_PARABOLA:
6847 m_OpsFocusProcess->focusR2Limit->setEnabled(
true);
6848 m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
true);
6851 case CurveFitting::FOCUS_2DGAUSSIAN:
6852 m_OpsFocusProcess->focusR2Limit->setEnabled(
true);
6853 m_OpsFocusProcess->focusRefineCurveFit->setEnabled(
true);
6861void Focus::setStarMeasure(StarMeasure starMeasure)
6863 if (m_OpsFocusProcess->focusStarMeasure->currentIndex() == -1)
6866 static bool first =
true;
6867 if (!first && m_StarMeasure == starMeasure)
6872 m_StarMeasure = starMeasure;
6873 setFocusAlgorithm(
static_cast<Algorithm
> (m_OpsFocusProcess->focusAlgorithm->currentIndex()));
6877 setAutoStarAndBox();
6883 switch(m_StarMeasure)
6885 case FOCUS_STAR_HFR:
6886 m_OptDir = CurveFitting::OPTIMISATION_MINIMISE;
6887 m_ScaleCalc = Mathematics::RobustStatistics::ScaleCalculation::SCALE_SESTIMATOR;
6888 m_FocusView->setStarsHFREnabled(
true);
6891 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6892 m_OpsFocusProcess->focusStarPSFLabel->hide();
6893 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6894 m_OpsFocusProcess->focusStarPSF->hide();
6897 case FOCUS_STAR_HFR_ADJ:
6898 m_OptDir = CurveFitting::OPTIMISATION_MINIMISE;
6899 m_ScaleCalc = Mathematics::RobustStatistics::ScaleCalculation::SCALE_SESTIMATOR;
6900 m_FocusView->setStarsHFREnabled(
false);
6903 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6904 m_OpsFocusProcess->focusStarPSFLabel->hide();
6905 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6906 m_OpsFocusProcess->focusStarPSF->hide();
6909 case FOCUS_STAR_FWHM:
6910 m_OptDir = CurveFitting::OPTIMISATION_MINIMISE;
6911 m_ScaleCalc = Mathematics::RobustStatistics::ScaleCalculation::SCALE_SESTIMATOR;
6913 m_FocusView->setStarsHFREnabled(
false);
6916 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusStarPSFLabel, 2, 2);
6917 m_OpsFocusProcess->focusStarPSFLabel->show();
6918 m_OpsFocusProcess->gridLayoutProcess->addWidget(m_OpsFocusProcess->focusStarPSF, 2, 3);
6919 m_OpsFocusProcess->focusStarPSF->show();
6922 case FOCUS_STAR_NUM_STARS:
6923 m_OptDir = CurveFitting::OPTIMISATION_MAXIMISE;
6924 m_ScaleCalc = Mathematics::RobustStatistics::ScaleCalculation::SCALE_SESTIMATOR;
6925 m_FocusView->setStarsHFREnabled(
true);
6928 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6929 m_OpsFocusProcess->focusStarPSFLabel->hide();
6930 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6931 m_OpsFocusProcess->focusStarPSF->hide();
6934 case FOCUS_STAR_FOURIER_POWER:
6935 m_OptDir = CurveFitting::OPTIMISATION_MAXIMISE;
6936 m_ScaleCalc = Mathematics::RobustStatistics::ScaleCalculation::SCALE_SESTIMATOR;
6937 m_FocusView->setStarsHFREnabled(
true);
6940 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6941 m_OpsFocusProcess->focusStarPSFLabel->hide();
6942 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6943 m_OpsFocusProcess->focusStarPSF->hide();
6946 case FOCUS_STAR_STDDEV:
6947 case FOCUS_STAR_SOBEL:
6948 case FOCUS_STAR_LAPLASSIAN:
6949 case FOCUS_STAR_CANNY:
6950 m_OptDir = CurveFitting::OPTIMISATION_MAXIMISE;
6951 m_ScaleCalc = Mathematics::RobustStatistics::ScaleCalculation::SCALE_SESTIMATOR;
6952 m_FocusView->setStarsHFREnabled(
true);
6955 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSFLabel);
6956 m_OpsFocusProcess->focusStarPSFLabel->hide();
6957 m_OpsFocusProcess->gridLayoutProcess->removeWidget(m_OpsFocusProcess->focusStarPSF);
6958 m_OpsFocusProcess->focusStarPSF->hide();
6966void Focus::setStarPSF(StarPSF starPSF)
6968 m_StarPSF = starPSF;
6971void Focus::setStarUnits(StarUnits starUnits)
6973 m_StarUnits = starUnits;
6976void Focus::setWalk(FocusWalk walk)
6978 if (m_OpsFocusMechanics->focusWalk->currentIndex() == -1)
6981 static bool first =
true;
6982 if (!first && m_FocusWalk == walk)
6991 case FOCUS_WALK_CLASSIC:
6992 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusNumStepsLabel,
6993 m_OpsFocusMechanics->focusOutStepsLabel);
6994 m_OpsFocusMechanics->focusNumStepsLabel->hide();
6995 m_OpsFocusMechanics->focusOutStepsLabel->show();
6996 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusNumSteps,
6997 m_OpsFocusMechanics->focusOutSteps);
6998 m_OpsFocusMechanics->focusNumSteps->hide();
6999 m_OpsFocusMechanics->focusOutSteps->show();
7002 case FOCUS_WALK_FIXED_STEPS:
7003 case FOCUS_WALK_CFZ_SHUFFLE:
7004 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutStepsLabel,
7005 m_OpsFocusMechanics->focusNumStepsLabel);
7006 m_OpsFocusMechanics->focusOutStepsLabel->hide();
7007 m_OpsFocusMechanics->focusNumStepsLabel->show();
7008 m_OpsFocusMechanics->gridLayoutMechanics->replaceWidget(m_OpsFocusMechanics->focusOutSteps,
7009 m_OpsFocusMechanics->focusNumSteps);
7010 m_OpsFocusMechanics->focusOutSteps->hide();
7011 m_OpsFocusMechanics->focusNumSteps->show();
7020double Focus::getStarUnits(
const StarMeasure starMeasure,
const StarUnits starUnits)
7022 if (starUnits == FOCUS_UNITS_PIXEL || starMeasure == FOCUS_STAR_NUM_STARS || starMeasure == FOCUS_STAR_FOURIER_POWER
7023 || starMeasure == FOCUS_STAR_STDDEV || starMeasure == FOCUS_STAR_SOBEL || starMeasure == FOCUS_STAR_LAPLASSIAN
7024 || starMeasure == FOCUS_STAR_CANNY)
7026 if (m_CcdPixelSizeX <= 0.0 || m_FocalLength <= 0.0)
7030 return m_CcdPixelSizeX / m_FocalLength * 206.265;
7033void Focus::calcCFZ()
7035 double cfzMicrons, cfzSteps;
7036 double cfzCameraSteps = calcCameraCFZ() / m_CFZUI->focusCFZStepSize->value();
7038 switch(
static_cast<Focus::CFZAlgorithm
> (m_CFZUI->focusCFZAlgorithm->currentIndex()))
7040 case Focus::FOCUS_CFZ_CLASSIC:
7042 cfzMicrons = 4.88f * m_CFZUI->focusCFZTolerance->value() * m_CFZUI->focusCFZWavelength->value() / 1000.0f *
7043 pow(m_CFZUI->focusCFZFNumber->value(), 2.0f);
7044 cfzSteps = cfzMicrons / m_CFZUI->focusCFZStepSize->value();
7045 m_cfzSteps = std::round(std::max(cfzSteps, cfzCameraSteps));
7046 m_CFZUI->focusCFZFormula->setText(
"CFZ = 4.88 t λ f²");
7047 m_CFZUI->focusCFZ->setText(
QString(
"%1 μm").arg(cfzMicrons, 0,
'f', 0));
7048 m_CFZUI->focusCFZSteps->setText(
QString(
"%1 steps").arg(cfzSteps, 0,
'f', 0));
7049 m_CFZUI->focusCFZCameraSteps->setText(
QString(
"%1 steps").arg(cfzCameraSteps, 0,
'f', 0));
7050 m_CFZUI->focusCFZFinal->setText(
QString(
"%1 steps").arg(m_cfzSteps, 0,
'f', 0));
7053 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTauLabel);
7054 m_CFZUI->focusCFZTauLabel->hide();
7055 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTau);
7056 m_CFZUI->focusCFZTau->hide();
7057 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeingLabel);
7058 m_CFZUI->focusCFZSeeingLabel->hide();
7059 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeing);
7060 m_CFZUI->focusCFZSeeing->hide();
7063 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZToleranceLabel, 1, 0);
7064 m_CFZUI->focusCFZToleranceLabel->show();
7065 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTolerance, 1, 1);
7066 m_CFZUI->focusCFZTolerance->show();
7067 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelengthLabel, 2, 0);
7068 m_CFZUI->focusCFZWavelengthLabel->show();
7069 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelength, 2, 1);
7070 m_CFZUI->focusCFZWavelength->show();
7073 case Focus::FOCUS_CFZ_WAVEFRONT:
7075 cfzMicrons = 4.0f * m_CFZUI->focusCFZTolerance->value() * m_CFZUI->focusCFZWavelength->value() / 1000.0f * pow(
7076 m_CFZUI->focusCFZFNumber->value(),
7078 cfzSteps = cfzMicrons / m_CFZUI->focusCFZStepSize->value();
7079 m_cfzSteps = std::round(std::max(cfzSteps, cfzCameraSteps));
7080 m_CFZUI->focusCFZFormula->setText(
"CFZ = 4 t λ f²");
7081 m_CFZUI->focusCFZ->setText(
QString(
"%1 μm").arg(cfzMicrons, 0,
'f', 0));
7082 m_CFZUI->focusCFZSteps->setText(
QString(
"%1 steps").arg(cfzSteps, 0,
'f', 0));
7083 m_CFZUI->focusCFZCameraSteps->setText(
QString(
"%1 steps").arg(cfzCameraSteps, 0,
'f', 0));
7084 m_CFZUI->focusCFZFinal->setText(
QString(
"%1 steps").arg(m_cfzSteps, 0,
'f', 0));
7087 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTauLabel);
7088 m_CFZUI->focusCFZTauLabel->hide();
7089 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTau);
7090 m_CFZUI->focusCFZTau->hide();
7091 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeingLabel);
7092 m_CFZUI->focusCFZSeeingLabel->hide();
7093 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZSeeing);
7094 m_CFZUI->focusCFZSeeing->hide();
7097 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZToleranceLabel, 1, 0);
7098 m_CFZUI->focusCFZToleranceLabel->show();
7099 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTolerance, 1, 1);
7100 m_CFZUI->focusCFZTolerance->show();
7101 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelengthLabel, 2, 0);
7102 m_CFZUI->focusCFZWavelengthLabel->show();
7103 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZWavelength, 2, 1);
7104 m_CFZUI->focusCFZWavelength->show();
7107 case Focus::FOCUS_CFZ_GOLD:
7109 cfzMicrons = 0.00225f * pow(m_CFZUI->focusCFZTau->value(), 0.5f) * m_CFZUI->focusCFZSeeing->value()
7110 * pow(m_CFZUI->focusCFZFNumber->value(), 2.0f) * m_CFZUI->focusCFZAperture->value();
7111 cfzSteps = cfzMicrons / m_CFZUI->focusCFZStepSize->value();
7112 m_cfzSteps = std::round(std::max(cfzSteps, cfzCameraSteps));
7113 m_CFZUI->focusCFZFormula->setText(
"CFZ = 0.00225 √τ θ f² A");
7114 m_CFZUI->focusCFZ->setText(
QString(
"%1 μm").arg(cfzMicrons, 0,
'f', 0));
7115 m_CFZUI->focusCFZSteps->setText(
QString(
"%1 steps").arg(cfzSteps, 0,
'f', 0));
7116 m_CFZUI->focusCFZCameraSteps->setText(
QString(
"%1 steps").arg(cfzCameraSteps, 0,
'f', 0));
7117 m_CFZUI->focusCFZFinal->setText(
QString(
"%1 steps").arg(m_cfzSteps, 0,
'f', 0));
7120 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZToleranceLabel);
7121 m_CFZUI->focusCFZToleranceLabel->hide();
7122 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZTolerance);
7123 m_CFZUI->focusCFZTolerance->hide();
7124 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZWavelengthLabel);
7125 m_CFZUI->focusCFZWavelengthLabel->hide();
7126 m_CFZUI->gridLayoutCFZ->removeWidget(m_CFZUI->focusCFZWavelength);
7127 m_CFZUI->focusCFZWavelength->hide();
7130 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTauLabel, 1, 0);
7131 m_CFZUI->focusCFZTauLabel->show();
7132 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZTau, 1, 1);
7133 m_CFZUI->focusCFZTau->show();
7134 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZSeeingLabel, 2, 0);
7135 m_CFZUI->focusCFZSeeingLabel->show();
7136 m_CFZUI->gridLayoutCFZ->addWidget(m_CFZUI->focusCFZSeeing, 2, 1);
7137 m_CFZUI->focusCFZSeeing->show();
7140 if (linearFocuser !=
nullptr && linearFocuser->isDone())
7141 emit drawCFZ(linearFocuser->solution(), linearFocuser->solutionValue(), m_cfzSteps,
7142 m_CFZUI->focusCFZDisplayVCurve->isChecked());
7148double Focus::calcCameraCFZ()
7150 return m_CcdPixelSizeX * pow(m_CFZUI->focusCFZFNumber->value(), 2.0) * m_CFZUI->focusCFZAperture->value() / 1000.0;
7153void Focus::wavelengthChanged()
7156 if (m_FilterManager)
7158 m_CFZUI->focusCFZWavelength->setValue(m_FilterManager->getFilterWavelength(
filter()));
7163void Focus::resetCFZToOT()
7166 m_CFZUI->focusCFZFNumber->setValue(m_FocalRatio);
7167 m_CFZUI->focusCFZAperture->setValue(m_Aperture);
7170 if (m_FilterManager)
7172 if (m_CFZUI->focusCFZWavelength->value() != m_FilterManager->getFilterWavelength(
filter()))
7173 m_CFZUI->focusCFZWavelength->setValue(m_FilterManager->getFilterWavelength(
filter()));
7178void Focus::setState(FocusState newState)
7180 qCDebug(KSTARS_EKOS_FOCUS) <<
"Focus State changes from" << getFocusStatusString(m_state) <<
"to" << getFocusStatusString(
7183 emit newStatus(m_state, opticalTrain());
7186void Focus::initView()
7188 m_FocusView.reset(
new FITSView(focusingWidget, FITS_FOCUS));
7190 m_FocusView->setBaseSize(focusingWidget->size());
7191 m_FocusView->createFloatingToolBar();
7194 focusingWidget->setLayout(vlayout);
7196 m_FocusView->setStarsEnabled(
true);
7197 m_FocusView->setStarsHFREnabled(
true);
7200QVariantMap Focus::getAllSettings()
const
7202 QVariantMap settings;
7205 for (
auto &oneWidget : findChildren<QComboBox*>())
7206 settings.insert(oneWidget->objectName(), oneWidget->currentText());
7209 for (
auto &oneWidget : findChildren<QDoubleSpinBox*>())
7210 settings.insert(oneWidget->objectName(), oneWidget->value());
7213 for (
auto &oneWidget : findChildren<QSpinBox*>())
7214 settings.insert(oneWidget->objectName(), oneWidget->value());
7217 for (
auto &oneWidget : findChildren<QCheckBox*>())
7218 settings.insert(oneWidget->objectName(), oneWidget->isChecked());
7221 for (
auto &oneWidget : findChildren<QGroupBox*>())
7222 if (oneWidget->isCheckable())
7223 settings.insert(oneWidget->objectName(), oneWidget->isChecked());
7226 for (
auto &oneWidget : findChildren<QSplitter*>())
7227 settings.insert(oneWidget->objectName(),
QString::fromUtf8(oneWidget->saveState().toBase64()));
7230 for (
auto &oneWidget : findChildren<QRadioButton*>())
7231 settings.insert(oneWidget->objectName(), oneWidget->isChecked());
7236void Focus::setAllSettings(
const QVariantMap &settings)
7240 disconnectSyncSettings();
7242 for (
auto &name : settings.keys())
7245 auto comboBox = findChild<QComboBox*>(name);
7248 syncControl(settings, name, comboBox);
7253 auto doubleSpinBox = findChild<QDoubleSpinBox*>(name);
7256 syncControl(settings, name, doubleSpinBox);
7261 auto spinBox = findChild<QSpinBox*>(name);
7264 syncControl(settings, name, spinBox);
7269 auto checkbox = findChild<QCheckBox*>(name);
7272 syncControl(settings, name, checkbox);
7277 auto groupbox = findChild<QGroupBox*>(name);
7278 if (groupbox && groupbox->isCheckable())
7280 syncControl(settings, name, groupbox);
7285 auto splitter = findChild<QSplitter*>(name);
7288 syncControl(settings, name, splitter);
7293 auto radioButton = findChild<QRadioButton*>(name);
7296 syncControl(settings, name, radioButton);
7302 for (
auto &key : settings.keys())
7304 auto value = settings[key];
7306 Options::self()->setProperty(key.
toLatin1(), value);
7308 m_Settings[key] = value;
7309 m_GlobalSettings[key] = value;
7312 emit settingsUpdated(getAllSettings());
7315 OpticalTrainSettings::Instance()->setOpticalTrainID(OpticalTrainManager::Instance()->
id(opticalTrainCombo->currentText()));
7316 OpticalTrainSettings::Instance()->setOneSetting(OpticalTrainSettings::Focus, m_Settings);
7319 connectSyncSettings();
7322 m_CurveFit =
static_cast<CurveFitting::CurveFit
> (m_OpsFocusProcess->focusCurveFit->currentIndex());
7323 setFocusDetection(
static_cast<StarAlgorithm
> (m_OpsFocusProcess->focusDetection->currentIndex()));
7324 setCurveFit(
static_cast<CurveFitting::CurveFit
>(m_OpsFocusProcess->focusCurveFit->currentIndex()));
7325 setStarMeasure(
static_cast<StarMeasure
>(m_OpsFocusProcess->focusStarMeasure->currentIndex()));
7326 setWalk(
static_cast<FocusWalk
>(m_OpsFocusMechanics->focusWalk->currentIndex()));
7330bool Focus::syncControl(
const QVariantMap &settings,
const QString &key,
QWidget * widget)
7341 if ((pSB = qobject_cast<QSpinBox *>(widget)))
7343 const int value = settings[key].toInt(&ok);
7350 else if ((pDSB = qobject_cast<QDoubleSpinBox *>(widget)))
7352 const double value = settings[key].toDouble(&ok);
7359 else if ((pCB = qobject_cast<QCheckBox *>(widget)))
7361 const bool value = settings[key].toBool();
7366 else if ((pGB = qobject_cast<QGroupBox *>(widget)))
7368 const bool value = settings[key].toBool();
7373 else if ((pRadioButton = qobject_cast<QRadioButton *>(widget)))
7375 const bool value = settings[key].toBool();
7377 pRadioButton->
click();
7381 else if ((pComboBox = qobject_cast<QComboBox *>(widget)))
7383 const QString value = settings[key].toString();
7387 else if ((pSplitter = qobject_cast<QSplitter *>(widget)))
7397void Focus::setupOpticalTrainManager()
7399 connect(OpticalTrainManager::Instance(), &OpticalTrainManager::updated,
this, &Focus::refreshOpticalTrain);
7402 OpticalTrainManager::Instance()->openEditor(opticalTrainCombo->currentText());
7406 ProfileSettings::Instance()->setOneSetting(ProfileSettings::FocusOpticalTrain,
7407 OpticalTrainManager::Instance()->
id(opticalTrainCombo->itemText(index)));
7408 refreshOpticalTrain();
7409 emit trainChanged();
7413void Focus::refreshOpticalTrain()
7415 bool validSettings =
false;
7416 opticalTrainCombo->blockSignals(
true);
7417 opticalTrainCombo->clear();
7418 opticalTrainCombo->addItems(OpticalTrainManager::Instance()->getTrainNames());
7419 trainB->setEnabled(
true);
7421 QVariant trainID = ProfileSettings::Instance()->getOneSetting(ProfileSettings::FocusOpticalTrain);
7425 auto id = trainID.
toUInt();
7428 if (OpticalTrainManager::Instance()->exists(
id) ==
false)
7430 qCWarning(KSTARS_EKOS_FOCUS) <<
"Optical train doesn't exist for id" << id;
7431 id = OpticalTrainManager::Instance()->id(opticalTrainCombo->itemText(0));
7434 auto name = OpticalTrainManager::Instance()->name(
id);
7436 opticalTrainCombo->setCurrentText(name);
7442 OpticalTrainSettings::Instance()->setOpticalTrainID(
id);
7444 auto focuser = OpticalTrainManager::Instance()->getFocuser(name);
7445 setFocuser(focuser);
7447 auto scope = OpticalTrainManager::Instance()->getScope(name);
7448 double reducer = OpticalTrainManager::Instance()->getReducer(name);
7449 setScopeDetails(scope, reducer);
7451 auto settings = OpticalTrainSettings::Instance()->getOneSetting(OpticalTrainSettings::Focus);
7452 if (settings.isValid())
7454 validSettings =
true;
7455 auto map = settings.toJsonObject().toVariantMap();
7456 if (map != m_Settings)
7459 setAllSettings(map);
7463 auto camera = OpticalTrainManager::Instance()->getCamera(name);
7466 opticalTrainCombo->setToolTip(
QString(
"%1 @ %2").arg(camera->getDeviceName(), scope[
"name"].toString()));
7469 auto nvp = camera->getNumber(
"CCD_INFO");
7472 m_CcdPixelSizeX = 0.0;
7473 m_CcdWidth = m_CcdHeight = 0;
7477 auto np = nvp->findWidgetByName(
"CCD_PIXEL_SIZE_X");
7479 m_CcdPixelSizeX = np->getValue();
7480 np = nvp->findWidgetByName(
"CCD_MAX_X");
7482 m_CcdWidth = np->getValue();
7483 np = nvp->findWidgetByName(
"CCD_MAX_Y");
7485 m_CcdHeight = np->getValue();
7490 auto filterWheel = OpticalTrainManager::Instance()->getFilterWheel(name);
7491 setFilterWheel(filterWheel);
7499 focusAdvisor->setupParams(name);
7500 focusAdvisor->updateParams();
7504 opticalTrainCombo->blockSignals(
false);
7508void Focus::setScopeDetails(
const QJsonObject &scope,
const double reducer)
7510 m_Aperture = scope[
"aperture"].toDouble(-1);
7511 m_FocalLength = scope[
"focal_length"].toDouble(-1);
7512 m_FocalRatio = scope[
"focal_ratio"].toDouble(-1);
7513 m_ScopeType = scope[
"type"].toString();
7514 m_Reducer = reducer;
7517 if (m_Reducer > 0.0)
7518 m_FocalLength *= m_Reducer;
7521 if (m_FocalRatio <= 0.0)
7523 m_FocalRatio = (m_Aperture > 0.001) ? m_FocalLength / m_Aperture : 0.0f;
7524 else if (m_Aperture < 0.0)
7526 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.
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 clearDataPoints()
clearDataPoints Remove all data points from HFR plots
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 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 appendLogText(const QString &logtext)
setFocusStatus Upon completion of the focusing process, set its status (fail or pass) and reset focus...
Q_SCRIPTABLE Q_NOREPLY void resetFrame()
DBUS interface function.
void processTemperatureSource(INDI::Property prop)
processTemperatureSource Updates focus temperature source.
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 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
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)
const KStarsDateTime & lt() const
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 capture(double settleTime=0.0)
DBUS interface function.
Q_SCRIPTABLE bool focusOut(int ms=-1)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void abort()
DBUS interface function.
Q_SCRIPTABLE bool focusIn(int ms=-1)
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)
QString toString(QStringView format, QCalendar cal) const const
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
QDBusConnection sessionBus()
QString filePath(const QString &fileName) const const
void valueChanged(double d)
bool exists() const const
bool isChecked() const const
QIcon fromTheme(const QString &name)
const_iterator constBegin() const const
const_iterator constEnd() const const
qsizetype count() const const
qsizetype size() const const
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