Files
tenmon/solver.cpp
T

108 lines
4.2 KiB
C++

#include "solver.h"
#include <fitsio.h>
#include <wcslib/wcshdr.h>
#include <wcslib/wcsutil.h>
#include "rawimage.h"
#include "loadrunable.h"
#include "scriptengine.h"
Solver::Solver(QObject *parent) : QObject(parent)
{
_solver = std::make_unique<StellarSolver>();
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> 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);
}