#include "solver.h" #include #include #include #include "rawimage.h" #include "loadrunable.h" #include "scriptengine.h" Solver::Solver(QObject *parent) : QObject(parent) { _solver = std::make_unique(); QStringList indexFolder = StellarSolver::getDefaultIndexFolderPaths(); _solver->setProperty("ProcessType", SSolver::SOLVE); _solver->setIndexFolderPaths(indexFolder); _solver->setParameterProfile(SSolver::Parameters::ALL_STARS); } Solver::~Solver() { } bool Solver::solveImage(const QString &path) { ImageInfoData info; std::shared_ptr rawImage; if(loadImage(path, info, rawImage, true)) { _path = path; switch(rawImage->type()) { case RawImage::UINT8: _stats.dataType = TBYTE; break; case RawImage::UINT16: _stats.dataType = TUSHORT; break; case RawImage::UINT32: _stats.dataType = TUINT; break; case RawImage::FLOAT32: _stats.dataType = TFLOAT; break; case RawImage::FLOAT64: _stats.dataType = TDOUBLE; break; default: _error = tr("Unsupported image data type"); return false; break; } _stats.bytesPerPixel = rawImage->typeSize(rawImage->type()); _stats.channels = rawImage->channels(); _stats.width = rawImage->width(); _stats.height = rawImage->height(); _stats.samples_per_channel = _stats.width * _stats.height; _solver->loadNewImageBuffer(_stats, (const uint8_t*)rawImage->data()); return _solver->solve(); } return false; } FITSImage::Solution Solver::getSolution() const { return _solver->getSolution(); } QString Solver::errorMessage() const { return _error; } void Solver::updateHeader() { FITSImage::Solution solution = getSolution(); qDebug() << "RA" << solution.ra << "DEC" << solution.dec << "Orient" << solution.orientation << "field wxh" << solution.fieldWidth << solution.fieldHeight << solution.pixscale; qDebug() << "error" << solution.raError << solution.decError; double rotationDeg = 360.0 - solution.orientation; if(rotationDeg > 360)rotationDeg -= 360; double rotationRad = rotationDeg / 180.0 * M_PI; double cdeltx = (solution.parity == FITSImage::NEGATIVE ? solution.pixscale : -solution.pixscale) / 3600.0; double cdelty = solution.pixscale / 3600.0; Script::File file(_path, nullptr); Script::FITSRecordModify modify; 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)")); modify.updateKeyword("CDELT2", cdelty, QByteArray("Y pixel size (deg)")); modify.updateKeyword("CRVAL1", solution.ra, QByteArray("RA of reference pixel (deg)")); modify.updateKeyword("CRVAL2", solution.dec, QByteArray("DEC of reference pixel (deg)")); modify.updateKeyword("CD1_1", std::cos(rotationRad) * cdeltx, QByteArray("CD matrix to convert (x,y) to (RA, DEC)")); modify.updateKeyword("CD1_2",-std::sin(rotationRad) * cdelty, QByteArray("CD matrix to convert (x,y) to (RA, DEC)")); modify.updateKeyword("CD2_1", std::sin(rotationRad) * cdeltx, QByteArray("CD matrix to convert (x,y) to (RA, DEC)")); modify.updateKeyword("CD2_2", std::cos(rotationRad) * cdelty, QByteArray("CD matrix to convert (x,y) to (RA, DEC)")); modify.updateKeyword("CROTA1", rotationDeg, QByteArray("Image twist X axis (deg)")); modify.updateKeyword("CROTA2", rotationDeg, QByteArray("Image twist Y axis (deg)")); modify.updateKeyword("CTYPE1", "RA---TAN", QByteArray("first parameter RA, projection TANgential")); modify.updateKeyword("CTYPE2", "DEC--TAN", QByteArray("first parameter DEC, projection TANgential")); modify.updateKeyword("RADESYS", "ICRS", QByteArray("International Celestial Reference System")); modify.updateKeyword("EQUINOX", 2000, QByteArray("Equinox of coordinates")); file.modifyFITSRecords(&modify); }