Adding platesolving
This commit is contained in:
@@ -101,6 +101,7 @@ if(STELLARSOLVER_INCLUDE AND STELLARSOLVER_LIB)
|
|||||||
target_sources(tenmon PRIVATE
|
target_sources(tenmon PRIVATE
|
||||||
solver.cpp solver.h
|
solver.cpp solver.h
|
||||||
platesolving.cpp platesolving.h platesolving.ui
|
platesolving.cpp platesolving.h platesolving.ui
|
||||||
|
platesolvingsettings.cpp platesolvingsettings.h platesolvingsettings.ui
|
||||||
)
|
)
|
||||||
endif(STELLARSOLVER_INCLUDE AND STELLARSOLVER_LIB)
|
endif(STELLARSOLVER_INCLUDE AND STELLARSOLVER_LIB)
|
||||||
|
|
||||||
|
|||||||
+42
-8
@@ -2,7 +2,11 @@
|
|||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
#ifdef PLATESOLVER
|
||||||
#include "solver.h"
|
#include "solver.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// filename arcseconds range
|
// filename arcseconds range
|
||||||
// index-4119.fits 1400–2000
|
// index-4119.fits 1400–2000
|
||||||
@@ -135,7 +139,7 @@ static const QMap<QString, QByteArray> md5 = {
|
|||||||
{"index-5202-45.fits.zst", "83fe2cff3cf65317f5c1bf7b953519e9"},
|
{"index-5202-45.fits.zst", "83fe2cff3cf65317f5c1bf7b953519e9"},
|
||||||
{"index-5202-46.fits.zst", "f12f308a3b53d95ffd7bc420700e4f44"},
|
{"index-5202-46.fits.zst", "f12f308a3b53d95ffd7bc420700e4f44"},
|
||||||
{"index-5202-47.fits.zst", "608a14303810c9762b25fc68896d2a26"},
|
{"index-5202-47.fits.zst", "608a14303810c9762b25fc68896d2a26"},
|
||||||
{"index-5203-00.fits.zst", "155217faa535550c1d7e499145750bb0"},
|
{"index-5203-00.fits.zst", "2862efb33765b7bbefb635dcad970298"},
|
||||||
{"index-5203-01.fits.zst", "2cd34cef4b44ad1e770396baccb2a46c"},
|
{"index-5203-01.fits.zst", "2cd34cef4b44ad1e770396baccb2a46c"},
|
||||||
{"index-5203-02.fits.zst", "40c9f67282210cc374281cde023c4e71"},
|
{"index-5203-02.fits.zst", "40c9f67282210cc374281cde023c4e71"},
|
||||||
{"index-5203-03.fits.zst", "c8f40e164ec3ce1df92e3a121a127716"},
|
{"index-5203-03.fits.zst", "c8f40e164ec3ce1df92e3a121a127716"},
|
||||||
@@ -368,6 +372,8 @@ void Download::readData()
|
|||||||
|
|
||||||
void Download::finished()
|
void Download::finished()
|
||||||
{
|
{
|
||||||
|
if(_reply->error() == QNetworkReply::NoError)
|
||||||
|
{
|
||||||
QByteArray data = _reply->readAll();
|
QByteArray data = _reply->readAll();
|
||||||
qDebug() << "finished" << data.size();
|
qDebug() << "finished" << data.size();
|
||||||
decompress(data);
|
decompress(data);
|
||||||
@@ -377,11 +383,21 @@ void Download::finished()
|
|||||||
if(_hash.result().toHex() == md5[_reply->url().fileName()])
|
if(_hash.result().toHex() == md5[_reply->url().fileName()])
|
||||||
qDebug() << "DOWNLOAD OK";
|
qDebug() << "DOWNLOAD OK";
|
||||||
else
|
else
|
||||||
|
{
|
||||||
qDebug() << "DOWNLOAD BAD";
|
qDebug() << "DOWNLOAD BAD";
|
||||||
|
_fw.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_fw.flush();
|
_fw.flush();
|
||||||
_fw.close();
|
_fw.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "Failed to perform http request" << _reply->url();
|
||||||
|
_fw.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Download::decompress(QByteArray &data)
|
void Download::decompress(QByteArray &data)
|
||||||
@@ -413,7 +429,9 @@ void Download::decompress(QByteArray &data)
|
|||||||
HttpDownloader::HttpDownloader(QObject *parent) : QObject(parent)
|
HttpDownloader::HttpDownloader(QObject *parent) : QObject(parent)
|
||||||
,_manager(new QNetworkAccessManager(this))
|
,_manager(new QNetworkAccessManager(this))
|
||||||
{
|
{
|
||||||
|
_manager->setAutoDeleteReplies(true);
|
||||||
connect(_manager, &QNetworkAccessManager::finished, this, &HttpDownloader::finished);
|
connect(_manager, &QNetworkAccessManager::finished, this, &HttpDownloader::finished);
|
||||||
|
#ifdef PLATESOLVER
|
||||||
QDir dir(Solver::getTenmonIndexPath());
|
QDir dir(Solver::getTenmonIndexPath());
|
||||||
if(!dir.exists())
|
if(!dir.exists())
|
||||||
{
|
{
|
||||||
@@ -422,6 +440,7 @@ HttpDownloader::HttpDownloader(QObject *parent) : QObject(parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_indexPath = dir.absolutePath();
|
_indexPath = dir.absolutePath();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpDownloader::download(const QUrl &url)
|
void HttpDownloader::download(const QUrl &url)
|
||||||
@@ -437,17 +456,17 @@ bool HttpDownloader::downloadIndex(int scale)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
QUrl url("https://nouspiro.space/");
|
QUrl url("https://nouspiro.space/");
|
||||||
|
QStringList files = indexFileNames(scale);
|
||||||
|
|
||||||
if(scale >= 7)
|
for(auto &file : files)
|
||||||
{
|
{
|
||||||
url.setPath(QString("/astrometry/index-%1.fits.zst").arg(4100 + scale));
|
if(QFile::exists(_indexPath + "/" + file))
|
||||||
download(url);
|
{
|
||||||
|
qDebug() << "File already exists, skipping" << file;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(int i=0; i<48; i++)
|
url.setPath("/astrometry/" + file + ".zst");
|
||||||
{
|
|
||||||
url.setPath(QString("/astrometry/index-%1-%2.fits.zst").arg(5200 + scale).arg(i, 2, 10, QChar('0')));
|
|
||||||
download(url);
|
download(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,6 +479,22 @@ void HttpDownloader::abort()
|
|||||||
_download->abort();
|
_download->abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList HttpDownloader::indexFileNames(int scale)
|
||||||
|
{
|
||||||
|
QStringList ret;
|
||||||
|
|
||||||
|
if(scale >= 7)
|
||||||
|
{
|
||||||
|
ret.append(QString("index-%1.fits").arg(4100 + scale));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i=0; i<48; i++)
|
||||||
|
ret.append(QString("index-%1-%2.fits").arg(5200 + scale).arg(i, 2, 10, QChar('0')));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void HttpDownloader::finished()
|
void HttpDownloader::finished()
|
||||||
{
|
{
|
||||||
if(_queue.isEmpty())
|
if(_queue.isEmpty())
|
||||||
@@ -478,7 +513,6 @@ void HttpDownloader::finished()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
_download->deleteLater();
|
|
||||||
_download = new Download(_manager->get(request), _indexPath, this);
|
_download = new Download(_manager->get(request), _indexPath, this);
|
||||||
connect(_download, &Download::progress, this, &HttpDownloader::updateProgress);
|
connect(_download, &Download::progress, this, &HttpDownloader::updateProgress);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public:
|
|||||||
// scale in range 19-1
|
// scale in range 19-1
|
||||||
bool downloadIndex(int scale);
|
bool downloadIndex(int scale);
|
||||||
void abort();
|
void abort();
|
||||||
|
static QStringList indexFileNames(int scale);
|
||||||
signals:
|
signals:
|
||||||
void progress(int percent, int files);
|
void progress(int percent, int files);
|
||||||
protected slots:
|
protected slots:
|
||||||
|
|||||||
+142
@@ -257,6 +257,33 @@ void WCSDataT::calculateBounds(double &minRa, double &maxRa, double &minDec, dou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double hav(double x)
|
||||||
|
{
|
||||||
|
return (1.0 - std::cos(x)) * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
double haverSine(const SkyPoint &a, SkyPoint &b)
|
||||||
|
{
|
||||||
|
const double ToRAD = M_PI / 180.0;
|
||||||
|
double d = hav((a.DEC() - b.DEC()) * ToRAD) + std::cos(a.DEC() * ToRAD) * std::cos(b.DEC() * ToRAD) * hav((a.RA() - b.RA()) * ToRAD);
|
||||||
|
return std::acos(1.0 - 2.0 * d) * (180.0 / M_PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
SkyPointScale WCSDataT::getRaDecScale() const
|
||||||
|
{
|
||||||
|
SkyPointScale ret;
|
||||||
|
pixelToWorld(QPointF(width/2.0, height/2.0), ret.point);
|
||||||
|
SkyPoint pointX;
|
||||||
|
SkyPoint pointY;
|
||||||
|
pixelToWorld(QPointF(width/2.0+1, height/2.0), pointX);
|
||||||
|
pixelToWorld(QPointF(width/2.0, height/2.0+1), pointY);
|
||||||
|
double scaleX = haverSine(ret.point, pointX) * 3600.0;
|
||||||
|
double scaleY = haverSine(ret.point, pointY) * 3600.0;
|
||||||
|
ret.scaleLow = std::min(scaleX, scaleY);
|
||||||
|
ret.scaleHigh = std::max(scaleX, scaleY);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
SkyPoint::SkyPoint() : ra(NAN), dec(NAN)
|
SkyPoint::SkyPoint() : ra(NAN), dec(NAN)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -284,3 +311,118 @@ QString SkyPoint::toString() const
|
|||||||
sec = std::modf(min, &min) * 60;
|
sec = std::modf(min, &min) * 60;
|
||||||
return QString("RA: %1 DEC: %2° %3' %4\"").arg(t.toString("HH'h' mm'm' ss's'")).arg(deg, 2, 'f', 0, '0').arg(min, 2, 'f', 0, '0').arg(sec, 2, 'f', 0, '0');
|
return QString("RA: %1 DEC: %2° %3' %4\"").arg(t.toString("HH'h' mm'm' ss's'")).arg(deg, 2, 'f', 0, '0').arg(min, 2, 'f', 0, '0').arg(sec, 2, 'f', 0, '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double SkyPoint::fromHMS(const QString &hms)
|
||||||
|
{
|
||||||
|
double deg = fromDMS(hms);
|
||||||
|
if(std::isnan(deg))return deg;
|
||||||
|
return deg * 15.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double SkyPoint::fromDMS(const QString &dms)
|
||||||
|
{
|
||||||
|
double deg = 0.0;
|
||||||
|
QString str = dms.trimmed();
|
||||||
|
str.remove(QRegularExpression("[hdms°'\"]"));
|
||||||
|
str.replace(':', ' ');
|
||||||
|
str.replace(QRegularExpression("\\s+"), " ");
|
||||||
|
QStringList fields = str.split(' ');
|
||||||
|
double sign = 1.0;
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
if(fields.size() >= 1)
|
||||||
|
deg = fields.at(0).toDouble(&ok);
|
||||||
|
if(!ok)return NAN;
|
||||||
|
if(deg < 0.0)
|
||||||
|
sign = -1.0;
|
||||||
|
if(fields.size() >= 2)
|
||||||
|
deg += sign * fields.at(1).toDouble() / 60.0;
|
||||||
|
if(fields.size() >= 3)
|
||||||
|
deg += sign * fields.at(2).toDouble() / 3600.0;
|
||||||
|
|
||||||
|
return deg;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkyPointScale ImageInfoData::getCenterRaDec() const
|
||||||
|
{
|
||||||
|
SkyPointScale ret;
|
||||||
|
if(wcs && wcs->valid())
|
||||||
|
{
|
||||||
|
ret = wcs->getRaDecScale();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double ra,dec,focalLen,scale,pixSizeX,pixSizeY;
|
||||||
|
int binX = 1;
|
||||||
|
int binY = 1;
|
||||||
|
ra = dec = focalLen = scale = pixSizeX = pixSizeY = NAN;
|
||||||
|
bool ok;
|
||||||
|
for(const FITSRecord &header : fitsHeader)
|
||||||
|
{
|
||||||
|
if(header.key == "OBJCTRA")
|
||||||
|
{
|
||||||
|
double tmp = SkyPoint::fromHMS(header.value.toString());
|
||||||
|
if(!std::isnan(tmp))ra = tmp;
|
||||||
|
}
|
||||||
|
else if(header.key == "RA" && std::isnan(ra))
|
||||||
|
{
|
||||||
|
double tmp = header.value.toDouble(&ok);
|
||||||
|
if(ok)ra = tmp;
|
||||||
|
}
|
||||||
|
else if(header.key == "OBJCTDEC")
|
||||||
|
{
|
||||||
|
double tmp = SkyPoint::fromDMS(header.value.toString());
|
||||||
|
if(!std::isnan(tmp))dec = tmp;
|
||||||
|
}
|
||||||
|
else if(header.key == "DEC" && std::isnan(dec))
|
||||||
|
{
|
||||||
|
double tmp = SkyPoint::fromDMS(header.value.toString());
|
||||||
|
if(!std::isnan(tmp))dec = tmp;
|
||||||
|
}
|
||||||
|
else if(header.key == "SCALE")
|
||||||
|
{
|
||||||
|
double tmp = header.value.toDouble(&ok);
|
||||||
|
if(ok)scale = tmp;
|
||||||
|
}
|
||||||
|
else if(header.key == "FOCALLEN")
|
||||||
|
{
|
||||||
|
double tmp = header.value.toDouble(&ok);
|
||||||
|
if(ok)focalLen = tmp;
|
||||||
|
}
|
||||||
|
else if(header.key == "PIXSIZE1" || header.key == "XPIXSZ")
|
||||||
|
{
|
||||||
|
pixSizeX = header.value.toDouble();
|
||||||
|
}
|
||||||
|
else if(header.key == "PIXSIZE2" || header.key == "YPIXSZ")
|
||||||
|
{
|
||||||
|
pixSizeY = header.value.toDouble();
|
||||||
|
}
|
||||||
|
else if(header.key == "XBINNING")
|
||||||
|
{
|
||||||
|
int tmp = header.value.toInt(&ok);
|
||||||
|
if(ok)binX = tmp;
|
||||||
|
}
|
||||||
|
else if(header.key == "YBINNING")
|
||||||
|
{
|
||||||
|
int tmp = header.value.toInt(&ok);
|
||||||
|
if(ok)binY = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.point.set(ra, dec);
|
||||||
|
if(!std::isnan(scale))
|
||||||
|
{
|
||||||
|
ret.scaleLow = ret.scaleHigh = scale;
|
||||||
|
}
|
||||||
|
else if(!(std::isnan(focalLen) || std::isnan(pixSizeX) || std::isnan(pixSizeY)))
|
||||||
|
{
|
||||||
|
const double r = 206.2648097656; // (180 * 3600) / (1000 * pi) magic number to convert pixel size to focal length ratio to arcsec.
|
||||||
|
ret.scaleLow = std::min(pixSizeX * binX / focalLen * r, pixSizeY * binY / focalLen * r);
|
||||||
|
ret.scaleHigh = std::max(pixSizeX * binX / focalLen * r, pixSizeY * binY / focalLen * r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.scaleLow *= 0.8;
|
||||||
|
ret.scaleHigh *= 1.2;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
+13
@@ -31,8 +31,19 @@ public:
|
|||||||
SkyPoint(double ra, double dec);
|
SkyPoint(double ra, double dec);
|
||||||
void set(double ra, double dec);
|
void set(double ra, double dec);
|
||||||
double RA() const { return ra; }
|
double RA() const { return ra; }
|
||||||
|
double RAHour() const { return ra / 15.0; }
|
||||||
double DEC() const { return dec; }
|
double DEC() const { return dec; }
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
|
static double fromHMS(const QString &hms);
|
||||||
|
static double fromDMS(const QString &dms);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SkyPointScale
|
||||||
|
{
|
||||||
|
SkyPoint point;
|
||||||
|
//arcsec per pixel
|
||||||
|
double scaleLow = 0.0;
|
||||||
|
double scaleHigh = 10000.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WCSDataT
|
class WCSDataT
|
||||||
@@ -51,6 +62,7 @@ public:
|
|||||||
bool worldToPixel(const SkyPoint &point, QPointF &pixel) const;
|
bool worldToPixel(const SkyPoint &point, QPointF &pixel) const;
|
||||||
void calculateBounds(double &minRa, double &maxRa, double &minDec, double &maxDec, double &crVal1, double &crVal2) const;
|
void calculateBounds(double &minRa, double &maxRa, double &minDec, double &maxDec, double &crVal1, double &crVal2) const;
|
||||||
bool valid() const { return wcs; };
|
bool valid() const { return wcs; };
|
||||||
|
SkyPointScale getRaDecScale() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImageInfoData
|
struct ImageInfoData
|
||||||
@@ -58,6 +70,7 @@ struct ImageInfoData
|
|||||||
QVector<FITSRecord> fitsHeader;
|
QVector<FITSRecord> fitsHeader;
|
||||||
QVector<QPair<QString, QString>> info;
|
QVector<QPair<QString, QString>> info;
|
||||||
std::shared_ptr<WCSDataT> wcs;
|
std::shared_ptr<WCSDataT> wcs;
|
||||||
|
SkyPointScale getCenterRaDec() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ImageInfoData);
|
Q_DECLARE_METATYPE(ImageInfoData);
|
||||||
|
|||||||
@@ -108,8 +108,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
m_databaseView = new DataBaseView(m_database, this);
|
m_databaseView = new DataBaseView(m_database, this);
|
||||||
connect(m_databaseView, SIGNAL(loadFile(QString)), this, SLOT(loadFile(QString)));
|
connect(m_databaseView, SIGNAL(loadFile(QString)), this, SLOT(loadFile(QString)));
|
||||||
|
|
||||||
|
#ifdef PLATESOLVER
|
||||||
_plateSolving = new PlateSolving(this);
|
_plateSolving = new PlateSolving(this);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, _plateSolving);
|
addDockWidget(Qt::RightDockWidgetArea, _plateSolving);
|
||||||
|
#endif
|
||||||
|
|
||||||
addToolBar(Qt::TopToolBarArea, m_stretchPanel);
|
addToolBar(Qt::TopToolBarArea, m_stretchPanel);
|
||||||
|
|
||||||
@@ -146,7 +148,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
connect(m_ringList, &ImageRingList::thumbnailLoaded, m_image, &ImageScrollArea::thumbnailLoaded);
|
connect(m_ringList, &ImageRingList::thumbnailLoaded, m_image, &ImageScrollArea::thumbnailLoaded);
|
||||||
connect(m_ringList, &ImageRingList::pixmapLoaded, m_stretchPanel, &StretchToolbar::imageLoaded);
|
connect(m_ringList, &ImageRingList::pixmapLoaded, m_stretchPanel, &StretchToolbar::imageLoaded);
|
||||||
connect(m_ringList, &ImageRingList::pixmapLoaded, histogram, &Histogram::imageLoaded);
|
connect(m_ringList, &ImageRingList::pixmapLoaded, histogram, &Histogram::imageLoaded);
|
||||||
|
#ifdef PLATESOLVER
|
||||||
connect(m_ringList, &ImageRingList::pixmapLoaded, _plateSolving, &PlateSolving::imageLoaded);
|
connect(m_ringList, &ImageRingList::pixmapLoaded, _plateSolving, &PlateSolving::imageLoaded);
|
||||||
|
#endif
|
||||||
connect(m_image, &ImageScrollArea::fileDropped, this, static_cast<void (MainWindow::*)(const QString &)>(&MainWindow::loadFile));
|
connect(m_image, &ImageScrollArea::fileDropped, this, static_cast<void (MainWindow::*)(const QString &)>(&MainWindow::loadFile));
|
||||||
|
|
||||||
QMenu *fileMenu = new QMenu(tr("File"), this);
|
QMenu *fileMenu = new QMenu(tr("File"), this);
|
||||||
@@ -255,7 +259,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
dockMenu->addAction(databaseViewDock->toggleViewAction());
|
dockMenu->addAction(databaseViewDock->toggleViewAction());
|
||||||
dockMenu->addAction(filetreeDock->toggleViewAction());
|
dockMenu->addAction(filetreeDock->toggleViewAction());
|
||||||
dockMenu->addAction(histogramDock->toggleViewAction());
|
dockMenu->addAction(histogramDock->toggleViewAction());
|
||||||
|
#ifdef PLATESOLVER
|
||||||
dockMenu->addAction(_plateSolving->toggleViewAction());
|
dockMenu->addAction(_plateSolving->toggleViewAction());
|
||||||
|
#endif
|
||||||
menuBar()->addMenu(dockMenu);
|
menuBar()->addMenu(dockMenu);
|
||||||
|
|
||||||
QMenu *helpMenu = menuBar()->addMenu(tr("Help"));
|
QMenu *helpMenu = menuBar()->addMenu(tr("Help"));
|
||||||
|
|||||||
+93
-34
@@ -1,45 +1,61 @@
|
|||||||
#include "platesolving.h"
|
#include "platesolving.h"
|
||||||
|
#include <QSettings>
|
||||||
#include "ui_platesolving.h"
|
#include "ui_platesolving.h"
|
||||||
#include "solver.h"
|
#include "solver.h"
|
||||||
#include "imageringlist.h"
|
#include "imageringlist.h"
|
||||||
|
#include "platesolvingsettings.h"
|
||||||
|
|
||||||
PlateSolving::PlateSolving(QWidget *parent)
|
PlateSolving::PlateSolving(QWidget *parent)
|
||||||
: QDockWidget(parent)
|
: QDockWidget(parent)
|
||||||
, ui(new Ui::PlateSolving)
|
, _ui(new Ui::PlateSolving)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
_ui->setupUi(this);
|
||||||
|
|
||||||
_solver = new Solver(this);
|
_solver = new Solver(this);
|
||||||
|
QSettings settings;
|
||||||
|
_solver->setIndexFolder(settings.value("platesolving/indexPath", Solver::getTenmonIndexPath()).toString());
|
||||||
auto profiles = StellarSolver::getBuiltInProfiles();
|
auto profiles = StellarSolver::getBuiltInProfiles();
|
||||||
|
int profileIdx = settings.value("platesolving/profile", 0).toInt();
|
||||||
|
_solver->setParameters(profiles[profileIdx]);
|
||||||
|
|
||||||
for(auto &profile : profiles)
|
for(auto &profile : profiles)
|
||||||
{
|
{
|
||||||
ui->profileComboBox->addItem(profile.listName);
|
_ui->profileComboBox->addItem(profile.listName);
|
||||||
}
|
}
|
||||||
|
_ui->profileComboBox->setCurrentIndex(profileIdx);
|
||||||
|
_ui->scaleUnit->setCurrentIndex(settings.value("platesolving/scaleUnit", 1).toInt());
|
||||||
|
|
||||||
connect(ui->profileComboBox, &QComboBox::currentIndexChanged, [this](int index){
|
connect(_ui->profileComboBox, &QComboBox::currentIndexChanged, [this](int index){
|
||||||
auto profiles = StellarSolver::getBuiltInProfiles();
|
auto profiles = StellarSolver::getBuiltInProfiles();
|
||||||
_solver->setParameters(profiles[index]);
|
_solver->setParameters(profiles[index]);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->extractButton, &QPushButton::clicked, this, &PlateSolving::extract);
|
connect(_ui->extractButton, &QPushButton::clicked, this, &PlateSolving::extract);
|
||||||
connect(ui->solveButton, &QPushButton::clicked, this, &PlateSolving::solve);
|
connect(_ui->solveButton, &QPushButton::clicked, this, &PlateSolving::solve);
|
||||||
|
connect(_ui->settingsButton, &QPushButton::clicked, this, &PlateSolving::settings);
|
||||||
connect(_solver, &Solver::solvingDone, this, &PlateSolving::solvingDone);
|
connect(_solver, &Solver::solvingDone, this, &PlateSolving::solvingDone);
|
||||||
connect(_solver, &Solver::extractionDone, this, &PlateSolving::extractionDone);
|
connect(_solver, &Solver::extractionDone, this, &PlateSolving::extractionDone);
|
||||||
|
connect(_solver, &Solver::logOutput, [this](const QString &log){ _ui->log->appendPlainText(log); });
|
||||||
}
|
}
|
||||||
|
|
||||||
PlateSolving::~PlateSolving()
|
PlateSolving::~PlateSolving()
|
||||||
{
|
{
|
||||||
delete ui;
|
QSettings settings;
|
||||||
|
settings.setValue("platesolving/profile", _ui->profileComboBox->currentIndex());
|
||||||
|
settings.setValue("platesolving/scaleUnit", _ui->scaleUnit->currentIndex());
|
||||||
|
delete _ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlateSolving::extract()
|
void PlateSolving::extract()
|
||||||
{
|
{
|
||||||
ui->solveButton->setDisabled(true);
|
if(!_rawImage)return;
|
||||||
ui->extractButton->setDisabled(true);
|
_ui->solveButton->setDisabled(true);
|
||||||
|
_ui->extractButton->setDisabled(true);
|
||||||
|
_ui->log->clear();
|
||||||
|
|
||||||
_solver->loadImage(_rawImage, _path);
|
_solver->loadImage(_rawImage, _path);
|
||||||
_solver->extractSources(ui->withHFR->isChecked());
|
_solvingTime.start();
|
||||||
|
_solver->extractSources(_ui->withHFR->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlateSolving::extractionDone()
|
void PlateSolving::extractionDone()
|
||||||
@@ -61,49 +77,92 @@ void PlateSolving::extractionDone()
|
|||||||
hfr /= size;
|
hfr /= size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->stars->setText(QString::number(stars.size()));
|
_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 %2x%3").arg(hfr).arg(a).arg(b));
|
||||||
|
_ui->log->appendPlainText(QString("Extraction finished in %1 ms").arg(_solvingTime.elapsed()));
|
||||||
|
|
||||||
ui->solveButton->setDisabled(false);
|
_ui->solveButton->setDisabled(false);
|
||||||
ui->extractButton->setDisabled(false);
|
_ui->extractButton->setDisabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlateSolving::solve()
|
void PlateSolving::solve()
|
||||||
{
|
{
|
||||||
ui->solveButton->setDisabled(true);
|
if(!_rawImage)return;
|
||||||
ui->extractButton->setDisabled(true);
|
_ui->solveButton->setDisabled(true);
|
||||||
|
_ui->extractButton->setDisabled(true);
|
||||||
|
_ui->log->clear();
|
||||||
|
|
||||||
_solver->loadImage(_rawImage, _path);
|
_solver->loadImage(_rawImage, _path);
|
||||||
|
if(_ui->usePosition->isChecked())
|
||||||
|
_solver->setSearchPosition(_ui->raStart->value(), _ui->decStart->value());
|
||||||
|
|
||||||
|
if(_ui->useScale->isChecked())
|
||||||
|
{
|
||||||
|
SSolver::ScaleUnits scaleUnit;
|
||||||
|
switch(_ui->scaleUnit->currentIndex())
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0:
|
||||||
|
scaleUnit = SSolver::ScaleUnits::DEG_WIDTH; break;
|
||||||
|
case 1:
|
||||||
|
scaleUnit = SSolver::ScaleUnits::ARCMIN_WIDTH; break;
|
||||||
|
case 2:
|
||||||
|
scaleUnit = SSolver::ScaleUnits::ARCSEC_PER_PIX; break;
|
||||||
|
case 3:
|
||||||
|
scaleUnit = SSolver::ScaleUnits::FOCAL_MM; break;
|
||||||
|
}
|
||||||
|
_solver->setSearchScale(_ui->fovLow->value(), _ui->fovHigh->value(), scaleUnit);
|
||||||
|
}
|
||||||
|
_solvingTime.start();
|
||||||
_solver->solveImage();
|
_solver->solveImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlateSolving::solvingDone()
|
void PlateSolving::solvingDone()
|
||||||
{
|
{
|
||||||
ui->solveButton->setDisabled(false);
|
_ui->solveButton->setDisabled(false);
|
||||||
ui->extractButton->setDisabled(false);
|
_ui->extractButton->setDisabled(false);
|
||||||
|
|
||||||
auto solution = _solver->getSolution();
|
auto solution = _solver->getSolution();
|
||||||
ui->ra->setText(QString::number(solution.ra));
|
_ui->ra->setText(QString::number(solution.ra));
|
||||||
ui->dec->setText(QString::number(solution.dec));
|
_ui->dec->setText(QString::number(solution.dec));
|
||||||
ui->orientation->setText(QString::number(solution.orientation));
|
_ui->orientation->setText(QString::number(solution.orientation));
|
||||||
ui->fieldWidth->setText(QString::number(solution.fieldWidth));
|
_ui->fieldWidth->setText(QString::number(solution.fieldWidth));
|
||||||
ui->fieldHeight->setText(QString::number(solution.fieldHeight));
|
_ui->fieldHeight->setText(QString::number(solution.fieldHeight));
|
||||||
ui->pixelScale->setText(QString::number(solution.pixscale));
|
_ui->pixelScale->setText(QString::number(solution.pixscale));
|
||||||
|
_ui->log->appendPlainText(QString("Solving finished in %1 ms").arg(_solvingTime.elapsed()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlateSolving::imageLoaded(Image *image)
|
void PlateSolving::imageLoaded(Image *image)
|
||||||
{
|
{
|
||||||
if(image)
|
if(image && image->rawImage())
|
||||||
{
|
{
|
||||||
_rawImage = image->rawImage();
|
_rawImage = image->rawImage();
|
||||||
_path = image->name();
|
_path = image->name();
|
||||||
ui->ra->clear();
|
_ui->ra->clear();
|
||||||
ui->dec->clear();
|
_ui->dec->clear();
|
||||||
ui->orientation->clear();
|
_ui->orientation->clear();
|
||||||
ui->fieldWidth->clear();
|
_ui->fieldWidth->clear();
|
||||||
ui->fieldHeight->clear();
|
_ui->fieldHeight->clear();
|
||||||
ui->pixelScale->clear();
|
_ui->pixelScale->clear();
|
||||||
ui->hfr->clear();
|
_ui->hfr->clear();
|
||||||
ui->stars->clear();
|
_ui->stars->clear();
|
||||||
|
|
||||||
|
const ImageInfoData &info = image->info();
|
||||||
|
SkyPointScale pointScale = info.getCenterRaDec();
|
||||||
|
if(!std::isnan(pointScale.point.RA()) && !std::isnan(pointScale.point.DEC()))
|
||||||
|
{
|
||||||
|
_ui->raStart->setValue(pointScale.point.RAHour());
|
||||||
|
_ui->decStart->setValue(pointScale.point.DEC());
|
||||||
|
}
|
||||||
|
|
||||||
|
_ui->scaleUnit->setCurrentIndex(2);
|
||||||
|
_ui->fovLow->setValue(pointScale.scaleLow);
|
||||||
|
_ui->fovHigh->setValue(pointScale.scaleHigh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlateSolving::settings()
|
||||||
|
{
|
||||||
|
PlateSolvingSettings settings(this);
|
||||||
|
settings.exec();
|
||||||
|
}
|
||||||
|
|||||||
+4
-1
@@ -1,6 +1,7 @@
|
|||||||
#ifndef PLATESOLVING_H
|
#ifndef PLATESOLVING_H
|
||||||
#define PLATESOLVING_H
|
#define PLATESOLVING_H
|
||||||
|
|
||||||
|
#include "qelapsedtimer.h"
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
|
|
||||||
class Solver;
|
class Solver;
|
||||||
@@ -17,6 +18,7 @@ class PlateSolving : public QDockWidget
|
|||||||
Solver *_solver;
|
Solver *_solver;
|
||||||
std::shared_ptr<RawImage> _rawImage;
|
std::shared_ptr<RawImage> _rawImage;
|
||||||
QString _path;
|
QString _path;
|
||||||
|
QElapsedTimer _solvingTime;
|
||||||
public:
|
public:
|
||||||
explicit PlateSolving(QWidget *parent = nullptr);
|
explicit PlateSolving(QWidget *parent = nullptr);
|
||||||
~PlateSolving();
|
~PlateSolving();
|
||||||
@@ -27,8 +29,9 @@ public slots:
|
|||||||
void solve();
|
void solve();
|
||||||
void solvingDone();
|
void solvingDone();
|
||||||
void imageLoaded(Image *image);
|
void imageLoaded(Image *image);
|
||||||
|
void settings();
|
||||||
private:
|
private:
|
||||||
Ui::PlateSolving *ui;
|
Ui::PlateSolving *_ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PLATESOLVING_H
|
#endif // PLATESOLVING_H
|
||||||
|
|||||||
+212
-50
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>571</width>
|
<width>860</width>
|
||||||
<height>472</height>
|
<height>700</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -30,21 +30,161 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Start point</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="3" column="3">
|
||||||
|
<widget class="QComboBox" name="scaleUnit">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Degree width</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Arcmin width</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Arcsec per pixel</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>35 mm equivalent focal length</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="usePosition">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use position</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="3">
|
||||||
|
<widget class="QDoubleSpinBox" name="fovHigh">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>100000.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="stepType">
|
||||||
|
<enum>QAbstractSpinBox::AdaptiveDecimalStepType</enum>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>10000.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_11">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Field height</string>
|
<string>DEC</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="2">
|
<item row="1" column="1">
|
||||||
<widget class="QLabel" name="label_7">
|
<widget class="QDoubleSpinBox" name="raStart">
|
||||||
<property name="text">
|
<property name="suffix">
|
||||||
<string>Pixel scale</string>
|
<string> h</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>24.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="4" column="2">
|
||||||
|
<widget class="QLabel" name="label_13">
|
||||||
|
<property name="text">
|
||||||
|
<string>High</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="fovLow">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>10000.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="stepType">
|
||||||
|
<enum>QAbstractSpinBox::AdaptiveDecimalStepType</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="useScale">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use scale</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="4">
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3">
|
||||||
|
<widget class="QDoubleSpinBox" name="decStart">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> deg</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>-90.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>90.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_12">
|
||||||
|
<property name="text">
|
||||||
|
<string>Low </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>RA</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QLabel" name="label_14">
|
||||||
|
<property name="text">
|
||||||
|
<string>Unit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Solution</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -52,20 +192,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLineEdit" name="orientation">
|
<widget class="QLineEdit" name="ra">
|
||||||
<property name="readOnly">
|
<property name="readOnly">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Orientation</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
<item row="0" column="2">
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -73,15 +206,8 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="3">
|
<item row="0" column="3">
|
||||||
<widget class="QLineEdit" name="pixelScale">
|
<widget class="QLineEdit" name="dec">
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="ra">
|
|
||||||
<property name="readOnly">
|
<property name="readOnly">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@@ -94,13 +220,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="3">
|
|
||||||
<widget class="QLineEdit" name="dec">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLineEdit" name="fieldWidth">
|
<widget class="QLineEdit" name="fieldWidth">
|
||||||
<property name="readOnly">
|
<property name="readOnly">
|
||||||
@@ -108,6 +227,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Field height</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="3">
|
<item row="1" column="3">
|
||||||
<widget class="QLineEdit" name="fieldHeight">
|
<widget class="QLineEdit" name="fieldHeight">
|
||||||
<property name="readOnly">
|
<property name="readOnly">
|
||||||
@@ -115,6 +241,34 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Orientation</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="orientation">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Pixel scale</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<widget class="QLineEdit" name="pixelScale">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_8">
|
<widget class="QLabel" name="label_8">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -144,33 +298,39 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="log">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QPushButton" name="extractButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Extract</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QPushButton" name="solveButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Solve</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QCheckBox" name="withHFR">
|
<widget class="QCheckBox" name="withHFR">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Extract with HFR</string>
|
<string>Extract with HFR</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<item row="2" column="0">
|
||||||
|
<widget class="QPushButton" name="extractButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Extract</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="2" column="1">
|
||||||
|
<widget class="QPushButton" name="solveButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Solve</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
<widget class="QPushButton" name="settingsButton">
|
<widget class="QPushButton" name="settingsButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Settings</string>
|
<string>Settings</string>
|
||||||
@@ -178,6 +338,8 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
#include "platesolvingsettings.h"
|
||||||
|
#include "ui_platesolvingsettings.h"
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include "solver.h"
|
||||||
|
|
||||||
|
PlateSolvingSettings::PlateSolvingSettings(QWidget *parent) : QDialog(parent)
|
||||||
|
, _ui(new Ui::PlateSolvingSettings)
|
||||||
|
{
|
||||||
|
_ui->setupUi(this);
|
||||||
|
|
||||||
|
_download = new HttpDownloader(this);
|
||||||
|
connect(_download, &HttpDownloader::progress, this, &PlateSolvingSettings::progress);
|
||||||
|
connect(_ui->stopDownloadButton, &QPushButton::clicked, _download, &HttpDownloader::abort);
|
||||||
|
|
||||||
|
connect(_ui->scale01, &QCheckBox::clicked, [this](){ if(_ui->scale01->isChecked())_download->downloadIndex(1); });
|
||||||
|
connect(_ui->scale02, &QCheckBox::clicked, [this](){ if(_ui->scale02->isChecked())_download->downloadIndex(2); });
|
||||||
|
connect(_ui->scale03, &QCheckBox::clicked, [this](){ if(_ui->scale03->isChecked())_download->downloadIndex(3); });
|
||||||
|
connect(_ui->scale04, &QCheckBox::clicked, [this](){ if(_ui->scale04->isChecked())_download->downloadIndex(4); });
|
||||||
|
connect(_ui->scale05, &QCheckBox::clicked, [this](){ if(_ui->scale05->isChecked())_download->downloadIndex(5); });
|
||||||
|
connect(_ui->scale06, &QCheckBox::clicked, [this](){ if(_ui->scale06->isChecked())_download->downloadIndex(6); });
|
||||||
|
connect(_ui->scale07, &QCheckBox::clicked, [this](){ if(_ui->scale07->isChecked())_download->downloadIndex(7); });
|
||||||
|
connect(_ui->scale08, &QCheckBox::clicked, [this](){ if(_ui->scale08->isChecked())_download->downloadIndex(8); });
|
||||||
|
connect(_ui->scale09, &QCheckBox::clicked, [this](){ if(_ui->scale09->isChecked())_download->downloadIndex(9); });
|
||||||
|
connect(_ui->scale10, &QCheckBox::clicked, [this](){ if(_ui->scale10->isChecked())_download->downloadIndex(10); });
|
||||||
|
connect(_ui->scale11, &QCheckBox::clicked, [this](){ if(_ui->scale11->isChecked())_download->downloadIndex(11); });
|
||||||
|
connect(_ui->scale12, &QCheckBox::clicked, [this](){ if(_ui->scale12->isChecked())_download->downloadIndex(12); });
|
||||||
|
connect(_ui->scale13, &QCheckBox::clicked, [this](){ if(_ui->scale13->isChecked())_download->downloadIndex(13); });
|
||||||
|
connect(_ui->scale14, &QCheckBox::clicked, [this](){ if(_ui->scale14->isChecked())_download->downloadIndex(14); });
|
||||||
|
connect(_ui->scale15, &QCheckBox::clicked, [this](){ if(_ui->scale15->isChecked())_download->downloadIndex(15); });
|
||||||
|
connect(_ui->scale16, &QCheckBox::clicked, [this](){ if(_ui->scale16->isChecked())_download->downloadIndex(16); });
|
||||||
|
connect(_ui->scale17, &QCheckBox::clicked, [this](){ if(_ui->scale17->isChecked())_download->downloadIndex(17); });
|
||||||
|
connect(_ui->scale18, &QCheckBox::clicked, [this](){ if(_ui->scale18->isChecked())_download->downloadIndex(18); });
|
||||||
|
connect(_ui->scale19, &QCheckBox::clicked, [this](){ if(_ui->scale19->isChecked())_download->downloadIndex(19); });
|
||||||
|
|
||||||
|
QSettings settings;
|
||||||
|
_ui->indexPaths->addItems(settings.value("platesolving/indexPaths", Solver::getIndexPaths()).toStringList());
|
||||||
|
_ui->indexPaths->setCurrentText(settings.value("platesolving/indexPath", Solver::getTenmonIndexPath()).toString());
|
||||||
|
connect(_ui->addButton, &QPushButton::clicked, [this](){
|
||||||
|
QString path = QFileDialog::getExistingDirectory(this, tr("Index files directory"), Solver::getTenmonIndexPath());
|
||||||
|
if(!path.isEmpty())
|
||||||
|
{
|
||||||
|
bool contain = false;
|
||||||
|
for(int i=0; i<_ui->indexPaths->count(); i++)
|
||||||
|
{
|
||||||
|
if(path == _ui->indexPaths->itemText(i))
|
||||||
|
{
|
||||||
|
contain = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!contain)_ui->indexPaths->addItem(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(_ui->removeButton, &QPushButton::clicked, [this](){
|
||||||
|
int current = _ui->indexPaths->currentIndex();
|
||||||
|
if(current > 0)_ui->indexPaths->removeItem(current);
|
||||||
|
});
|
||||||
|
|
||||||
|
_watcher = new QFileSystemWatcher(this);
|
||||||
|
_watcher->addPath(Solver::getTenmonIndexPath());
|
||||||
|
connect(_watcher, &QFileSystemWatcher::directoryChanged, this, &PlateSolvingSettings::checkIndexFiles);
|
||||||
|
connect(_ui->indexPaths, &QComboBox::currentTextChanged, [this](const QString &text){
|
||||||
|
_watcher->removePaths(_watcher->directories());
|
||||||
|
_watcher->addPath(text);
|
||||||
|
});
|
||||||
|
connect(_ui->indexPaths, &QComboBox::currentIndexChanged, [this](int index){
|
||||||
|
_ui->indexFilesGroup->setEnabled(index == 0);
|
||||||
|
});
|
||||||
|
checkIndexFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
PlateSolvingSettings::~PlateSolvingSettings()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.setValue("platesolving/indexPath", _ui->indexPaths->currentText());
|
||||||
|
QStringList paths;
|
||||||
|
for(int i=0; i<_ui->indexPaths->count(); i++)
|
||||||
|
paths.append(_ui->indexPaths->itemText(i));
|
||||||
|
|
||||||
|
settings.setValue("platesolving/indexPaths", paths);
|
||||||
|
delete _ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlateSolvingSettings::checkIndexFiles()
|
||||||
|
{
|
||||||
|
QString indexDir = Solver::getTenmonIndexPath() + "/";
|
||||||
|
auto checkScale = [indexDir](QCheckBox *box, int scale)
|
||||||
|
{
|
||||||
|
bool all = true;
|
||||||
|
QStringList files = HttpDownloader::indexFileNames(scale);
|
||||||
|
for(auto &file : files)
|
||||||
|
if(!QFile::exists(indexDir + file))
|
||||||
|
{
|
||||||
|
all = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
box->setChecked(all);
|
||||||
|
if(all)box->setStyleSheet("color: green; font: bold;");
|
||||||
|
else box->setStyleSheet("");
|
||||||
|
};
|
||||||
|
|
||||||
|
checkScale(_ui->scale01, 1);
|
||||||
|
checkScale(_ui->scale02, 2);
|
||||||
|
checkScale(_ui->scale03, 3);
|
||||||
|
checkScale(_ui->scale04, 4);
|
||||||
|
checkScale(_ui->scale05, 5);
|
||||||
|
checkScale(_ui->scale06, 6);
|
||||||
|
checkScale(_ui->scale07, 7);
|
||||||
|
checkScale(_ui->scale08, 8);
|
||||||
|
checkScale(_ui->scale09, 9);
|
||||||
|
checkScale(_ui->scale10, 10);
|
||||||
|
checkScale(_ui->scale11, 11);
|
||||||
|
checkScale(_ui->scale12, 12);
|
||||||
|
checkScale(_ui->scale13, 13);
|
||||||
|
checkScale(_ui->scale14, 14);
|
||||||
|
checkScale(_ui->scale15, 15);
|
||||||
|
checkScale(_ui->scale16, 16);
|
||||||
|
checkScale(_ui->scale17, 17);
|
||||||
|
checkScale(_ui->scale18, 18);
|
||||||
|
checkScale(_ui->scale19, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlateSolvingSettings::progress(int percent, int files)
|
||||||
|
{
|
||||||
|
_ui->filesRemaining->setText(tr("%1 files").arg(files));
|
||||||
|
_ui->downloadProgressbar->setValue(percent);
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef PLATESOLVINGSETTINGS_H
|
||||||
|
#define PLATESOLVINGSETTINGS_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QFileSystemWatcher>
|
||||||
|
#include "httpdownloader.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class PlateSolvingSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlateSolvingSettings : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
HttpDownloader *_download;
|
||||||
|
QFileSystemWatcher *_watcher;
|
||||||
|
public:
|
||||||
|
explicit PlateSolvingSettings(QWidget *parent = nullptr);
|
||||||
|
~PlateSolvingSettings();
|
||||||
|
void checkIndexFiles();
|
||||||
|
protected slots:
|
||||||
|
void progress(int percent, int files);
|
||||||
|
private:
|
||||||
|
Ui::PlateSolvingSettings *_ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLATESOLVINGSETTINGS_H
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>PlateSolvingSettings</class>
|
||||||
|
<widget class="QDialog" name="PlateSolvingSettings">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>787</width>
|
||||||
|
<height>479</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="indexPaths">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="addButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="removeButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p>Plate solving need index files in order to solve an image. You can download them here by checking. This is possible only to default location.</p><p>It is required to download index files that cover 100%-50% field of view and recomended 100%-10%. So for images with 70' field of view it is required to download index files in 30'-85' and recomended 4'-85'.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="indexFilesGroup">
|
||||||
|
<property name="title">
|
||||||
|
<string>Index files</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale14">
|
||||||
|
<property name="text">
|
||||||
|
<string>240' - 340'index-4114.fits (1.4 MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale17">
|
||||||
|
<property name="text">
|
||||||
|
<string>680' - 1000' index-4117.fits (242 kiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale16">
|
||||||
|
<property name="text">
|
||||||
|
<string>480' - 680' index-4116.fits (400 kiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale18">
|
||||||
|
<property name="text">
|
||||||
|
<string>1000' - 1400' index-4118.fits (183 kiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale15">
|
||||||
|
<property name="text">
|
||||||
|
<string>340' - 480' index-4115.fits (723 kiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale19">
|
||||||
|
<property name="text">
|
||||||
|
<string>1400' - 2000' index-4119.fits (141 kiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale12">
|
||||||
|
<property name="text">
|
||||||
|
<string>120' - 170' index-4112.fits (5.1MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale13">
|
||||||
|
<property name="text">
|
||||||
|
<string>170' - 240' index-4113.fits (2.7MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="17" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale11">
|
||||||
|
<property name="text">
|
||||||
|
<string>85' - 120' index-4111.fits (9.8 MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="18" column="0">
|
||||||
|
<widget class="QCheckBox" name="scale10">
|
||||||
|
<property name="text">
|
||||||
|
<string>60' - 85' index-4110.fits (24 MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QCheckBox" name="scale09">
|
||||||
|
<property name="text">
|
||||||
|
<string>42' - 60' index-4109.fits (48 MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QCheckBox" name="scale08">
|
||||||
|
<property name="text">
|
||||||
|
<string>30' - 42' index-4108.fits (91 MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QCheckBox" name="scale07">
|
||||||
|
<property name="text">
|
||||||
|
<string>22' - 30' index-4107.fits (158 MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QCheckBox" name="scale06">
|
||||||
|
<property name="text">
|
||||||
|
<string>16' - 22' index-5206-*.fits (294 MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QCheckBox" name="scale05">
|
||||||
|
<property name="text">
|
||||||
|
<string>11' - 16' index-5205-*.fits (587 MiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QCheckBox" name="scale04">
|
||||||
|
<property name="text">
|
||||||
|
<string>8' - 11' index-5204-*.fits (1.2 GiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="QCheckBox" name="scale03">
|
||||||
|
<property name="text">
|
||||||
|
<string>4.0' - 5.6' index-5203-*.fits (2.3 GiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QCheckBox" name="scale02">
|
||||||
|
<property name="text">
|
||||||
|
<string>5.6' - 8.0' index-5202-*.fits (4.6 GiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="17" column="1">
|
||||||
|
<widget class="QCheckBox" name="scale01">
|
||||||
|
<property name="text">
|
||||||
|
<string>2.0' - 2.8' index-5201-*.fits (8.9 GiB)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="filesRemaining">
|
||||||
|
<property name="text">
|
||||||
|
<string>0 files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QProgressBar" name="downloadProgressbar">
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="stopDownloadButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Stop download</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
+34
-1
@@ -3,8 +3,8 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
#include <QFloat16>
|
#include <QFloat16>
|
||||||
|
#include <QColorSpace>
|
||||||
#include <lcms2.h>
|
#include <lcms2.h>
|
||||||
//#include <libstellarsolver/stellarsolver.h>
|
|
||||||
|
|
||||||
using F16 = qfloat16;
|
using F16 = qfloat16;
|
||||||
|
|
||||||
@@ -804,6 +804,39 @@ std::shared_ptr<RawImage> RawImage::fromPlanar(const void *pixels, uint32_t w, u
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<RawImage> RawImage::toPlanar()
|
||||||
|
{
|
||||||
|
std::shared_ptr<RawImage> ret = std::make_shared<RawImage>(m_width, m_height, 1, m_type);
|
||||||
|
size_t size = m_width * m_height;
|
||||||
|
size_t ch = m_ch;
|
||||||
|
|
||||||
|
auto convert = [&](auto *in, auto *out)
|
||||||
|
{
|
||||||
|
for(size_t i=0; i<size; i++)
|
||||||
|
out[i] = in[i * ch];
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(m_type)
|
||||||
|
{
|
||||||
|
case UINT8:
|
||||||
|
convert(static_cast<uint8_t*>(data()), static_cast<uint8_t*>(ret->data()));
|
||||||
|
break;
|
||||||
|
case UINT16:
|
||||||
|
case FLOAT16:
|
||||||
|
convert(static_cast<uint16_t*>(data()), static_cast<uint16_t*>(ret->data()));
|
||||||
|
break;
|
||||||
|
case UINT32:
|
||||||
|
case FLOAT32:
|
||||||
|
convert(static_cast<uint32_t*>(data()), static_cast<uint32_t*>(ret->data()));
|
||||||
|
break;
|
||||||
|
case FLOAT64:
|
||||||
|
convert(static_cast<double*>(data()), static_cast<double*>(ret->data()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<RawImage> RawImage::split() const
|
std::vector<RawImage> RawImage::split() const
|
||||||
{
|
{
|
||||||
std::vector<RawImage> planes;
|
std::vector<RawImage> planes;
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,6 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QColorSpace>
|
|
||||||
|
|
||||||
extern int THUMB_SIZE;
|
extern int THUMB_SIZE;
|
||||||
extern int THUMB_SIZE_BORDER;
|
extern int THUMB_SIZE_BORDER;
|
||||||
@@ -114,6 +113,7 @@ public:
|
|||||||
|
|
||||||
static std::shared_ptr<RawImage> fromPlanar(const RawImage &img);
|
static std::shared_ptr<RawImage> fromPlanar(const RawImage &img);
|
||||||
static std::shared_ptr<RawImage> fromPlanar(const void *pixels, uint32_t w, uint32_t h, uint32_t ch, DataType type);
|
static std::shared_ptr<RawImage> fromPlanar(const void *pixels, uint32_t w, uint32_t h, uint32_t ch, DataType type);
|
||||||
|
std::shared_ptr<RawImage> toPlanar();
|
||||||
static size_t typeSize(DataType type);
|
static size_t typeSize(DataType type);
|
||||||
std::vector<RawImage> split() const;
|
std::vector<RawImage> split() const;
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
|
|||||||
+37
-13
@@ -12,11 +12,10 @@
|
|||||||
Solver::Solver(QObject *parent) : QObject(parent)
|
Solver::Solver(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
_solver = new StellarSolver(this);
|
_solver = new StellarSolver(this);
|
||||||
|
connect(_solver, &StellarSolver::logOutput, this, &Solver::logOutput);
|
||||||
QStringList indexFolder = getIndexPaths();
|
|
||||||
|
|
||||||
_solver->setProperty("ProcessType", SSolver::SOLVE);
|
_solver->setProperty("ProcessType", SSolver::SOLVE);
|
||||||
_solver->setIndexFolderPaths(indexFolder);
|
_solver->setIndexFolderPaths(QStringList(getTenmonIndexPath()));
|
||||||
_solver->setParameterProfile(SSolver::Parameters::ALL_STARS);
|
_solver->setParameterProfile(SSolver::Parameters::ALL_STARS);
|
||||||
|
|
||||||
connect(_solver, &StellarSolver::finished, this, &Solver::finished);
|
connect(_solver, &StellarSolver::finished, this, &Solver::finished);
|
||||||
@@ -26,9 +25,9 @@ Solver::~Solver()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Solver::setIndexFolders(const QStringList &indexPaths)
|
void Solver::setIndexFolder(const QString &indexPath)
|
||||||
{
|
{
|
||||||
_solver->setIndexFolderPaths(indexPaths);
|
_solver->setIndexFolderPaths(QStringList(indexPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Solver::loadImage(const QString &path)
|
bool Solver::loadImage(const QString &path)
|
||||||
@@ -46,6 +45,11 @@ bool Solver::loadImage(const QString &path)
|
|||||||
bool Solver::loadImage(std::shared_ptr<RawImage> &image, const QString &path)
|
bool Solver::loadImage(std::shared_ptr<RawImage> &image, const QString &path)
|
||||||
{
|
{
|
||||||
_rawImage = image;
|
_rawImage = image;
|
||||||
|
if(_rawImage->channels() > 1)
|
||||||
|
_rawImagePlanar = _rawImage->toPlanar();
|
||||||
|
else
|
||||||
|
_rawImagePlanar = _rawImage;
|
||||||
|
|
||||||
switch(_rawImage->type())
|
switch(_rawImage->type())
|
||||||
{
|
{
|
||||||
case RawImage::UINT8:
|
case RawImage::UINT8:
|
||||||
@@ -68,13 +72,15 @@ bool Solver::loadImage(std::shared_ptr<RawImage> &image, const QString &path)
|
|||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_stats.bytesPerPixel = _rawImage->typeSize(_rawImage->type());
|
_stats.bytesPerPixel = _rawImage->typeSize(_rawImagePlanar->type());
|
||||||
_stats.channels = _rawImage->channels();
|
_stats.channels = _rawImagePlanar->channels();
|
||||||
_stats.width = _rawImage->width();
|
_stats.width = _rawImagePlanar->width();
|
||||||
_stats.height = _rawImage->height();
|
_stats.height = _rawImagePlanar->height();
|
||||||
_stats.samples_per_channel = _stats.width * _stats.height;
|
_stats.samples_per_channel = _stats.width * _stats.height;
|
||||||
|
|
||||||
_loaded = _solver->loadNewImageBuffer(_stats, (const uint8_t*)_rawImage->data());
|
_solver->clearSearchPosition();
|
||||||
|
_solver->clearSearchScale();
|
||||||
|
_loaded = _solver->loadNewImageBuffer(_stats, (const uint8_t*)_rawImagePlanar->data());
|
||||||
_path = path;
|
_path = path;
|
||||||
return _loaded;
|
return _loaded;
|
||||||
}
|
}
|
||||||
@@ -169,17 +175,35 @@ void Solver::updateHeader()
|
|||||||
|
|
||||||
void Solver::setParameters(Parameters::ParametersProfile profile)
|
void Solver::setParameters(Parameters::ParametersProfile profile)
|
||||||
{
|
{
|
||||||
_solver->setParameterProfile(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)
|
void Solver::setParameters(const Parameters ¶meters)
|
||||||
{
|
{
|
||||||
_solver->setParameters(parameters);
|
auto profile = parameters;
|
||||||
|
// TODO seems like any paralel is crashing with Qt6
|
||||||
|
profile.partition = false;
|
||||||
|
//profile.inParallel = false;
|
||||||
|
_solver->setParameters(profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Solver::setSearchScale(double fovLow, double fowHigh, SSolver::ScaleUnits units)
|
||||||
|
{
|
||||||
|
_solver->setSearchScale(fovLow, fowHigh, units);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Solver::setSearchPosition(double ra, double dec)
|
||||||
|
{
|
||||||
|
_solver->setSearchPositionRaDec(ra, dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Solver::getIndexPaths()
|
QStringList Solver::getIndexPaths()
|
||||||
{
|
{
|
||||||
QStringList paths;// = StellarSolver::getDefaultIndexFolderPaths();
|
QStringList paths = StellarSolver::getDefaultIndexFolderPaths();
|
||||||
paths.prepend(getTenmonIndexPath());
|
paths.prepend(getTenmonIndexPath());
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ class Solver : public QObject
|
|||||||
QString _path;
|
QString _path;
|
||||||
QString _error;
|
QString _error;
|
||||||
std::shared_ptr<RawImage> _rawImage;
|
std::shared_ptr<RawImage> _rawImage;
|
||||||
|
std::shared_ptr<RawImage> _rawImagePlanar;
|
||||||
public:
|
public:
|
||||||
explicit Solver(QObject *parent = nullptr);
|
explicit Solver(QObject *parent = nullptr);
|
||||||
~Solver();
|
~Solver();
|
||||||
void setIndexFolders(const QStringList &list);
|
void setIndexFolder(const QString &indexPath);
|
||||||
|
|
||||||
bool loadImage(const QString &path);
|
bool loadImage(const QString &path);
|
||||||
bool loadImage(std::shared_ptr<RawImage> &image, const QString &path);
|
bool loadImage(std::shared_ptr<RawImage> &image, const QString &path);
|
||||||
@@ -32,6 +33,8 @@ public:
|
|||||||
void updateHeader();
|
void updateHeader();
|
||||||
void setParameters(SSolver::Parameters::ParametersProfile profile);
|
void setParameters(SSolver::Parameters::ParametersProfile profile);
|
||||||
void setParameters(const SSolver::Parameters ¶meters);
|
void setParameters(const SSolver::Parameters ¶meters);
|
||||||
|
void setSearchScale(double fovLow, double fowHigh, ScaleUnits units);
|
||||||
|
void setSearchPosition(double ra, double dec);
|
||||||
|
|
||||||
static QStringList getIndexPaths();
|
static QStringList getIndexPaths();
|
||||||
static QString getTenmonIndexPath();
|
static QString getTenmonIndexPath();
|
||||||
@@ -40,6 +43,7 @@ public slots:
|
|||||||
signals:
|
signals:
|
||||||
void solvingDone();
|
void solvingDone();
|
||||||
void extractionDone();
|
void extractionDone();
|
||||||
|
void logOutput(const QString &log);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SOLVER_H
|
#endif // SOLVER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user