// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "JFJochPixelRefineTableWindow.h" #include #include #include JFJochPixelRefineTableWindow::JFJochPixelRefineTableWindow(QWidget *parent) : JFJochHelperWindow(parent) { setWindowTitle("PixelRefine reflections"); resize(950, 600); auto central = new QWidget(this); setCentralWidget(central); auto layout = new QVBoxLayout(central); m_summary = new QLabel(tr("No PixelRefine result yet."), this); m_summary->setTextFormat(Qt::RichText); m_summary->setWordWrap(true); layout->addWidget(m_summary); m_table = new QTableView(this); m_model = new QStandardItemModel(this); setupModel(); m_proxy = new QSortFilterProxyModel(this); m_proxy->setSourceModel(m_model); m_proxy->setSortRole(Qt::UserRole); // numeric sort on the underlying values m_table->setModel(m_proxy); m_table->setEditTriggers(QAbstractItemView::NoEditTriggers); m_table->setSortingEnabled(true); m_table->sortByColumn(6, Qt::DescendingOrder); // default: I desc m_table->verticalHeader()->setVisible(false); m_table->horizontalHeader()->setSortIndicatorShown(true); m_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_table->setStyleSheet("background-color: white;"); layout->addWidget(m_table); } void JFJochPixelRefineTableWindow::setupModel() { const QStringList headers = { "h", "k", "l", "d [Å]", "Compl.", "Part.", "I", "Sigma", "Est. I_true", "Ref. I_true" }; m_model->setColumnCount(headers.size()); for (int i = 0; i < headers.size(); ++i) m_model->setHeaderData(i, Qt::Horizontal, headers[i]); } static QStandardItem *numItem(double value, int decimals) { auto *it = new QStandardItem(); const QString text = std::isfinite(value) ? QString::number(value, 'f', decimals) : QStringLiteral("—"); it->setData(text, Qt::DisplayRole); it->setData(value, Qt::UserRole); it->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); return it; } static QStandardItem *intItem(int value) { auto *it = new QStandardItem(); it->setData(static_cast(value), Qt::DisplayRole); it->setData(static_cast(value), Qt::UserRole); it->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); return it; } void JFJochPixelRefineTableWindow::setReport(PixelRefineReport report) { // --- per-image summary: PixelRefine vs the standard pipeline --------------- auto fmt = [](double v, int dec) { return std::isfinite(v) ? QString::number(v, 'f', dec) : QStringLiteral("—"); }; auto pct = [](double v) { return std::isfinite(v) ? QString::number(v * 100.0, 'f', 1) + "%" : QStringLiteral("—"); }; m_summary->setText( tr("PixelRefine: scale G = %1, B = %2 Ų, CC = %3 (%4 refl)" "  |  " "Pipeline: scale G = %5, B = %6 Ų, CC = %7") .arg(fmt(report.pr_G, 4), fmt(report.pr_B, 1), pct(report.pr_cc)) .arg(report.pr_cc_n) .arg(fmt(report.pipe_G, 4), fmt(report.pipe_B, 1), pct(report.pipe_cc))); // --- per-reflection rows --------------------------------------------------- m_model->removeRows(0, m_model->rowCount()); for (const auto &r : report.rows) { QList row; row << intItem(r.h) << intItem(r.k) << intItem(r.l); row << numItem(r.d, 3); row << numItem(r.completeness, 2); row << numItem(r.partiality, 2); row << numItem(r.I, 1); row << numItem(r.sigma, 1); row << numItem(r.I_true_est, 1); row << numItem(r.I_true_ref, 1); m_model->appendRow(row); } }