// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "PowderCalibrationWidget.h" #include #include #include #include "../../common/JFJochMath.h" #include "../image_analysis/geom_refinement/AssignSpotsToRings.h" #include "../image_analysis/geom_refinement/Calibrants.h" PowderCalibrationWidget::PowderCalibrationWidget(QWidget *parent) : QWidget(parent) { auto layout = new QVBoxLayout(this); calibrantCombo = new QComboBox(this); updateCalibrantList(); auto findBeamCenterButton = new QPushButton("Guess detector calibration", this); connect(findBeamCenterButton, &QPushButton::clicked,this, &PowderCalibrationWidget::findBeamCenterClicked); auto optimizeBeamCenterButton = new QPushButton("Refine detector calibration", this); connect(optimizeBeamCenterButton, &QPushButton::clicked,this, &PowderCalibrationWidget::optimizeBeamCenterClicked); auto calibrantRingsButton = new QPushButton("Display calibrant rings", this); connect(calibrantRingsButton, &QPushButton::clicked, this, [this]() { std::vector rings = CalculateXtalRings(GetCalibrant(), 10); QVector q_rings; for (float ring : rings) { q_rings.append(2 * PI / ring); } emit ringsFromCalibration(q_rings); }); auto refine_row = new QGridLayout(); refine_row->setSpacing(12); refine_row->addWidget(new QLabel("Calibrant:"),0,0); refine_row->addWidget(calibrantCombo,0,1); refine_row->addWidget(findBeamCenterButton,1, 0); refine_row->addWidget(optimizeBeamCenterButton,1, 1); refine_row->addWidget(calibrantRingsButton,2, 0); layout->addLayout(refine_row); setLayout(layout); } UnitCell PowderCalibrationWidget::GetCalibrant() const { // The combo lists the shared calibrant table (in its order), then the current sample's own cell. // Ice is skipped: it is a ring list rather than a cell, and this panel works in cells. int idx = calibrantCombo->currentIndex(); for (const auto &c : Calibrants()) { if (!c.cell) continue; if (idx == 0) return *c.cell; idx--; } if (sample_cell) return sample_cell.value(); return *Calibrants().front().cell; } void PowderCalibrationWidget::updateCalibrantList() { calibrantCombo->clear(); for (const auto &c : Calibrants()) if (c.cell) calibrantCombo->addItem(QString::fromStdString(c.name)); if (sample_cell) calibrantCombo->addItem(QString("Current sample (%1 %2 %3 %4 %5 %6)") .arg(QString::number(sample_cell->a, 'f', 1)) .arg(QString::number(sample_cell->b, 'f', 1)) .arg(QString::number(sample_cell->c, 'f', 1)) .arg(QString::number(sample_cell->alpha, 'f', 1)) .arg(QString::number(sample_cell->beta, 'f', 1)) .arg(QString::number(sample_cell->gamma, 'f', 1))); calibrantCombo->setCurrentIndex(0); } void PowderCalibrationWidget::loadImage(std::shared_ptr image) { if (image) sample_cell = image->Dataset().experiment.GetUnitCell(); updateCalibrantList(); } void PowderCalibrationWidget::findBeamCenterClicked() { emit findBeamCenter(GetCalibrant(), true); } void PowderCalibrationWidget::optimizeBeamCenterClicked() { emit findBeamCenter(GetCalibrant(), false); }