// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "JFJochAzIntImage.h" #include #include "../../common/JFJochException.h" JFJochAzIntImage::JFJochAzIntImage(QWidget *parent) : JFJochImage(parent) { } void JFJochAzIntImage::Clear() { W = 0; H = 0; image_fp.clear(); if (scene()) scene()->clear(); } void JFJochAzIntImage::imageLoaded(std::shared_ptr in_image) { if (!in_image) { Clear(); CalcROI(); return; } const auto &profile = in_image->ImageData().az_int_profile; const auto &ds = in_image->Dataset(); int az_bins = ds.azimuthal_bins; int q_bins = ds.q_bins; if (az_bins > 0 && q_bins > 0 && profile.size() == static_cast(az_bins * q_bins) && ds.az_int_bin_to_phi.size() == profile.size() && ds.az_int_bin_to_q.size() == profile.size()) { image = in_image; float local_min = range_min, local_max = range_max; if (auto_range) { local_min = std::numeric_limits::infinity(); local_max = -std::numeric_limits::infinity(); for (float v : profile) { if (std::isfinite(v)) { if (v < local_min) local_min = v; if (v > local_max) local_max = v; } } if (!std::isfinite(local_min) || !std::isfinite(local_max) || local_max <= local_min) { Clear(); return; } } else { if (!(std::isfinite(local_min) && std::isfinite(local_max) && local_max > local_min)) { Clear(); return; } } // Update base class members W = q_bins; H = az_bins; image_fp = profile; // Update foreground/background for color mapping background = local_min; foreground = local_max; emit backgroundChanged(background); emit foregroundChanged(foreground); // Generate pixmap and redraw using base class functionality GeneratePixmap(); Redraw(); CalcROI(); } else { Clear(); } } void JFJochAzIntImage::mouseHover(QMouseEvent* event) { if (!scene() || !image || W == 0 || H == 0) return; QPointF scenePos = mapToScene(event->pos()); int x = static_cast(scenePos.x()); int y = static_cast(scenePos.y()); if (x >= 0 && x < static_cast(W) && y >= 0 && y < static_cast(H)) { size_t idx = y * W + x; QString statusText = QString("Q: %1 Å^-1 phi: %2° value: %3") .arg(QString::number(image->Dataset().az_int_bin_to_q[idx], 'f', 3)) .arg(QString::number(image->Dataset().az_int_bin_to_phi[idx], 'f', 3)) .arg(QString::number(image_fp[idx], 'f', 3)); emit writeStatusBar(statusText, 0); } } void JFJochAzIntImage::mouseDoubleClickEvent(QMouseEvent *event) { if (!scene() || !image || W == 0 || H == 0) return; QPointF scenePos = mapToScene(event->pos()); int x = static_cast(scenePos.x()); int y = static_cast(scenePos.y()); if (x >= 0 && x < static_cast(W) && y >= 0 && y < static_cast(H)) { size_t idx = y * W + x; float q = image->Dataset().az_int_bin_to_q[idx]; float phi = image->Dataset().az_int_bin_to_phi[idx]; auto geom = image->Dataset().experiment.GetDiffractionGeometry(); auto coord = geom.ResPhiToPxl(2 * M_PI / q, phi / 180.0 * M_PI); emit zoomOnBin(QPointF(coord.first, coord.second)); } }