Add modifing FITS records
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "loadrunable.h"
|
||||
#include "rawimage.h"
|
||||
#include "loadrunable.h"
|
||||
#include <fitsio2.h>
|
||||
|
||||
namespace Script
|
||||
{
|
||||
@@ -16,6 +17,8 @@ ScriptEngine::ScriptEngine(QObject *parent) : QObject(parent)
|
||||
{
|
||||
QJSValue engine = _jsEngine->newQObject(this);
|
||||
_jsEngine->globalObject().setProperty("engine", engine);
|
||||
QJSValue fitsRecordObject = _jsEngine->newQMetaObject(&FITSRecordModify::staticMetaObject);
|
||||
_jsEngine->globalObject().setProperty("FITSRecordModify", fitsRecordObject);
|
||||
_database->init(QLatin1String("scriptengine"));
|
||||
_semaphore.release(_pool->maxThreadCount());
|
||||
}
|
||||
@@ -303,6 +306,136 @@ QJSValue File::fitsRecords()
|
||||
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
|
||||
{
|
||||
return _engine->isMarked(this);
|
||||
@@ -408,4 +541,20 @@ void ScriptEngineThread::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()});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@ signals:
|
||||
void finished();
|
||||
};
|
||||
|
||||
class FITSRecordModify;
|
||||
|
||||
class File : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -93,6 +95,7 @@ public:
|
||||
Q_INVOKABLE QString fitsValue(const QString &key);
|
||||
Q_INVOKABLE QJSValue fitsValues(const QString &key);
|
||||
Q_INVOKABLE QJSValue fitsRecords();
|
||||
Q_INVOKABLE bool modifyFITSRecords(const FITSRecordModify *modify);
|
||||
Q_INVOKABLE bool isMarked() const;
|
||||
Q_INVOKABLE File* copy(const QString &newpath) const;
|
||||
Q_INVOKABLE bool move(const QString &newpath);
|
||||
@@ -101,6 +104,21 @@ public:
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user