diff --git a/mainwindow.cpp b/mainwindow.cpp index 08de390..328dbd5 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -72,7 +72,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) infoDock->setWidget(m_info); infoDock->setObjectName("infoDock"); addDockWidget(Qt::LeftDockWidgetArea, infoDock); - resize(800, 600); + resize(1024, 600); setStatusBar(new QStatusBar(this)); m_database = new Database(this); @@ -111,6 +111,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) #ifdef PLATESOLVER _plateSolving = new PlateSolving(this); addDockWidget(Qt::RightDockWidgetArea, _plateSolving); + _plateSolving->hide(); #endif addToolBar(Qt::TopToolBarArea, m_stretchPanel); @@ -268,7 +269,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) helpMenu->addAction(tr("Help"), QKeySequence::HelpContents, [this]{ HelpDialog help(this); help.exec(); }); helpMenu->addAction(tr("About Tenmon"), [this]{ About about(this); about.exec(); }); helpMenu->addAction(tr("About Qt"), [this](){ QMessageBox::aboutQt(this); }); - helpMenu->addAction(tr("Check update"), this, &MainWindow::checkNewVersion); + helpMenu->addAction(tr("Check for update"), this, &MainWindow::checkNewVersion); setupSigterm(); QSettings settings; diff --git a/platesolving.cpp b/platesolving.cpp index 107a785..386ec56 100644 --- a/platesolving.cpp +++ b/platesolving.cpp @@ -81,7 +81,7 @@ void PlateSolving::extractionDone() } _ui->stars->setText(QString::number(stars.size())); - _ui->hfr->setText(QString("%1 %2x%3").arg(hfr).arg(a).arg(b)); + _ui->hfr->setText(QString("%1 Ecc:%2").arg(hfr).arg(std::sqrt(1 - (b*b)/(a*a)))); _ui->log->appendPlainText(QString("Extraction finished in %1 ms").arg(_solvingTime.elapsed())); _ui->solveButton->setDisabled(false); @@ -180,7 +180,7 @@ void PlateSolving::imageLoaded(Image *image) _ui->scaleUnit->setCurrentIndex(2); _ui->fovLow->setValue(pointScale.scaleLow); _ui->fovHigh->setValue(pointScale.scaleHigh); - _ui->usePosition->setChecked(true); + _ui->useScale->setChecked(true); } else { diff --git a/scriptengine.cpp b/scriptengine.cpp index 5d3f7b5..bc43c9a 100644 --- a/scriptengine.cpp +++ b/scriptengine.cpp @@ -9,6 +9,7 @@ #include "batchprocessing.h" #include #include "libXISF/libxisf.h" +#include "solver.h" namespace Script { @@ -25,6 +26,8 @@ ScriptEngine::ScriptEngine(BatchProcessing *parent) _jsEngine->globalObject().setProperty("FITSRecordModify", fitsRecordObject); _database->init(QLatin1String("scriptengine")); _semaphore.release(_pool->maxThreadCount()); + + _solver = new Solver(this); } void ScriptEngine::setParams(const QString &scriptPath, const QList> &paths, const QString &outputDir) @@ -46,6 +49,7 @@ const QString &ScriptEngine::outputDir() const void ScriptEngine::interrupt() { + _solver->abort(); _jsEngine->setInterrupted(true); } @@ -118,6 +122,25 @@ QJSValue ScriptEngine::getItem(const QStringList &items, const QString &label, i return ret; } +void ScriptEngine::setStartingSolution(const QJSValue &solution) +{ + if(solution.isObject()) + { + if(solution.hasProperty("ra") && solution.hasProperty("dec") && solution.property("ra").isNumber() && solution.property("dec").isNumber()) + _solver->setSearchPosition(solution.property("ra").toNumber(), solution.property("dec").toNumber()); + if(solution.hasProperty("pixscale") && solution.property("pixscale").isNumber()) + { + double scale = solution.property("pixscale").toNumber(); + _solver->setSearchScale(scale * 0.8, scale * 1.2, SSolver::ScaleUnits::ARCSEC_PER_PIX); + } + } + else + { + _solver->clearStartingPositionAndScale(); + } + +} + bool ScriptEngine::convert(File *file, QString &outpath, const QString &format, const QVariantMap ¶ms, bool async) { QString path; @@ -151,6 +174,86 @@ bool ScriptEngine::convert(File *file, QString &outpath, const QString &format, return true; } +QJSValue ScriptEngine::solveImage(File *file, bool updateHeader) +{ + QString path = file->absoluteFilePath(); + QJSValue ret = newObject(); + + if(_solver->loadImage(path)) + { + if(_solver->solveImage(true)) + { + auto solution = _solver->getSolution(); + ret.setProperty("fieldWidth", solution.fieldWidth); + ret.setProperty("fieldHeight", solution.fieldHeight); + ret.setProperty("ra", solution.ra); + ret.setProperty("dec", solution.dec); + ret.setProperty("orientation", solution.orientation); + ret.setProperty("pixscale", solution.pixscale); + ret.setProperty("parity", solution.parity == FITSImage::Parity::POSITIVE); + ret.setProperty("raError", solution.raError); + ret.setProperty("decError", solution.decError); + if(updateHeader) + { + QString error; + if(!_solver->updateHeader(error)) + logError(error); + } + } + else + { + logError("Failed to plate solve image " + path); + } + } + else + { + logError("Failed to load image " + path); + } + return ret; +} + +QJSValue ScriptEngine::extractStars(File *file, bool hfr) +{ + QJSValue ret; + QString path = file->absoluteFilePath(); + if(_solver->loadImage(path)) + { + if(_solver->extractSources(hfr, true)) + { + auto stars = _solver->getStars(); + ret = newArray(stars.size()); + int i = 0; + for(auto &star : stars) + { + QJSValue starj = newObject(); + starj.setProperty("x", star.x); + starj.setProperty("y", star.y); + starj.setProperty("mag", star.mag); + starj.setProperty("flux", star.flux); + starj.setProperty("peak", star.peak); + starj.setProperty("HFR", star.HFR); + starj.setProperty("a", star.a); + starj.setProperty("b", star.b); + starj.setProperty("theta", star.theta); + starj.setProperty("ra", star.ra); + starj.setProperty("dec", star.dec); + starj.setProperty("numPixels", star.numPixels); + ret.setProperty(i++, starj); + } + } + else + { + logError("Failed to extract sources from " + path); + } + } + else + { + logError("Failed to load image " + path); + } + + return ret; +} + QJSValue ScriptEngine::newObject() { return _jsEngine->newObject(); @@ -579,6 +682,22 @@ QJSValue File::stats() return _stats; } +QJSValue File::solve(bool updateHeader) +{ + if(_solution.isUndefined() || updateHeader) + _solution = _engine->solveImage(this, updateHeader); + + return _solution; +} + +QJSValue File::extractStars(bool hfr) +{ + if(_stars.isUndefined()) + _stars = _engine->extractStars(this, hfr); + + return _stars; +} + ScriptEngineThread::ScriptEngineThread(BatchProcessing *parent) : QObject(parent) { _thread = new QThread(); diff --git a/scriptengine.h b/scriptengine.h index 36f4f9d..f06de48 100644 --- a/scriptengine.h +++ b/scriptengine.h @@ -11,6 +11,7 @@ #include "imageinfo.h" class BatchProcessing; +class Solver; namespace Script { @@ -28,6 +29,7 @@ class ScriptEngine : public QObject QString _scriptPath; QString _outputDir; QList> _paths; + Solver *_solver; public: explicit ScriptEngine(BatchProcessing *parent = nullptr); void setParams(const QString &scriptPath, const QList> &paths, const QString &outputDir); @@ -45,7 +47,10 @@ public: Q_INVOKABLE QJSValue getInt(const QString &label = QString(), int value = 0); Q_INVOKABLE QJSValue getFloat(const QString &label = QString(), double value = 0, int decimals = 3) const; Q_INVOKABLE QJSValue getItem(const QStringList &items, const QString &label = "", int current = 0) const; + Q_INVOKABLE void setStartingSolution(const QJSValue &solution = QJSValue()); bool convert(File *file, QString &outpath, const QString &format, const QVariantMap ¶ms, bool async); + QJSValue solveImage(File *file, bool updateHeader); + QJSValue extractStars(File *file, bool hfr); QJSValue newObject(); QJSValue newArray(uint size); public slots: @@ -86,6 +91,8 @@ class File : public QObject void loadFitsKeywords(); bool mkpath(const QString &path) const; QJSValue _stats; + QJSValue _solution; + QJSValue _stars; public: explicit File(const QString &path, ScriptEngine *engine); explicit File(const QString &path, const QString &root, ScriptEngine *engine); @@ -109,6 +116,8 @@ public: Q_INVOKABLE File* convert(const QString &outpath, const QString &format, const QVariantMap ¶ms = QVariantMap()); Q_INVOKABLE File* convertAsync(const QString &outpath, const QString &format, const QVariantMap ¶ms = QVariantMap()); Q_INVOKABLE QJSValue stats(); + Q_INVOKABLE QJSValue solve(bool updateHeader = false); + Q_INVOKABLE QJSValue extractStars(bool hfr); }; class FITSRecordModify : public QObject diff --git a/solver.cpp b/solver.cpp index 7933c65..0809383 100644 --- a/solver.cpp +++ b/solver.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include "rawimage.h" @@ -15,8 +16,11 @@ Solver::Solver(QObject *parent) : QObject(parent) connect(_solver, &StellarSolver::logOutput, this, &Solver::logOutput); _solver->setProperty("ProcessType", SSolver::SOLVE); - _solver->setIndexFolderPaths(QStringList(getTenmonIndexPath())); - _solver->setParameterProfile(SSolver::Parameters::ALL_STARS); + QSettings settings; + setIndexFolder(settings.value("platesolving/indexPath", Solver::getTenmonIndexPath()).toString()); + int profileIdx = settings.value("platesolving/profile", 0).toInt(); + auto profiles = _solver->getBuiltInProfiles(); + _solver->setParameters(profiles[profileIdx]); connect(_solver, &StellarSolver::finished, this, &Solver::finished); } @@ -32,12 +36,14 @@ void Solver::setIndexFolder(const QString &indexPath) bool Solver::loadImage(const QString &path) { + if(path == _path)return true; + _loaded = false; std::shared_ptr image; ImageInfoData info; if(::loadImage(path, info, image, true)) { - loadImage(image, path); + return loadImage(image, path); } return false; } @@ -85,25 +91,27 @@ bool Solver::loadImage(std::shared_ptr &image, const QString &path) return _loaded; } -bool Solver::solveImage() +bool Solver::solveImage(bool sync) { if(_loaded && !_solver->isRunning()) { _process = SSolver::ProcessType::SOLVE; _solver->setProperty("ProcessType", _process); - _solver->start(); + if(sync)return _solver->solve(); + else _solver->start(); return true; } return false; } -bool Solver::extractSources(bool hfr) +bool Solver::extractSources(bool hfr, bool sync) { if(_loaded && !_solver->isRunning()) { _process = hfr ? SSolver::ProcessType::EXTRACT_WITH_HFR : SSolver::ProcessType::EXTRACT; _solver->setProperty("ProcessType", _process); - _solver->start(); + if(sync)return _solver->extract(hfr); + else _solver->start(); return true; } return false; @@ -161,6 +169,7 @@ bool Solver::updateHeader(QString &error) Script::File file(_path, nullptr); Script::FITSRecordModify modify; + modify.removeKeyword("RADECSYS"); modify.updateKeyword("CRPIX1", _stats.width / 2.0, QByteArray("x pixel coordinate of the reference point")); modify.updateKeyword("CRPIX2", _stats.height / 2.0, QByteArray("y pixel coordinate of the reference point")); modify.updateKeyword("CDELT1", cdeltx, QByteArray("X pixel size (deg)")); @@ -185,18 +194,14 @@ bool Solver::updateHeader(QString &error) void Solver::setParameters(Parameters::ParametersProfile profile) { auto profileParam = _solver->getBuiltInProfiles().at(profile); - // TODO seems like any paralel is crashing with Qt6 profileParam.partition = false; - //profileParam.inParallel = false; _solver->setParameters(profileParam); } void Solver::setParameters(const Parameters ¶meters) { auto profile = parameters; - // TODO seems like any paralel is crashing with Qt6 profile.partition = false; - //profile.inParallel = false; _solver->setParameters(profile); } @@ -210,6 +215,12 @@ void Solver::setSearchPosition(double ra, double dec) _solver->setSearchPositionRaDec(ra, dec); } +void Solver::clearStartingPositionAndScale() +{ + _solver->clearSearchPosition(); + _solver->clearSearchScale(); +} + QStringList Solver::getIndexPaths() { QStringList paths = StellarSolver::getDefaultIndexFolderPaths(); diff --git a/solver.h b/solver.h index 8ff5859..51fcc6d 100644 --- a/solver.h +++ b/solver.h @@ -23,8 +23,8 @@ public: bool loadImage(const QString &path); bool loadImage(std::shared_ptr &image, const QString &path); - bool solveImage(); - bool extractSources(bool hfr); + bool solveImage(bool sync = false); + bool extractSources(bool hfr, bool sync = false); void abort(); const FITSImage::Solution& getSolution() const; const QList& getStars() const; @@ -36,6 +36,7 @@ public: void setParameters(const SSolver::Parameters ¶meters); void setSearchScale(double fovLow, double fowHigh, ScaleUnits units); void setSearchPosition(double ra, double dec); + void clearStartingPositionAndScale(); static QStringList getIndexPaths(); static QString getTenmonIndexPath();