Compare commits

...

5 Commits

Author SHA1 Message Date
nou 1a214a169e Blind and update question for platesolve script 2025-04-28 17:25:07 +02:00
nou f8704c51d8 FITS hightlight settings 2025-04-28 17:06:24 +02:00
nou 3feee0256c New core.question script method 2025-04-28 17:04:45 +02:00
nou 53472d807c Adding new scripts 2025-04-27 22:54:29 +02:00
nou 9f06269aa4 Improve chart graph 2025-04-27 17:43:32 +02:00
12 changed files with 199 additions and 26 deletions
+39
View File
@@ -272,6 +272,45 @@ QJSValue BatchProcessing::getItem(const QStringList &items, const QString &label
return ok ? ret : QJSValue();
}
QJSValue BatchProcessing::question(const QString &question, const QStringList &buttons, const QString &title)
{
QMessageBox::StandardButtons standardButtons = QMessageBox::NoButton;
if(buttons.contains("ok"))standardButtons |= QMessageBox::Ok;
if(buttons.contains("yes"))standardButtons |= QMessageBox::Yes;
if(buttons.contains("no"))standardButtons |= QMessageBox::No;
if(buttons.contains("yesall"))standardButtons |= QMessageBox::YesToAll;
if(buttons.contains("noall"))standardButtons |= QMessageBox::NoToAll;
if(buttons.contains("abort"))standardButtons |= QMessageBox::Abort;
if(buttons.contains("retry"))standardButtons |= QMessageBox::Retry;
if(buttons.contains("ignore"))standardButtons |= QMessageBox::Ignore;
if(buttons.contains("cancel"))standardButtons |= QMessageBox::Cancel;
if(buttons.contains("discard"))standardButtons |= QMessageBox::Discard;
if(buttons.contains("apply"))standardButtons |= QMessageBox::Apply;
if(buttons.contains("reset"))standardButtons |= QMessageBox::Reset;
if(standardButtons == QMessageBox::NoButton)standardButtons = QMessageBox::Ok;
QMessageBox::StandardButton button = QMessageBox::question(this, title, question, standardButtons);
QJSValue ret;
switch(button)
{
default:
case QMessageBox::Ok: ret = "ok"; break;
case QMessageBox::Yes: ret = "yes"; break;
case QMessageBox::No: ret = "no"; break;
case QMessageBox::YesToAll: ret = "yesall"; break;
case QMessageBox::NoToAll: ret = "noall"; break;
case QMessageBox::Abort: ret = "abort"; break;
case QMessageBox::Retry: ret = "retry"; break;
case QMessageBox::Ignore: ret = "ignore"; break;
case QMessageBox::Cancel: ret = "cancel"; break;
case QMessageBox::Discard: ret = "discard"; break;
case QMessageBox::Apply: ret = "apply"; break;
case QMessageBox::Reset: ret = "reset"; break;
}
return ret;
}
void BatchProcessing::plot(const QVariant &graph)
{
ChartGraph *chart = new ChartGraph(this);
+1
View File
@@ -41,6 +41,7 @@ public slots:
QJSValue getInt(const QString &label, int value);
QJSValue getFloat(const QString &label, double value, int decimals);
QJSValue getItem(const QStringList &items, const QString &label, int current);
QJSValue question(const QString &question, const QStringList &buttons, const QString &title = "");
void plot(const QVariant &graph);
};
+69 -12
View File
@@ -4,12 +4,15 @@
#include <QLineSeries>
#include <QBarSeries>
#include <QBarSet>
#include <QBarCategoryAxis>
#include <QScatterSeries>
#include <QMenu>
#include <QMenuBar>
#include <QValueAxis>
#include <QFileDialog>
#include <QSettings>
#include <QToolBar>
#include <QStyle>
class ChartView : public QChartView
{
@@ -22,6 +25,7 @@ public:
protected:
void keyPressEvent(QKeyEvent *event) override
{
if(!chart()->isZoomed())chart()->zoom(0.999999);//workaround so zoomReset() reset scroll
switch(event->key())
{
case Qt::Key_Plus:
@@ -52,6 +56,7 @@ protected:
if(event->button() == Qt::LeftButton)
{
_scroll = true;
if(!chart()->isZoomed())chart()->zoom(0.999999);//workaround so zoomReset() reset scroll
_mousePos = event->position();
}
@@ -72,25 +77,29 @@ protected:
_scroll = false;
QChartView::mouseReleaseEvent(event);
}
void wheelEvent(QWheelEvent *event) override
{
if(event->angleDelta().y() > 0)
chart()->zoomIn();
if(event->angleDelta().y() < 0)
chart()->zoomOut();
}
};
ChartGraph::ChartGraph(QWidget *parent) : QDialog(parent)
ChartGraph::ChartGraph(QWidget *parent) : QMainWindow(parent)
{
setAttribute(Qt::WA_DeleteOnClose);
setModal(false);
_chartView = new ChartView(this);
setLayout(new QVBoxLayout);
layout()->addWidget(_chartView);
setCentralWidget(_chartView);
_chart = new QChart;
_chartView->setChart(_chart);
_chartView->setRenderHint(QPainter::Antialiasing);
resize(1024, 768);
QMenuBar *menuBar = new QMenuBar(this);
menuBar->addAction(tr("Save"), this, &ChartGraph::save);
layout()->setMenuBar(menuBar);
menuBar()->addAction(tr("Save"), this, &ChartGraph::save);
menuBar()->addAction(tr("Reset view"), [this](){ _chart->zoomReset(); });
}
void ChartGraph::plot(const QVariant &graph)
@@ -117,13 +126,29 @@ void ChartGraph::plot(const QVariant &graph)
QBarSeries *barSeries = nullptr;
qreal minX = INFINITY;
qreal maxX = -INFINITY;
qreal minY = INFINITY;
qreal maxY = -INFINITY;
qreal minY2 = INFINITY;
qreal maxY2 = -INFINITY;
QValueAxis *xaxis = new QValueAxis(_chart);
QBarCategoryAxis *barxaxis = new QBarCategoryAxis(_chart);
QValueAxis *yaxis = new QValueAxis(_chart);
QValueAxis *y2axis = new QValueAxis(_chart);
_chart->addAxis(xaxis, Qt::AlignBottom);
_chart->addAxis(yaxis, Qt::AlignLeft);
_chart->addAxis(y2axis, Qt::AlignRight);
_chart->addAxis(barxaxis, Qt::AlignBottom);
y2axis->setGridLinePen(Qt::DashDotLine);
for(auto s : map["series"].toList())
{
QVariantMap serie = s.toMap();
QString type = serie["type"].toString();
bool y2 = serie["y2"].toBool();
if(type == "line" || type == "points" || type == "linePoints" || type.isEmpty())
{
QXYSeries *series = nullptr;
@@ -151,10 +176,20 @@ void ChartGraph::plot(const QVariant &graph)
for(int i = 0; i < y.size(); i++)
{
qreal val = y[i].toDouble();
if(y2)
{
minY2 = std::min(minY2, val);
maxY2 = std::max(maxY2, val);
}
else
{
minY = std::min(minY, val);
maxY = std::max(maxY, val);
}
series->append(i, val);
}
minX = std::min(minX, 0.0);
maxX = std::max(maxX, y.size() - 1.0);
}
else
{
@@ -162,13 +197,25 @@ void ChartGraph::plot(const QVariant &graph)
for(int i = 0; i < size; i++)
{
qreal val = y[i].toDouble();
if(y2)
{
minY2 = std::min(minY2, val);
maxY2 = std::max(maxY2, val);
}
else
{
minY = std::min(minY, val);
maxY = std::max(maxY, val);
}
minX = std::min(minX, x[i].toDouble());
maxX = std::max(maxX, x[i].toDouble());
series->append(x[i].toDouble(), val);
}
}
_chart->addSeries(series);
series->attachAxis(xaxis);
series->attachAxis(y2 ? y2axis : yaxis);
if(serie["bestFit"].toBool())
{
series->setBestFitLineVisible(true);
@@ -193,6 +240,8 @@ void ChartGraph::plot(const QVariant &graph)
{
barSeries = new QBarSeries(_chart);
_chart->addSeries(barSeries);
barSeries->attachAxis(yaxis);
barSeries->attachAxis(barxaxis);
}
QBarSet *set = new QBarSet(serie["title"].toString());
QVariantList y = serie["y"].toList();
@@ -205,6 +254,9 @@ void ChartGraph::plot(const QVariant &graph)
}
barSeries->append(set);
for(int i = barxaxis->count() + 1; i <= y.size(); i++)
barxaxis->append(QString::number(i));
if(serie.contains("color"))
{
QString color = serie["color"].toString();
@@ -213,13 +265,18 @@ void ChartGraph::plot(const QVariant &graph)
}
}
_chart->createDefaultAxes();
QValueAxis *yaxis = qobject_cast<QValueAxis*>(_chart->axes(Qt::Vertical).front());
if(yaxis)
if(barSeries)
{
qreal off = (maxY - minY) * 0.05;
yaxis->setRange(std::min(minY - off, 0.0), maxY + off);
xaxis->setRange(std::min(minX, -0.5), std::max(maxX, barxaxis->count() - 0.5));
minY = std::min(minY, 0.0);
}
else
{
xaxis->setRange(minX, maxX);
}
yaxis->setRange(minY, maxY);
y2axis->setRange(minY2, maxY2);
show();
}
+2 -3
View File
@@ -1,13 +1,13 @@
#ifndef CHARTGRAPH_H
#define CHARTGRAPH_H
#include <QDialog>
#include <QMainWindow>
#include <QJSValue>
#include <QChart>
class ChartView;
class ChartGraph : public QDialog
class ChartGraph : public QMainWindow
{
Q_OBJECT
QChart *_chart;
@@ -17,7 +17,6 @@ public:
void plot(const QVariant &graph);
public slots:
void save();
signals:
};
#endif // CHARTGRAPH_H
+7
View File
@@ -136,6 +136,13 @@ QJSValue ScriptEngine::getItem(const QStringList &items, const QString &label, i
return ret;
}
QJSValue ScriptEngine::question(const QString &question, const QStringList &buttons, const QString &title) const
{
QJSValue ret;
QMetaObject::invokeMethod(_parent, "question", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QJSValue, ret), Q_ARG(QString, question), Q_ARG(QStringList, buttons), Q_ARG(QString, title));
return ret;
}
void ScriptEngine::plot(const QJSValue &graph)
{
QVariant graphV = graph.toVariant(QJSValue::ConvertJSObjects);
+1
View File
@@ -47,6 +47,7 @@ public:
Q_INVOKABLE QJSValue getInt(const QString &label = QString(), int value = 0);
Q_INVOKABLE QJSValue getFloat(const QString &label = QString(), double value = 0, int decimals = 3) const;
Q_INVOKABLE QJSValue getItem(const QStringList &items, const QString &label = "", int current = 0) const;
Q_INVOKABLE QJSValue question(const QString &question, const QStringList &buttons = {"ok"}, const QString &title = "") const;
Q_INVOKABLE void plot(const QJSValue &pointsArray);
Q_INVOKABLE QJSValue openFile(const QString &fileName, const QString &mode = "r");
bool convert(File *file, QString &outpath, const QString &format, const QVariantMap &params, bool async);
-6
View File
@@ -1,11 +1,5 @@
core.log("This script convert any FITS file into XISF with ZSTD compression");
if(files.length == 0)
{
core.log("No input files");
throw "";
}
let compression = {"compressionType": "zstd+sh"};
for(file of files)
+49
View File
@@ -0,0 +1,49 @@
core.log("Measure HFR and eccentricity of stars");
var chart = {
"title": "Measure stars",
"legend": {"visible": true, "align": "left"},
"series": [
{
"title": "HFR",
"type": "bar",
"y":[]
},
{
"title": "Ecc",
"type": "bar",
"y":[]
},
{
"title": "Star count",
"type": "linePoints",
"y":[],
"y2": true,
"bestFit": true
}
]
};
core.setSolverProfile(5);
for(file of files)
{
if(file.suffix() == "fits" || file.suffix() == "fit" || file.suffix() == "xisf")
{
var stars = file.extractStars(true);
var sumHFR = 0;
var ecc = 0;
for(star of stars)
{
sumHFR += star.HFR;
ecc += Math.sqrt(1 - (star.b * star.b) / (star.a * star.a));
}
chart.series[0].y.push(sumHFR / stars.length);
chart.series[1].y.push(ecc / stars.length);
chart.series[2].y.push(stars.length);
core.log(file.fileName() + " Stars:" + stars.length + " HFR: " + sumHFR / stars.length + " Ecc: " + ecc / stars.length);
}
}
core.plot(chart);
+2
View File
@@ -1,3 +1,5 @@
core.log("Script to modify FITS header in FITS and XISF files");
function checkFITS(key)
{
const noEditableKey = ["SIMPLE", "BITPIX", "NAXIS", "NAXIS1", "NAXIS2", "NAXIS3", "EXTEND", "BZERO", "BSCALE"];
+20
View File
@@ -0,0 +1,20 @@
core.log("Plate solve and update solution");
var first = true;
var update = core.question("Update FITS header with solution?", ["yes", "no"], "Update FITS header") == "yes";
var blind = core.question("Do blind solve every image?", ["yes", "no"], "Blind solve?") == "yes";
for(file of files)
{
if(file.suffix() == "fits" || file.suffix() == "fit" || file.suffix() == "xisf")
{
var solution = file.solve(update);
if(first && !blind)
{
core.setStartingSolution(solution);
first = false;
}
core.log(file.fileName() + " " + "RA: " + (solution.ra / 15) + "h DEC: " + solution.dec + "deg");
}
}
+2
View File
@@ -4,5 +4,7 @@
<file>convert to XISF</file>
<file>median</file>
<file>modify FITS header</file>
<file>measure HFR</file>
<file>plate solve</file>
</qresource>
</RCC>
+3 -1
View File
@@ -89,8 +89,8 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
m_bestFit->setToolTip(tr("Set Best Fit zoom level when opening new image."));
m_bestFit->setChecked(BESTFIT);
m_headerHighlight = new QListWidget(this);
m_headerHighlight->setToolTip(tr("List of FITS keywords that will be highlighted in Image info"));
for(auto i = headerHighlight.begin(); i != headerHighlight.end(); i++)
{
QListWidgetItem *item = new QListWidgetItem(m_headerHighlight);
@@ -98,6 +98,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
item->setBackground(i.value());
}
m_keyword = new QLineEdit(this);
m_keyword->setPlaceholderText(tr("FITS keyword"));
QPushButton *color = new QPushButton(this);
QPixmap pix(16, 16);
pix.fill(m_color);
@@ -136,6 +137,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
layout->addRow(m_qualityThumbnail);
layout->addRow(m_useNativeDialog);
layout->addRow(m_bestFit);
layout->addRow(new QLabel(tr("FITS header highlight"), this));
layout->addRow(m_headerHighlight);
layout->addRow(m_keyword, color);
layout->addRow(add, remove);