gui shows roi now

This commit is contained in:
2025-06-30 12:03:39 +02:00
parent b775dd0efa
commit cbd0aed8e5
10 changed files with 92 additions and 85 deletions

View File

@ -40,6 +40,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
void SetDataCallBack(bool enable); void SetDataCallBack(bool enable);
void SetBinary(bool enable, int from = 0, int to = 0); void SetBinary(bool enable, int from = 0, int to = 0);
void StartAcquisition(); void StartAcquisition();
void UpdateROI();
public slots: public slots:
void SetPersistency(int val); void SetPersistency(int val);
@ -166,8 +167,8 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
int64_t currentFrame{0}; int64_t currentFrame{0};
mutable std::mutex mPlots; mutable std::mutex mPlots;
int64_t currentAcqIndex{0}; int64_t currentAcqIndex{0};
slsDetectorDefs::ROI rxRoi{}; bool hasRoi{false};
bool isRxRoiDisplayed{false}; bool roiDisplayInitialized{false};
bool isGapPixels{false}; bool isGapPixels{false};
unsigned int nPixelsX{0}; unsigned int nPixelsX{0};
@ -176,6 +177,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
uint32_t gainMask{0}; uint32_t gainMask{0};
int gainOffset{0}; int gainOffset{0};
bool gotthard25; bool gotthard25;
std::vector<slsDetectorDefs::ROI> roi{1};
}; };
} // namespace sls } // namespace sls

View File

@ -5,6 +5,8 @@
#include "SlsQt1DZoomer.h" #include "SlsQt1DZoomer.h"
#include "sls/ansi.h" #include "sls/ansi.h"
#include "sls/sls_detector_defs.h"
#include <array> #include <array>
#include <qwt_plot.h> #include <qwt_plot.h>
#include <qwt_plot_curve.h> #include <qwt_plot_curve.h>
@ -141,8 +143,9 @@ class SlsQt1DPlot : public QwtPlot {
void SetLogX(bool yes = 1); void SetLogX(bool yes = 1);
void SetLogY(bool yes = 1); void SetLogY(bool yes = 1);
void EnableRoiBox(std::array<int, 4> roi); void EnableRoiBoxes(std::vector<slsDetectorDefs::ROI> roi, int ymin,
void DisableRoiBox(); int ymax);
void DisableRoiBoxes();
private: private:
bool gainPlot{false}; bool gainPlot{false};
@ -169,6 +172,7 @@ class SlsQt1DPlot : public QwtPlot {
friend void SlsQtH1D::Attach(SlsQt1DPlot *p); friend void SlsQtH1D::Attach(SlsQt1DPlot *p);
friend void SlsQtH1D::Detach(SlsQt1DPlot *p); friend void SlsQtH1D::Detach(SlsQt1DPlot *p);
std::vector<std::unique_ptr<QwtPlotShapeItem>> roiBoxes{};
QwtPlotShapeItem *roiBox{nullptr}; QwtPlotShapeItem *roiBox{nullptr};
signals: signals:

View File

@ -3,6 +3,8 @@
#pragma once #pragma once
#include "SlsQt2DHist.h" #include "SlsQt2DHist.h"
#include "SlsQt2DZoomer.h" #include "SlsQt2DZoomer.h"
#include "sls/sls_detector_defs.h"
#include <array> #include <array>
#include <qlist.h> #include <qlist.h>
#include <qwt_plot.h> #include <qwt_plot.h>
@ -71,8 +73,8 @@ class SlsQt2DPlot : public QwtPlot {
void SetLogz(bool enable, bool isMin, bool isMax, double min, double max); void SetLogz(bool enable, bool isMin, bool isMax, double min, double max);
void SetZRange(bool isMin, bool isMax, double min, double max); void SetZRange(bool isMin, bool isMax, double min, double max);
void LogZ(bool on = 1); void LogZ(bool on = 1);
void EnableRoiBox(std::array<int, 4> roi); void EnableRoiBoxes(std::vector<slsDetectorDefs::ROI> roi);
void DisableRoiBox(); void DisableRoiBoxes();
public slots: public slots:
void showSpectrogram(bool on); void showSpectrogram(bool on);
@ -101,7 +103,7 @@ class SlsQt2DPlot : public QwtPlot {
QList<double> contourLevelsLog; QList<double> contourLevelsLog;
bool disableZoom{false}; bool disableZoom{false};
int isLog; int isLog;
QwtPlotShapeItem *roiBox{nullptr}; std::vector<std::unique_ptr<QwtPlotShapeItem>> roiBoxes{};
}; };
} // namespace sls } // namespace sls

View File

@ -462,24 +462,26 @@ void SlsQt1DPlot::SetLog(int axisId, bool yes) {
Update(); Update();
} }
void SlsQt1DPlot::EnableRoiBox(std::array<int, 4> roi) { void SlsQt1DPlot::EnableRoiBoxes(std::vector<slsDetectorDefs::ROI> roi,
if (roiBox == nullptr) { int ymin, int ymax) {
roiBox = new QwtPlotShapeItem(); roiBoxes.clear();
roiBox->attach(this); for (auto &r : roi) {
roiBox->setPen(QColor(Qt::yellow), 2.0, Qt::SolidLine); auto box = std::make_unique<QwtPlotShapeItem>();
box->setPen(QColor(Qt::yellow), 2.0, Qt::SolidLine);
// TopLeft - BottomRight (max points are +1 on graph)
QRectF myRect(QPointF(r.xmin, ymin), QPointF(r.xmax - 1, ymax - 1));
box->setRect(myRect);
box->attach(this);
roiBoxes.push_back(std::move(box));
} }
// TopLeft - BottomRight (max points are +1 on graph)
QRect myRect(QPoint(roi[0], roi[2]), QPoint(roi[1] - 1, roi[3] - 1));
roiBox->setRect(QRectF(myRect));
replot(); replot();
} }
void SlsQt1DPlot::DisableRoiBox() { void SlsQt1DPlot::DisableRoiBoxes() {
if (roiBox != nullptr) { for (auto &r : roiBoxes) {
roiBox->detach(); r->detach();
replot();
} }
replot();
} }
void SlsQt1DPlot::SetZoomX(const QRectF &rect) { void SlsQt1DPlot::SetZoomX(const QRectF &rect) {

View File

@ -350,25 +350,25 @@ void SlsQt2DPlot::showSpectrogram(bool on) {
Update(); Update();
} }
void SlsQt2DPlot::EnableRoiBox(std::array<int, 4> roi) { void SlsQt2DPlot::EnableRoiBoxes(std::vector<slsDetectorDefs::ROI> roi) {
if (roiBox == nullptr) { roiBoxes.clear();
roiBox = new QwtPlotShapeItem(); for (auto &r : roi) {
auto box = std::make_unique<QwtPlotShapeItem>();
box->setPen(QColor(Qt::yellow), 2.0, Qt::SolidLine);
// TopLeft - BottomRight (max points are +1 on graph)
QRectF myRect(QPointF(r.xmin, r.ymin), QPointF(r.xmax - 1, r.ymax - 1));
box->setRect(myRect);
box->attach(this);
roiBoxes.push_back(std::move(box));
} }
roiBox->setPen(QColor(Qt::yellow), 2.0, Qt::SolidLine);
// TopLeft - BottomRight (max points are +1 on graph)
QRect myRect(QPoint(roi[0], roi[2]), QPoint(roi[1] - 1, roi[3] - 1));
roiBox->setRect(QRectF(myRect));
roiBox->attach(this);
replot(); replot();
} }
void SlsQt2DPlot::DisableRoiBox() { void SlsQt2DPlot::DisableRoiBoxes() {
if (roiBox != nullptr) { for (auto &r : roiBoxes) {
roiBox->detach(); r->detach();
replot();
} }
replot();
} }
} // namespace sls } // namespace sls

View File

@ -539,6 +539,7 @@ void qDetectorMain::EnableTabs(bool enable) {
tabDeveloper->Refresh(); tabDeveloper->Refresh();
tabPlot->Refresh(); tabPlot->Refresh();
plot->UpdateROI();
plot->StartAcquisition(); plot->StartAcquisition();
} else { // to enable scan box } else { // to enable scan box
tabPlot->Refresh(); tabPlot->Refresh();

View File

@ -608,7 +608,6 @@ void qDrawPlot::StartAcquisition() {
currentFrame = 0; currentFrame = 0;
boxPlot->setTitle("Old Plot"); boxPlot->setTitle("Old Plot");
det->clearAcquiringFlag(); // (from previous exit) or if running det->clearAcquiringFlag(); // (from previous exit) or if running
isRxRoiDisplayed = false;
// ensure data streaming in receiver (if plot enabled) // ensure data streaming in receiver (if plot enabled)
if (isPlot) { if (isPlot) {
@ -632,6 +631,33 @@ void qDrawPlot::StartAcquisition() {
LOG(logDEBUG) << "End of Starting Acquisition in qDrawPlot"; LOG(logDEBUG) << "End of Starting Acquisition in qDrawPlot";
} }
void qDrawPlot::UpdateROI() {
try {
std::lock_guard<std::mutex> lock(mPlots);
roi = det->getRxROI();
roiDisplayInitialized = false;
// roi enabled
if (roi.size() > 1 || !roi[0].completeRoi()) {
hasRoi = true;
// update gap pixels (gap pixels only for 2d)
if (isGapPixels) {
for (auto &r : roi) {
r.xmin += ((r.xmin / 1024) * 6 + (r.xmin / 256) * 2);
r.xmax += ((r.xmax / 1024) * 6 + (r.xmax / 256) * 2);
r.ymin += ((r.ymin / 512) * 34 + (r.ymin / 256) * 2);
r.ymax += ((r.ymax / 512) * 34 + (r.ymax / 256) * 2);
}
LOG(logINFO)
<< "Roi recalculated with gap pixels: " << ToString(roi);
}
} else {
hasRoi = false;
}
LOG(logDEBUG) << "Roi: " << ToString(roi);
}
CATCH_DISPLAY("Could not get reciver ROI.", "qDrawPlot::UpdateRoi")
}
void qDrawPlot::AcquireThread() { void qDrawPlot::AcquireThread() {
LOG(logDEBUG) << "Acquire Thread"; LOG(logDEBUG) << "Acquire Thread";
std::string mess; std::string mess;
@ -709,7 +735,6 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
<< " \t dynamic range: " << data->dynamicRange << std::endl << " \t dynamic range: " << data->dynamicRange << std::endl
<< " \t file index: " << data->fileIndex << std::endl << " \t file index: " << data->fileIndex << std::endl
<< " \t complete image: " << data->completeImage << std::endl << " \t complete image: " << data->completeImage << std::endl
<< " \t rx Roi: " << ToString(data->rxRoi) << std::endl
<< " ]"; << " ]";
progress = data->progressIndex; progress = data->progressIndex;
@ -717,22 +742,6 @@ void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
currentFrame = frameIndex; currentFrame = frameIndex;
LOG(logDEBUG) << "[ Progress:" << progress << "%, Frame:" << currentFrame LOG(logDEBUG) << "[ Progress:" << progress << "%, Frame:" << currentFrame
<< " ]"; << " ]";
if (!isRxRoiDisplayed) {
rxRoi.xmin = data->rxRoi[0];
rxRoi.xmax = data->rxRoi[1];
rxRoi.ymin = data->rxRoi[2];
rxRoi.ymax = data->rxRoi[3];
// only for 2d anyway
if (isGapPixels) {
rxRoi.xmin += ((rxRoi.xmin / 1024) * 6 + (rxRoi.xmin / 256) * 2);
rxRoi.xmax += ((rxRoi.xmax / 1024) * 6 + (rxRoi.xmax / 256) * 2);
rxRoi.ymin += ((rxRoi.ymin / 512) * 34 + (rxRoi.ymin / 256) * 2);
rxRoi.ymax += ((rxRoi.ymax / 512) * 34 + (rxRoi.ymax / 256) * 2);
LOG(logINFO) << "Rx_roi recalculated with gap pixels: "
<< ToString(rxRoi);
}
LOG(logDEBUG) << "Rx_roi: " << ToString(rxRoi);
}
// 1d check if npixelX has changed (m3 for different counters enabled) // 1d check if npixelX has changed (m3 for different counters enabled)
if (is1d && static_cast<int>(nPixelsX) != data->nx) { if (is1d && static_cast<int>(nPixelsX) != data->nx) {
@ -971,30 +980,27 @@ void qDrawPlot::Update1dPlot() {
xyRangeChanged = false; xyRangeChanged = false;
} }
plot1d->DisableZoom(disableZoom); plot1d->DisableZoom(disableZoom);
if (!isRxRoiDisplayed) { if (!roiDisplayInitialized) {
isRxRoiDisplayed = true; roiDisplayInitialized = true;
if (rxRoi.completeRoi()) { if (!hasRoi) {
plot1d->DisableRoiBox(); plot1d->DisableRoiBoxes();
if (isGainDataExtracted) { if (isGainDataExtracted) {
gainplot1d->DisableRoiBox(); gainplot1d->DisableRoiBoxes();
} }
lblRxRoiEnabled->hide(); lblRxRoiEnabled->hide();
} else { } else {
plot1d->EnableRoiBox(std::array<int, 4>{ plot1d->EnableRoiBoxes(roi, (int)plot1d->GetYMinimum(),
rxRoi.xmin, rxRoi.xmax, (int)plot1d->GetYMinimum(), (int)plot1d->GetYMaximum());
(int)plot1d->GetYMaximum()});
if (isGainDataExtracted) { if (isGainDataExtracted) {
gainplot1d->EnableRoiBox( gainplot1d->EnableRoiBoxes(roi, 0, 3);
std::array<int, 4>{rxRoi.xmin, rxRoi.xmax, 0, 3});
} }
lblRxRoiEnabled->show(); lblRxRoiEnabled->show();
} }
} }
// ymin and ymax could change (so replot roi every time) // ymin and ymax could change (so replot roi every time)
if (!rxRoi.completeRoi()) { if (hasRoi) {
plot1d->EnableRoiBox(std::array<int, 4>{rxRoi.xmin, rxRoi.xmax, plot1d->EnableRoiBoxes(roi, (int)plot1d->GetYMinimum(),
(int)plot1d->GetYMinimum(), (int)plot1d->GetYMaximum());
(int)plot1d->GetYMaximum()});
} }
} }
@ -1025,18 +1031,18 @@ void qDrawPlot::Update2dPlot() {
} }
plot2d->DisableZoom(disableZoom); plot2d->DisableZoom(disableZoom);
plot2d->SetZRange(isZRange[0], isZRange[1], zRange[0], zRange[1]); plot2d->SetZRange(isZRange[0], isZRange[1], zRange[0], zRange[1]);
if (!isRxRoiDisplayed) { if (!roiDisplayInitialized) {
isRxRoiDisplayed = true; roiDisplayInitialized = true;
if (rxRoi.completeRoi()) { if (!hasRoi) {
plot2d->DisableRoiBox(); plot2d->DisableRoiBoxes();
if (isGainDataExtracted) { if (isGainDataExtracted) {
gainplot2d->DisableRoiBox(); gainplot2d->DisableRoiBoxes();
} }
lblRxRoiEnabled->hide(); lblRxRoiEnabled->hide();
} else { } else {
plot2d->EnableRoiBox(rxRoi.getIntArray()); plot2d->EnableRoiBoxes(roi);
if (isGainDataExtracted) { if (isGainDataExtracted) {
gainplot2d->EnableRoiBox(rxRoi.getIntArray()); gainplot2d->EnableRoiBoxes(roi);
} }
lblRxRoiEnabled->show(); lblRxRoiEnabled->show();
} }

View File

@ -19,14 +19,6 @@ class detectorData {
databytes(databytes), dynamicRange(dynamicRange), databytes(databytes), dynamicRange(dynamicRange),
completeImage(completeImage){}; completeImage(completeImage){};
detectorData(double progressIndex, std::string fileName, int nx, int ny,
char *data, int databytes, int dynamicRange,
uint64_t fileIndex, bool completeImage,
std::array<int, 4> rxRoi)
: progressIndex(progressIndex), fileName(fileName),
fileIndex(fileIndex), nx(nx), ny(ny), data(data),
databytes(databytes), dynamicRange(dynamicRange),
completeImage(completeImage), rxRoi(rxRoi){};
/** /**
* data has to be deleted by caller * data has to be deleted by caller
*/ */
@ -62,7 +54,6 @@ class detectorData {
int databytes; int databytes;
int dynamicRange; int dynamicRange;
bool completeImage; bool completeImage;
std::array<int, 4> rxRoi{{-1, -1, -1, -1}};
}; };
} // namespace sls } // namespace sls

View File

@ -535,7 +535,6 @@ void DetectorImpl::readFrameFromReceiver() {
bool quadEnable = false; bool quadEnable = false;
// to flip image // to flip image
bool eiger = false; bool eiger = false;
std::array<int, 4> rxRoi{}; // TODO: get roi from json header
std::vector<bool> runningList(zmqSocket.size()); std::vector<bool> runningList(zmqSocket.size());
std::vector<bool> connectList(zmqSocket.size()); std::vector<bool> connectList(zmqSocket.size());
@ -732,7 +731,7 @@ void DetectorImpl::readFrameFromReceiver() {
thisData = new detectorData(currentProgress, currentFileName, thisData = new detectorData(currentProgress, currentFileName,
nDetActualPixelsX, nDetActualPixelsY, nDetActualPixelsX, nDetActualPixelsY,
callbackImage, imagesize, dynamicRange, callbackImage, imagesize, dynamicRange,
currentFileIndex, completeImage, rxRoi); currentFileIndex, completeImage);
try { try {
dataReady( dataReady(
thisData, currentFrameIndex, thisData, currentFrameIndex,

View File

@ -1843,7 +1843,7 @@ int ClientInterface::get_roi_metadata(Interface &socket) {
if (detType == CHIPTESTBOARD || detType == XILINX_CHIPTESTBOARD) if (detType == CHIPTESTBOARD || detType == XILINX_CHIPTESTBOARD)
functionNotImplemented(); functionNotImplemented();
auto retvals = impl()->getMultiROIMetadata(); auto retvals = impl()->getMultiROIMetadata();
LOG(logINFORED) << "Receiver ROI metadata retval:" << ToString(retvals); LOG(logDEBUG1) << "Receiver ROI metadata retval:" << ToString(retvals);
auto size = static_cast<int>(retvals.size()); auto size = static_cast<int>(retvals.size());
socket.Send(size); socket.Send(size);
if (size > 0) if (size > 0)