11#include "config-kstars.h"
13#include "fits_debug.h"
14#include "fitssepdetector.h"
22#include <QtConcurrent>
24#ifdef HAVE_STELLARSOLVER
25#include "ekos/auxiliary/stellarsolverprofileeditor.h"
26#include <stellarsolver.h>
58#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
59 return QtConcurrent::run(&FITSSEPDetector::findSourcesAndBackground,
this, boundary);
61 return QtConcurrent::run(
this, &FITSSEPDetector::findSourcesAndBackground, boundary);
65bool FITSSEPDetector::findSourcesAndBackground(
QRect const &boundary)
67#ifndef HAVE_STELLARSOLVER
73 int maxStarsCount = getValue(
"maxStarsCount", 100000).
toInt();
75 int optionsProfileIndex = getValue(
"optionsProfileIndex", -1).
toInt();
76 Ekos::ProfileGroup group =
static_cast<Ekos::ProfileGroup
>(getValue(
"optionsProfileGroup", 1).
toInt());
78 m_ImageData->getImageBuffer()));
83 case Ekos::AlignProfiles:
86 case Ekos::GuideProfiles:
87 filename =
"SavedGuideProfiles.ini";
89 case Ekos::FocusProfiles:
90 filename =
"SavedFocusProfiles.ini";
92 case Ekos::HFRProfiles:
93 filename =
"SavedHFRProfiles.ini";
99 if(
QFile(savedOptionsProfiles).exists())
100 optionsList = StellarSolver::loadSavedOptionsProfiles(savedOptionsProfiles);
105 case Ekos::AlignProfiles:
106 optionsList = Ekos::getDefaultAlignOptionsProfiles();
108 case Ekos::GuideProfiles:
109 optionsList = Ekos::getDefaultGuideOptionsProfiles();
111 case Ekos::FocusProfiles:
112 optionsList = Ekos::getDefaultFocusOptionsProfiles();
114 case Ekos::HFRProfiles:
115 optionsList = Ekos::getDefaultHFROptionsProfiles();
119 if (optionsProfileIndex >= 0 && optionsList.
count() > optionsProfileIndex)
121 auto params = optionsList[optionsProfileIndex];
122 params.partition = Options::stellarSolverPartition();
123 solver->setParameters(params);
124 qCDebug(KSTARS_FITS) <<
"Sextract with: " << optionsList[optionsProfileIndex].listName;
128 auto params = SSolver::Parameters();
129 params.partition = Options::stellarSolverPartition();
130 solver->setParameters(params);
134 const bool runHFR = group != Ekos::AlignProfiles;
136 solver->setLogLevel(SSolver::LOG_NONE);
137 solver->setSSLogLevel(SSolver::LOG_OFF);
140 solver->extract(runHFR, boundary);
142 solver->extract(runHFR);
144 stars = solver->getStarList();
147 if (stars.
empty() || image.isNull())
150 auto bg = solver->getBackground();
152 skyBG.mean = bg.global;
153 skyBG.sigma = bg.globalrms;
154 skyBG.numPixelsInSkyEstimate = bg.bw * bg.bh;
155 skyBG.setStarsDetected(bg.num_stars_detected);
156 m_ImageData->setSkyBackground(skyBG);
164 std::sort(stars.
begin(), stars.
end(), [](
const FITSImage::Star & star1,
const FITSImage::Star & star2) ->
bool { return star1.HFR > star2.HFR;});
166 std::sort(stars.
begin(), stars.
end(), [](
const FITSImage::Star & star1,
const FITSImage::Star & star2) ->
bool { return star1.flux > star2.flux;});
170 int starCount = qMin(maxStarsCount, stars.
count());
171 starCenters.
reserve(starCount);
172 for (
int i = 0; i < starCount; i++)
174 Edge *oneEdge =
new Edge();
175 oneEdge->x = stars[i].x;
176 oneEdge->y = stars[i].y;
177 oneEdge->val = stars[i].peak;
178 oneEdge->sum = stars[i].flux;
179 oneEdge->HFR = stars[i].HFR;
180 oneEdge->width = stars[i].a;
181 oneEdge->numPixels = stars[i].numPixels;
185 oneEdge->ellipticity = 1 - stars[i].b / stars[i].a;
187 oneEdge->ellipticity = 0;
189 starCenters.
append(oneEdge);
191 m_ImageData->setStarCenters(starCenters);
197void FITSSEPDetector::getFloatBuffer(
float * buffer,
int x,
int y,
int w,
int h, FITSData
const *data)
const
199 auto * rawBuffer =
reinterpret_cast<T
const *
>(data->getImageBuffer());
201 if (buffer ==
nullptr)
204 float * floatPtr = buffer;
209 FITSImage::Statistic
const &stats = data->getStatistics();
211 for (
int y1 = y; y1 < y2; y1++)
213 int offset = y1 * stats.width;
214 for (
int x1 = x; x1 < x2; x1++)
216 *floatPtr++ = rawBuffer[offset + x1];
221SkyBackground::SkyBackground(
double mean_,
double sigma_,
double numPixels_)
223 initialize(mean_, sigma_, numPixels_);
226void SkyBackground::initialize(
double mean_,
double sigma_,
227 double numPixelsInSkyEstimate_,
int numStars_)
231 numPixelsInSkyEstimate = numPixelsInSkyEstimate_;
232 varSky = sigma_ * sigma_;
233 starsDetected = numStars_;
237double SkyBackground::SNR(
double flux,
double numPixels,
double gain)
const
239 if (numPixelsInSkyEstimate <= 0 || gain <= 0)
242 const double numer = flux;
243 const double denom = sqrt( numer / gain + numPixels * varSky * (1 + 1 / numPixelsInSkyEstimate));
246 return numer / denom;
QString filePath(const QString &fileName) const const
void append(QList< T > &&value)
qsizetype count() const const
void reserve(qsizetype size)
bool isValid() const const
QFuture< T > run(Function function,...)
int toInt(bool *ok) const const