1 /* StellarSolver, StellarSolver Intenal Library developed by Robert Lancaster, 2020 2 3 This application is free software; you can redistribute it and/or 4 modify it under the terms of the GNU General Public 5 License as published by the Free Software Foundation; either 6 version 2 of the License, or (at your option) any later version. 7 */ 8 #pragma once 9 10 //Includes for this project 11 #include "structuredefinitions.h" 12 #include "sextractorsolver.h" 13 #include "parameters.h" 14 #include "version.h" 15 16 //QT Includes 17 #include <QDir> 18 #include <QThread> 19 #include <QMap> 20 #include <QVariant> 21 #include <QVector> 22 #include <QRect> 23 #include <QPointer> 24 25 using namespace SSolver; 26 27 class StellarSolver : public QObject 28 { 29 Q_OBJECT 30 Q_PROPERTY(QString BasePath MEMBER m_BasePath) 31 Q_PROPERTY(QString FileToProcess MEMBER m_FileToProcess) 32 Q_PROPERTY(QString ASTAPBinaryPath MEMBER m_ASTAPBinaryPath) 33 Q_PROPERTY(QString SextractorBinaryPath MEMBER m_SextractorBinaryPath) 34 Q_PROPERTY(QString ConfPath MEMBER m_ConfPath) 35 Q_PROPERTY(QString SolverPath MEMBER m_SolverPath) 36 Q_PROPERTY(QString WCSPath MEMBER m_WCSPath) 37 Q_PROPERTY(QString AstrometryAPIKey MEMBER m_AstrometryAPIKey) 38 Q_PROPERTY(QString AstrometryAPIURL MEMBER m_AstrometryAPIURL) 39 Q_PROPERTY(QString LogFileName MEMBER m_LogFileName) 40 Q_PROPERTY(bool UsePosition MEMBER m_UsePosition) 41 Q_PROPERTY(bool UseScale MEMBER m_UseScale) 42 Q_PROPERTY(bool AutoGenerateAstroConfig MEMBER m_AutoGenerateAstroConfig) 43 Q_PROPERTY(bool CleanupTemporaryFiles MEMBER m_CleanupTemporaryFiles) 44 Q_PROPERTY(bool OnlySendFITSFiles MEMBER m_OnlySendFITSFiles) 45 Q_PROPERTY(bool LogToFile MEMBER m_LogToFile) 46 Q_PROPERTY(SolverType SolverType MEMBER m_SolverType) 47 Q_PROPERTY(ProcessType ProcessType MEMBER m_ProcessType) 48 Q_PROPERTY(ExtractorType ExtractorType MEMBER m_SextractorType) 49 50 public: 51 //The constructor and destructor foe the StellarSolver Object 52 explicit StellarSolver(ProcessType type, const FITSImage::Statistic &imagestats, uint8_t const *imageBuffer, 53 QObject *parent = nullptr); 54 explicit StellarSolver(const FITSImage::Statistic &imagestats, uint8_t const *imageBuffer, QObject *parent = nullptr); 55 ~StellarSolver(); 56 57 //Methods to get default file paths 58 static ExternalProgramPaths getLinuxDefaultPaths(); 59 static ExternalProgramPaths getLinuxInternalPaths(); 60 static ExternalProgramPaths getMacHomebrewPaths(); 61 static ExternalProgramPaths getMacInternalPaths(); 62 static ExternalProgramPaths getWinANSVRPaths(); 63 static ExternalProgramPaths getWinCygwinPaths(); 64 65 //This gets the processType as a string explaining the command StellarSolver is Running getCommandString()66 QString getCommandString() 67 { 68 return SSolver::getCommandString(m_ProcessType, m_SextractorType, m_SolverType); 69 } 70 71 //This gets the scale unit string for astrometry.net input 72 //This should NOT be translated getScaleUnitString()73 QString getScaleUnitString() 74 { 75 return SSolver::getScaleUnitString(m_ScaleUnit); 76 } 77 78 //This gets a string for the Sextractor setting for calculating Flux using ellipses or circles getShapeString()79 QString getShapeString() 80 { 81 return SSolver::getShapeString(params.apertureShape); 82 } 83 84 //This gets a string for which Parallel Solving Algorithm we are using getMultiAlgoString()85 QString getMultiAlgoString() 86 { 87 return SSolver::getMultiAlgoString(params.multiAlgorithm); 88 } 89 getLogLevelString()90 QString getLogLevelString() 91 { 92 return SSolver::getLogLevelString(m_AstrometryLogLevel); 93 } 94 getVersion()95 static QString getVersion() 96 { 97 return QString("StellarSolver Library Version: %1, build: %2").arg(StellarSolver_VERSION).arg(StellarSolver_BUILD_TS); 98 } 99 getVersionNumber()100 static QString getVersionNumber() 101 { 102 return StellarSolver_VERSION; 103 } 104 105 //Logging Settings for Astrometry 106 bool m_LogToFile {false}; //This determines whether or not to save the output from Astrometry.net to a file 107 QString m_LogFileName; //This is the path to the log file that it will save. 108 logging_level m_AstrometryLogLevel {LOG_NONE}; //This is the level of astrometry logging. Beware, setting this too high can severely affect performance 109 SSolverLogLevel m_SSLogLevel {LOG_NORMAL}; //This is the level for the StellarSolver Logging 110 111 //These are for creating temporary files 112 //This is the base name used for all temporary files. It uses a random name based on the type of solver/sextractor. 113 QString m_BaseName; 114 //This is the path used for saving any temporary files. They are by default saved to the default temp directory, you can change it if you want to. 115 QString m_BasePath {QDir::tempPath()}; 116 117 //STELLARSOLVER METHODS 118 //The public methods here are for you to start, stop, setup, and get results from the StellarSolver 119 120 //These are the most important methods that you can use for the StellarSolver 121 122 /** 123 * @brief sextract Extracts stars from the image. 124 * @param calculateHFR If true, it will also calculated Half-Flux Radius for each detected star. HFR calculations can be very CPU-intensive. 125 * @param frame If set, it will only extract stars within this rectangular region of the image. 126 */ 127 void extract(bool calculateHFR = false, QRect frame = QRect()); 128 129 void solve(); 130 void start(); 131 void releaseSextractorSolver(SextractorSolver *solver); 132 void abort(); 133 134 //These set the settings for the StellarSolver setParameters(Parameters parameters)135 void setParameters(Parameters parameters) 136 { 137 params = parameters; 138 }; 139 void setParameterProfile(SSolver::Parameters::ParametersProfile profile); setIndexFolderPaths(QStringList indexPaths)140 void setIndexFolderPaths(QStringList indexPaths) 141 { 142 indexFolderPaths = indexPaths; 143 }; 144 void setSearchScale(double fov_low, double fov_high, const QString &scaleUnits); 145 //This sets the scale range for the image to speed up the solver 146 void setSearchScale(double fov_low, double fov_high, ScaleUnits units); 147 void setSearchPositionRaDec(double ra, 148 double dec); //This sets the search RA/DEC/Radius to speed up the solver 149 void setSearchPositionInDegrees(double ra, double dec); setLogLevel(logging_level level)150 void setLogLevel(logging_level level) 151 { 152 m_AstrometryLogLevel = level; 153 }; setSSLogLevel(SSolverLogLevel level)154 void setSSLogLevel(SSolverLogLevel level) 155 { 156 m_SSLogLevel = level; 157 }; 158 159 //These static methods can be used by classes to configure parameters or paths 160 //This creates the conv filter from a fwhm 161 static void createConvFilterFromFWHM(Parameters *params, double fwhm); 162 static QList<Parameters> getBuiltInProfiles(); 163 static QList<SSolver::Parameters> loadSavedOptionsProfiles(QString savedOptionsProfiles); 164 static QStringList getDefaultIndexFolderPaths(); 165 166 167 //Accessor Method for external classes getNumStarsFound()168 int getNumStarsFound() const 169 { 170 return numStars; 171 } getStarList()172 const QList<FITSImage::Star> &getStarList() const 173 { 174 return m_ExtractorStars; 175 } getBackground()176 const FITSImage::Background &getBackground() const 177 { 178 return background; 179 } getStarListFromSolve()180 const QList<FITSImage::Star> &getStarListFromSolve() const 181 { 182 return m_SolverStars; 183 } getSolution()184 const FITSImage::Solution &getSolution() const 185 { 186 return solution; 187 } 188 sextractionDone()189 bool sextractionDone() const 190 { 191 return m_HasExtracted; 192 } solvingDone()193 bool solvingDone() const 194 { 195 return m_HasSolved; 196 } 197 failed()198 bool failed() const 199 { 200 return m_HasFailed; 201 } setLoadWCS(bool set)202 void setLoadWCS(bool set) 203 { 204 loadWCS = set; 205 } hasWCSData()206 bool hasWCSData() const 207 { 208 return hasWCS; 209 }; getNumThreads()210 int getNumThreads() const 211 { 212 if(parallelSolvers.size() == 0) return 1; 213 else return parallelSolvers.size(); 214 } 215 getCurrentParameters()216 const Parameters &getCurrentParameters() 217 { 218 return params; 219 } isCalculatingHFR()220 bool isCalculatingHFR() 221 { 222 return m_CalculateHFR; 223 } 224 225 void setUseSubframe(QRect frame); clearSubFrame()226 void clearSubFrame() 227 { 228 useSubframe = false; 229 m_Subframe = QRect(0, 0, m_Statistics.width, m_Statistics.height); 230 }; 231 232 bool isRunning() const; 233 raString(double ra)234 inline static QString raString(double ra) 235 { 236 char rastr[32]; 237 ra2hmsstring(ra, rastr); 238 return rastr; 239 } 240 decString(double dec)241 inline static QString decString(double dec) 242 { 243 char decstr[32]; 244 dec2dmsstring(dec, decstr); 245 return decstr; 246 } 247 248 virtual FITSImage::wcs_point *getWCSCoord(); 249 250 bool pixelToWCS(const QPointF &pixelPoint, FITSImage::wcs_point &skyPoint); 251 bool wcsToPixel(const FITSImage::wcs_point &skyPoint, QPointF &pixelPoint); 252 253 254 public slots: 255 void processFinished(int code); 256 void parallelSolve(); 257 void finishParallelSolve(int success); 258 void finishWCS(); 259 260 private: 261 int whichSolver(SextractorSolver *solver); 262 //Static Utility 263 static double snr(const FITSImage::Background &background, 264 const FITSImage::Star &star, double gain = 0.5); 265 266 267 bool appendStarsRAandDEC(QList<FITSImage::Star> &stars); 268 269 bool checkParameters(); 270 SextractorSolver* createSextractorSolver(); 271 272 //This finds out the amount of available RAM on the system 273 bool getAvailableRAM(double &availableRAM, double &totalRAM); 274 //This determines if there is enough RAM for the selected index files so that we don't try to load indexes inParallel unless it can handle it. 275 bool enoughRAMisAvailableFor(QStringList indexFolders); 276 277 //This defines the type of process to perform. 278 ProcessType m_ProcessType { EXTRACT }; 279 ExtractorType m_SextractorType { EXTRACTOR_INTERNAL }; 280 SolverType m_SolverType {SOLVER_STELLARSOLVER}; 281 282 //External Options 283 QString m_FileToProcess; 284 bool m_CleanupTemporaryFiles {true}; 285 bool m_AutoGenerateAstroConfig {true}; 286 bool m_OnlySendFITSFiles {true}; 287 288 //System File Paths 289 QStringList m_IndexFilePaths; 290 QString m_ASTAPBinaryPath; 291 QString m_SextractorBinaryPath; 292 QString m_ConfPath; 293 QString m_SolverPath; 294 QString m_WCSPath; 295 296 //Online Options 297 QString m_AstrometryAPIKey; 298 QString m_AstrometryAPIURL; 299 300 bool useSubframe {false}; 301 QRect m_Subframe; 302 bool m_isRunning {false}; 303 QList<SextractorSolver*> parallelSolvers; 304 QPointer<SextractorSolver> m_SextractorSolver; 305 QPointer<SextractorSolver> solverWithWCS; 306 int m_ParallelSolversFinishedCount {0}; 307 bool parallelSolversAreRunning() const; 308 309 //The currently set parameters for StellarSolver 310 Parameters params; 311 //This is the list of folder paths that the solver will use to search for index files 312 QStringList indexFolderPaths {getDefaultIndexFolderPaths()}; 313 314 //Astrometry Scale Parameters, These are not saved parameters and change for each image, use the methods to set them 315 bool m_UseScale {false}; //Whether or not to use the image scale parameters 316 double m_ScaleLow {0}; //Lower bound of image scale estimate 317 double m_ScaleHigh {0}; //Upper bound of image scale estimate 318 ScaleUnits m_ScaleUnit {ARCMIN_WIDTH}; //In what units are the lower and upper bounds? 319 320 //Astrometry Position Parameters, These are not saved parameters and change for each image, use the methods to set them 321 bool m_UsePosition = false; //Whether or not to use initial information about the position 322 double m_SearchRA = HUGE_VAL; //RA of field center for search, format: decimal degrees 323 double m_SearchDE = HUGE_VAL; //DEC of field center for search, format: decimal degrees 324 325 //StellarSolver Internal settings that are needed by ExternalSextractorSolver as well 326 bool m_CalculateHFR {false}; //Whether or not the HFR of the image should be calculated using sep_flux_radius. Don't do it unless you need HFR 327 bool m_HasExtracted {false}; //This boolean is set when the sextraction is done 328 bool m_HasSolved {false}; //This boolean is set when the solving is done 329 bool m_HasFailed {false}; 330 FITSImage::Statistic m_Statistics; //This is information about the image 331 332 const uint8_t *m_ImageBuffer { nullptr }; //The generic data buffer containing the image data 333 334 //The Results 335 FITSImage::Background background; //This is a report on the background levels found during sextraction 336 //This is the list of stars that get extracted from the image, saved to the file, and then solved by astrometry.net 337 QList<FITSImage::Star> m_ExtractorStars; 338 //This is the list of stars that were extracted for the last successful solve 339 QList<FITSImage::Star> m_SolverStars; 340 //The number of stars found in the last operation 341 int numStars; 342 FITSImage::Solution solution; //This is the solution that comes back from the Solver 343 bool loadWCS {true}; 344 bool hasWCS {false}; //This boolean gets set if the StellarSolver has WCS data to retrieve 345 bool hasWCSCoord{false}; //This boolean gets set if the Stellrsolver has already computed WCS Coordinates 346 FITSImage::wcs_point * wcs_coord {nullptr}; 347 348 bool wasAborted {false}; 349 // This is the cancel file path that astrometry.net monitors. If it detects this file, it aborts the solve 350 QString cancelfn; //Filename whose creation signals the process to stop 351 QString solvedfn; //Filename whose creation tells astrometry.net it already solved the field. 352 353 bool m_isBlocking = false; //This boolean determines whether to run in a blocking way. 354 355 signals: 356 //This signals that there is infomation that should be printed to a log file or log window 357 void logOutput(QString logText); 358 359 // Extraction and/or solving complete. 360 // If can be completed successfully or in failure, but it's done. 361 void ready(); 362 363 void wcsReady(); 364 365 void finished(); 366 367 }; 368 369