File indexing completed on 2024-05-12 15:23:43

0001 /*
0002     SPDX-FileCopyrightText: 2020 Hy Murveit <hy@murveit.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <QObject>
0010 #include <QList>
0011 #include <QVector3D>
0012 
0013 #include "starcorrespondence.h"
0014 #include "vect.h"
0015 #include "calibration.h"
0016 
0017 class GuideView;
0018 
0019 namespace SSolver
0020 {
0021 class Parameters;
0022 }
0023 
0024 /*
0025  * This class manages selecting a guide star, finding that star in a new image
0026  * and calculating the drift of the new star image.
0027  * The major methods are:
0028  *
0029  * GuideStars guideStars();
0030  * guideStars.selectGuideStar(QSharedPointer<FITSdata>);
0031  * Selects a guide star, given the input image. This can be done at the start of
0032  * calibration, when guiding starts, or when the guide star is lost.
0033  *
0034  * Vector xy = guideStars.findGuideStar(QSharedPointer<FITSdata>, QRect trackingBox)
0035  * Finds the guide star that was previously selected. xy will contain the pixel coordinates
0036  * {x,y,0}. The tracking box is not enforced if the multi-star star-finding algorithm
0037  * is used, however, if that fails, it backs off to the star with the best score
0038  * (basically the brightest star) in the tracking box.
0039  *
0040  * bool success = guideStars.getDrift(guideStarDrift,  reticle_x, reticle_y, RADrift, DECDrift)
0041  * Returns the star movement in RA and DEC. The reticle can be input indicating
0042  * that the desired position for the original guide star and reference stars has
0043  * shifted (e.g. dithering).
0044  */
0045 
0046 class GuideStars
0047 {
0048     public:
0049         GuideStars();
0050         ~GuideStars() {}
0051 
0052         // Select a guide star, given the image.
0053         // Performs a SEP processing to detect stars, then finds the
0054         // most desirable guide star.
0055         QVector3D selectGuideStar(const QSharedPointer<FITSData> &imageData);
0056 
0057         // Finds the guide star previously selected with selectGuideStar()
0058         // in a new image. This sets up internal structures for getDrift().
0059         GuiderUtils::Vector findGuideStar(const QSharedPointer<FITSData> &imageData, const QRect &trackingBox,
0060                                           QSharedPointer<GuideView> &guideView, bool firstFrame);
0061 
0062         // Finds the drift of the star positions in arc-seconds for RA and DEC.
0063         // Must be called after findGuideStar().
0064         // Returns false if this can't be calculated.
0065         // setCalibration must have been called once before this (so that pixel
0066         // positions can be converted to RA and DEC).
0067         bool getDrift(double oneStarDrift, double reticle_x, double reticle_y,
0068                       double *RADrift, double *DECDrift);
0069 
0070         // Use this calibration object for conversions to arcseconds and RA/DEC.
0071         void setCalibration(const Calibration &calibration);
0072 
0073         // Returns the sky background object that was obtained from SEP analysis.
0074         const SkyBackground &skybackground() const
0075         {
0076             return skyBackground;
0077         }
0078         double getGuideStarMass() const
0079         {
0080             return guideStarMass;
0081         }
0082         double getGuideStarSNR() const
0083         {
0084             return guideStarSNR;
0085         }
0086 
0087         int getNumStarsDetected() const
0088         {
0089             return m_NumStarsDetected;
0090         }
0091 
0092         int getNumReferencesFound() const
0093         {
0094             return starCorrespondence.getNumReferencesFound();
0095         }
0096 
0097         int getNumReferences() const
0098         {
0099             return starCorrespondence.size();
0100         }
0101 
0102         void reset()
0103         {
0104             starCorrespondence.reset();
0105         }
0106 
0107     private:
0108         // Used to initialize the StarCorrespondence object, which ultimately finds
0109         // the guidestar using the geometry between it and the other stars detected.
0110         void setupStarCorrespondence(const QList<Edge> &neighbors, int guideIndex);
0111 
0112         // Evaluates which stars are desirable as guide stars and reference stars.
0113         void evaluateSEPStars(const QList<Edge *> &starCenters, QVector<double> *scores,
0114                               const QRect *roi, const double maxHFR) const;
0115 
0116         // Prepares parameters for evaluateSEPStars().
0117         SSolver::Parameters getStarExtractionParameters(int num);
0118 
0119         // Returns the top num stars according to the evaluateSEPStars criteria.
0120         void findTopStars(const QSharedPointer<FITSData> &imageData, int num, QList<Edge> *stars,
0121                           const double maxHFR,
0122                           const QRect *roi = nullptr,
0123                           QList<double> *outputScores = nullptr,
0124                           QList<double> *minDistances = nullptr);
0125         // The interface to the SEP star detection algoritms.
0126         int findAllSEPStars(const QSharedPointer<FITSData> &imageData, QList<Edge*> *sepStars, int num);
0127 
0128         // Convert from input image coordinates to output RA and DEC coordinates.
0129         GuiderUtils::Vector point2arcsec(const GuiderUtils::Vector &p) const;
0130 
0131         // Returns the RA and DEC distance between the star and the reference star.
0132         void computeStarDrift(const Edge &star, const Edge &reference,
0133                               double *driftRA, double *driftDEC) const;
0134         // Selects the guide star given the star detections and score generated
0135         // by evaluateSEPStars().
0136         QVector3D selectGuideStar(const QList<Edge> &detectedStars,
0137                                   const QList<double> &sepScores,
0138                                   int maxX, int maxY,
0139                                   const QList<double> &minDistances);
0140 
0141         // Computes the distance from stars[i] to its closest neighbor.
0142         double findMinDistance(int index, const QList<Edge*> &stars);
0143 
0144         // Plot the positions of the neighbor stars on the guideView display.
0145         void plotStars(QSharedPointer<GuideView> &guideView, const QRect &trackingBox);
0146 
0147         // These three methods are useful for testing.
0148         void setDetectedStars(const QList<Edge> &stars)
0149         {
0150             detectedStars = stars;
0151         }
0152         void setSkyBackground(const SkyBackground &background)
0153         {
0154             skyBackground = background;
0155         }
0156         void setStarMap(const QVector<int> &map)
0157         {
0158             starMap = map;
0159         }
0160         int getStarMap(int index);
0161 
0162         // Sky background value generated by the SEP processing.
0163         // Used to calculate star SNR values.
0164         SkyBackground skyBackground;
0165 
0166         // Used to find the guide star in a new set of image detections.
0167         StarCorrespondence starCorrespondence;
0168 
0169         // These are set when the guide star is detected, and can be queried, e.g.
0170         // for logging.
0171         double guideStarMass = 0;
0172         double guideStarSNR = 0;
0173 
0174         // The newly detected stars.
0175         QVector<int> starMap;
0176         // This maps between the newly detected stars and the reference stars.
0177         QList<Edge> detectedStars;
0178 
0179         Calibration calibration;
0180         bool calibrationInitialized {false};
0181 
0182         // Find guide star will allow robust star correspondence.
0183         bool allowMissingGuideStar { true };
0184 
0185         int unreliableDectionCounter { 0 };
0186 
0187         int m_NumStarsDetected { 0 };
0188 
0189         friend class TestGuideStars;
0190 };