Add modifing FITS records

This commit is contained in:
2024-04-12 09:58:21 +02:00
parent 933fd4a2a0
commit ae84cbdfe0
2 changed files with 167 additions and 0 deletions
+149
View File
@@ -5,6 +5,7 @@
#include "loadrunable.h" #include "loadrunable.h"
#include "rawimage.h" #include "rawimage.h"
#include "loadrunable.h" #include "loadrunable.h"
#include <fitsio2.h>
namespace Script namespace Script
{ {
@@ -16,6 +17,8 @@ ScriptEngine::ScriptEngine(QObject *parent) : QObject(parent)
{ {
QJSValue engine = _jsEngine->newQObject(this); QJSValue engine = _jsEngine->newQObject(this);
_jsEngine->globalObject().setProperty("engine", engine); _jsEngine->globalObject().setProperty("engine", engine);
QJSValue fitsRecordObject = _jsEngine->newQMetaObject(&FITSRecordModify::staticMetaObject);
_jsEngine->globalObject().setProperty("FITSRecordModify", fitsRecordObject);
_database->init(QLatin1String("scriptengine")); _database->init(QLatin1String("scriptengine"));
_semaphore.release(_pool->maxThreadCount()); _semaphore.release(_pool->maxThreadCount());
} }
@@ -303,6 +306,136 @@ QJSValue File::fitsRecords()
return array; return array;
} }
bool File::modifyFITSRecords(const FITSRecordModify *modify)
{
_fitsKeywordsLoaded = false;
_fitsKeywords.clear();
if(QRegularExpression("fits", QRegularExpression::CaseInsensitiveOption).match(suffix()).hasMatch())
{
fitsfile *file;
int status = 0;
fits_open_diskfile(&file, _path.toLocal8Bit().data(), READWRITE, &status);
int num = 0;
fits_get_num_hdus(file, &num, &status);
if(status)
{
_engine->newMessage("Failed to open FITS file", true);
return false;
}
int imgtype;
int naxis;
long naxes[3] = {0};
int type = -1;
for(int i=1; i <= num; i++)
{
fits_movabs_hdu(file, i, IMAGE_HDU, &status);
fits_get_hdu_type(file, &type, &status);
fits_get_img_param(file, 3, &imgtype, &naxis, naxes, &status);
if(type == IMAGE_HDU && naxis >= 2 && naxis <= 3 && status == 0)
break;
if(i == num)return false;
}
for(auto &remove : modify->_remove)
{
fits_delete_key(file, remove.toLatin1().data(), &status);
}
for(auto &record : modify->_update)
{
switch(record.value.typeId())
{
case QMetaType::Bool:
{
int val = record.value.toBool();
fits_update_key(file, TLOGICAL, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
break;
}
case QMetaType::Int:
case QMetaType::UInt:
{
long long val = record.value.toLongLong();
fits_update_key(file, TLONGLONG, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
break;
}
case QMetaType::QString:
{
QByteArray val = record.value.toString().toLatin1();
fits_update_key(file, TSTRING, record.key.data(), val.isEmpty() ? nullptr : val.data(), record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
break;
}
case QMetaType::Float:
case QMetaType::Double:
{
double val = record.value.toDouble();
fits_update_key(file, TDOUBLE, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
break;
}
default:
_engine->newMessage("Unknown type for KEY " + record.key, true);
return false;
break;
}
if(status)
{
char error[100];
fits_get_errstatus(status, error);
_engine->newMessage(QString("Error when updating KEY {} {}").arg(record.key).arg(error), true);
return false;
}
}
for(auto &record : modify->_add)
{
switch(record.value.typeId())
{
case QMetaType::Bool:
{
int val = record.value.toBool();
fits_write_key(file, TLOGICAL, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
break;
}
case QMetaType::Int:
case QMetaType::UInt:
{
long long val = record.value.toLongLong();
fits_write_key(file, TLONGLONG, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
break;
}
case QMetaType::QString:
{
QByteArray val = record.value.toString().toLatin1();
fits_write_key(file, TSTRING, record.key.data(), val.isEmpty() ? nullptr : val.data(), record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
break;
}
case QMetaType::Float:
case QMetaType::Double:
{
double val = record.value.toDouble();
fits_write_key(file, TDOUBLE, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
break;
}
default:
_engine->newMessage("Unknown type for KEY " + record.key, true);
return false;
break;
}
if(status)
{
char error[100];
fits_get_errstatus(status, error);
_engine->newMessage(QString("Error when adding KEY {} {}").arg(record.key).arg(error), true);
return false;
}
}
fits_close_file(file, &status);
return status == 0;
}
return false;
}
bool File::isMarked() const bool File::isMarked() const
{ {
return _engine->isMarked(this); return _engine->isMarked(this);
@@ -408,4 +541,20 @@ void ScriptEngineThread::interrupt()
if(_engine)_engine->interrupt(); if(_engine)_engine->interrupt();
} }
void FITSRecordModify::removeKeyword(const QString &key)
{
if(!_remove.contains(key))
_remove.append(key);
}
void FITSRecordModify::updateKeyword(const QString &key, const QVariant &value, const QString &comment)
{
_update.append({key.toLatin1(), value, comment.toLatin1()});
}
void FITSRecordModify::addKeyword(const QString &key, const QVariant &value, const QString &comment)
{
_update.append({key.toLatin1(), value, comment.toLatin1()});
}
} }
+18
View File
@@ -64,6 +64,8 @@ signals:
void finished(); void finished();
}; };
class FITSRecordModify;
class File : public QObject class File : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -93,6 +95,7 @@ public:
Q_INVOKABLE QString fitsValue(const QString &key); Q_INVOKABLE QString fitsValue(const QString &key);
Q_INVOKABLE QJSValue fitsValues(const QString &key); Q_INVOKABLE QJSValue fitsValues(const QString &key);
Q_INVOKABLE QJSValue fitsRecords(); Q_INVOKABLE QJSValue fitsRecords();
Q_INVOKABLE bool modifyFITSRecords(const FITSRecordModify *modify);
Q_INVOKABLE bool isMarked() const; Q_INVOKABLE bool isMarked() const;
Q_INVOKABLE File* copy(const QString &newpath) const; Q_INVOKABLE File* copy(const QString &newpath) const;
Q_INVOKABLE bool move(const QString &newpath); Q_INVOKABLE bool move(const QString &newpath);
@@ -101,6 +104,21 @@ public:
Q_INVOKABLE QJSValue stats(); Q_INVOKABLE QJSValue stats();
}; };
class FITSRecordModify : public QObject
{
Q_OBJECT
QStringList _remove;
QVector<FITSRecord> _update;
QVector<FITSRecord> _add;
friend class File;
public:
Q_INVOKABLE FITSRecordModify(){};
Q_INVOKABLE void removeKeyword(const QString &key);
Q_INVOKABLE void updateKeyword(const QString &key, const QVariant &value, const QString &comment = QString());
Q_INVOKABLE void addKeyword(const QString &key, const QVariant &value, const QString &comment = QString());
};
} }
#endif // SCRIPTENGINE_H #endif // SCRIPTENGINE_H