mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-21 11:20:04 +02:00
1203 lines
40 KiB
C++
1203 lines
40 KiB
C++
// SPDX-License-Identifier: LGPL-3.0-or-other
|
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
|
#include "qDrawPlot.h"
|
|
#include "SlsQt1DPlot.h"
|
|
#include "SlsQt2DPlot.h"
|
|
#include "qCloneWidget.h"
|
|
#include "sls/detectorData.h"
|
|
|
|
#include "sls/ToString.h"
|
|
#include "sls/detectorData.h"
|
|
|
|
#include <QFileDialog>
|
|
#include <QPainter>
|
|
#include <QResizeEvent>
|
|
#include <QtConcurrentRun>
|
|
|
|
qDrawPlot::qDrawPlot(QWidget *parent, sls::Detector *detector)
|
|
: QWidget(parent), det(detector) {
|
|
setupUi(this);
|
|
SetupWidgetWindow();
|
|
LOG(logINFO) << "Plots ready";
|
|
}
|
|
|
|
qDrawPlot::~qDrawPlot() {
|
|
DetachHists();
|
|
for (QVector<SlsQtH1D *>::iterator h = hists1d.begin(); h != hists1d.end();
|
|
++h) {
|
|
delete *h;
|
|
}
|
|
|
|
hists1d.clear();
|
|
delete[] datax1d;
|
|
for (auto &it : datay1d)
|
|
delete[] it;
|
|
|
|
delete[] gainDatay1d;
|
|
delete[] data2d;
|
|
delete[] gainData;
|
|
delete plot1d;
|
|
delete gainhist1d;
|
|
delete gainplot1d;
|
|
delete plot2d;
|
|
delete gainplot2d;
|
|
delete[] pedestalVals;
|
|
delete[] tempPedestalVals;
|
|
}
|
|
|
|
void qDrawPlot::SetupWidgetWindow() {
|
|
detType = det->getDetectorType().squash();
|
|
switch (detType) {
|
|
case slsDetectorDefs::JUNGFRAU:
|
|
pixelMask = ((1 << 14) - 1);
|
|
gainMask = (3 << 14);
|
|
gainOffset = 14;
|
|
LOG(logINFO) << "Pixel Mask: " << std::hex << pixelMask
|
|
<< ", Gain Mask:" << gainMask
|
|
<< ", Gain Offset:" << std::dec << gainOffset;
|
|
break;
|
|
case slsDetectorDefs::GOTTHARD2:
|
|
pixelMask = ((1 << 12) - 1);
|
|
gainMask = (3 << 12);
|
|
gainOffset = 12;
|
|
LOG(logINFO) << "Pixel Mask: " << std::hex << pixelMask
|
|
<< ", Gain Mask:" << gainMask
|
|
<< ", Gain Offset:" << std::dec << gainOffset;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
// save
|
|
try {
|
|
std::string temp = det->getFilePath().squash("/tmp/");
|
|
fileSavePath = QString(temp.c_str());
|
|
temp = det->getFileNamePrefix().squash("xxx");
|
|
fileSaveName = QString(temp.c_str());
|
|
} catch (const std::exception &e) {
|
|
qDefs::ExceptionMessage("Could not get file path or file name.",
|
|
e.what(), "qDrawPlot::SetupWidgetWindow");
|
|
fileSavePath = "/tmp";
|
|
fileSaveName = "Image";
|
|
}
|
|
|
|
gotthard25 = ((detType == slsDetectorDefs::GOTTHARD2 ||
|
|
detType == slsDetectorDefs::GOTTHARD) &&
|
|
det->size() == 2);
|
|
|
|
SetupPlots();
|
|
SetDataCallBack(true);
|
|
det->registerAcquisitionFinishedCallback(&(GetAcquisitionFinishedCallBack),
|
|
this);
|
|
Initialization();
|
|
}
|
|
|
|
void qDrawPlot::Initialization() {
|
|
connect(this, SIGNAL(UpdateSignal()), this, SLOT(UpdatePlot()));
|
|
}
|
|
|
|
void qDrawPlot::SetupPlots() {
|
|
setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
|
|
// default image size
|
|
slsDetectorDefs::xy res = det->getDetectorSize();
|
|
nPixelsX = res.x;
|
|
nPixelsY = res.y;
|
|
LOG(logINFO) << "nPixelsX:" << nPixelsX;
|
|
LOG(logINFO) << "nPixelsY:" << nPixelsY;
|
|
|
|
boxPlot->setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
widgetStatistics->hide();
|
|
lblCompleteImage->hide();
|
|
lblInCompleteImage->hide();
|
|
|
|
// setup 1d data
|
|
|
|
delete[] datax1d;
|
|
datax1d = new double[nPixelsX];
|
|
if (datay1d.size()) {
|
|
for (auto &it : datay1d) {
|
|
delete[] it;
|
|
}
|
|
datay1d.clear();
|
|
}
|
|
datay1d.push_back(new double[nPixelsX]);
|
|
// default display data
|
|
for (unsigned int px = 0; px < nPixelsX; ++px) {
|
|
datax1d[px] = px;
|
|
datay1d[0][px] = 0;
|
|
}
|
|
// add a hist
|
|
SlsQtH1D *h = new SlsQtH1D("", nPixelsX, datax1d, datay1d[0]);
|
|
h->SetLineColor(0);
|
|
h->setStyleLinesorDots(isLines);
|
|
h->setSymbolMarkers(isMarkers);
|
|
hists1d.append(h);
|
|
// setup 1d plot
|
|
plot1d = new SlsQt1DPlot(boxPlot);
|
|
plot1d->setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
plot1d->SetTitleFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
plot1d->SetXFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
plot1d->SetYFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
plot1d->SetTitle("");
|
|
plot1d->SetXTitle(xTitle1d);
|
|
plot1d->SetYTitle(yTitle1d);
|
|
h->Attach(plot1d);
|
|
plot1d->hide();
|
|
|
|
delete[] gainDatay1d;
|
|
gainDatay1d = new double[nPixelsX];
|
|
// default display data
|
|
for (unsigned int px = 0; px < nPixelsX; ++px) {
|
|
gainDatay1d[px] = 0;
|
|
}
|
|
// set gain hist
|
|
gainhist1d = new SlsQtH1D("", nPixelsX, datax1d, gainDatay1d);
|
|
gainhist1d->SetLineColor(0);
|
|
gainhist1d->setStyleLinesorDots(isLines);
|
|
gainhist1d->setSymbolMarkers(isMarkers);
|
|
// setup 1d gain plot
|
|
gainplot1d = new SlsQt1DPlot(boxPlot);
|
|
gainplot1d->SetTitleFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
gainplot1d->SetYFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
gainplot1d->SetTitle("");
|
|
gainplot1d->SetYTitle("Gain");
|
|
// set ticks to just 3
|
|
QList<double> majorTicks({0, 1, 2, 3});
|
|
QwtScaleDiv div(0, 3, QList<double>(), QList<double>(), majorTicks);
|
|
gainplot1d->setAxisScaleDiv(QwtPlot::yLeft, div);
|
|
// gainplot1d->axisScaleDraw(QwtPlot::xBottom)->enableComponent(QwtScaleDraw::Ticks,
|
|
// false);
|
|
// gainplot1d->axisScaleDraw(QwtPlot::yLeft)->enableComponent(QwtScaleDraw::Labels,
|
|
// false);
|
|
gainhist1d->setItemAttribute(QwtPlotItem::Legend, false);
|
|
gainhist1d->Attach(gainplot1d);
|
|
gainplot1d->hide();
|
|
|
|
// setup 2d data
|
|
|
|
delete[] data2d;
|
|
data2d = new double[nPixelsY * nPixelsX];
|
|
for (unsigned int px = 0; px < nPixelsX; ++px)
|
|
for (unsigned int py = 0; py < nPixelsY; ++py)
|
|
data2d[py * nPixelsX + px] =
|
|
sqrt(pow(0 + 1, 2) * pow(double(px) - nPixelsX / 2, 2) /
|
|
pow(nPixelsX / 2, 2) / pow(1 + 1, 2) +
|
|
pow(double(py) - nPixelsY / 2, 2) / pow(nPixelsY / 2, 2)) /
|
|
sqrt(2);
|
|
|
|
delete[] gainData;
|
|
gainData = new double[nPixelsY * nPixelsX];
|
|
for (unsigned int px = 0; px < nPixelsX; ++px)
|
|
for (unsigned int py = 0; py < nPixelsY; ++py)
|
|
gainData[py * nPixelsX + px] =
|
|
sqrt(pow(0 + 1, 2) * pow(double(px) - nPixelsX / 2, 2) /
|
|
pow(nPixelsX / 2, 2) / pow(1 + 1, 2) +
|
|
pow(double(py) - nPixelsY / 2, 2) / pow(nPixelsY / 2, 2)) /
|
|
sqrt(2);
|
|
// setup 2d plot
|
|
plot2d = new SlsQt2DPlot(boxPlot);
|
|
plot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5,
|
|
nPixelsY - 0.5, data2d);
|
|
plot2d->setFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
plot2d->SetTitleFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
plot2d->SetXFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
plot2d->SetYFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
plot2d->SetZFont(QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
plot2d->setTitle("");
|
|
plot2d->SetXTitle(xTitle2d);
|
|
plot2d->SetYTitle(yTitle2d);
|
|
plot2d->SetZTitle(zTitle2d);
|
|
|
|
gainplot2d = new SlsQt2DPlot(boxPlot);
|
|
gainplot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5,
|
|
nPixelsY - 0.5, gainData);
|
|
gainplot2d->SetTitleFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
gainplot2d->setTitle("Gain");
|
|
gainplot2d->SetZTitle("");
|
|
gainplot2d->enableAxis(QwtPlot::yLeft, false);
|
|
// gainplot2d->enableAxis(1, false);
|
|
gainplot2d->enableAxis(QwtPlot::xBottom, false);
|
|
// set ticks to just 3
|
|
gainplot2d->setAxisScaleDiv(QwtPlot::yRight, div);
|
|
gainplot2d->hide();
|
|
|
|
// layout of plots
|
|
int ratio = qDefs::DATA_GAIN_PLOT_RATIO - 1;
|
|
plotLayout->addWidget(plot1d, 0, 0, ratio, ratio);
|
|
plotLayout->addWidget(plot2d, 0, 0, ratio, ratio);
|
|
plotLayout->addWidget(gainplot1d, ratio, 0, 1, ratio, Qt::AlignTop);
|
|
plotLayout->addWidget(gainplot2d, 0, ratio, 1, 1,
|
|
Qt::AlignRight | Qt::AlignTop);
|
|
}
|
|
|
|
void qDrawPlot::resizeEvent(QResizeEvent *event) {
|
|
if (gainplot2d->isVisible()) {
|
|
gainplot2d->setFixedWidth(plot2d->width() /
|
|
qDefs::DATA_GAIN_PLOT_RATIO);
|
|
gainplot2d->setFixedHeight(plot2d->height() /
|
|
qDefs::DATA_GAIN_PLOT_RATIO);
|
|
}
|
|
if (gainplot1d->isVisible()) {
|
|
gainplot1d->setFixedWidth(plot1d->width());
|
|
gainplot1d->setFixedHeight(plot1d->height() /
|
|
qDefs::DATA_GAIN_PLOT_RATIO);
|
|
}
|
|
event->accept();
|
|
}
|
|
|
|
bool qDrawPlot::GetIsRunning() { return isRunning; }
|
|
|
|
void qDrawPlot::SetRunning(bool enable) { isRunning = enable; }
|
|
|
|
double qDrawPlot::GetProgress() { return progress; }
|
|
|
|
int64_t qDrawPlot::GetCurrentFrameIndex() { return currentFrame; }
|
|
|
|
void qDrawPlot::Select1dPlot(bool enable) {
|
|
if (enable) {
|
|
is1d = true;
|
|
// DetachHists(); it clears the last measurement
|
|
plot1d->SetXTitle(xTitle1d);
|
|
plot1d->SetYTitle(yTitle1d);
|
|
plot1d->show();
|
|
plot2d->hide();
|
|
} else {
|
|
is1d = false;
|
|
plot2d->SetTitle("");
|
|
plot2d->SetXTitle(xTitle2d);
|
|
plot2d->SetYTitle(yTitle2d);
|
|
plot2d->SetZTitle(zTitle2d);
|
|
plot1d->hide();
|
|
plot2d->show();
|
|
}
|
|
}
|
|
|
|
void qDrawPlot::SetPlotTitlePrefix(QString title) {
|
|
LOG(logINFO) << "Setting Title to " << title.toAscii().constData();
|
|
plotTitlePrefix = title;
|
|
}
|
|
|
|
void qDrawPlot::SetXAxisTitle(QString title) {
|
|
LOG(logINFO) << "Setting X Axis Title to " << title.toAscii().constData();
|
|
if (is1d) {
|
|
xTitle1d = title;
|
|
} else {
|
|
xTitle2d = title;
|
|
}
|
|
}
|
|
|
|
void qDrawPlot::SetYAxisTitle(QString title) {
|
|
LOG(logINFO) << "Setting Y Axis Title to " << title.toAscii().constData();
|
|
if (is1d) {
|
|
yTitle1d = title;
|
|
} else {
|
|
yTitle2d = title;
|
|
}
|
|
}
|
|
|
|
void qDrawPlot::SetZAxisTitle(QString title) {
|
|
LOG(logINFO) << "Setting Z Axis Title to " << title.toAscii().constData();
|
|
zTitle2d = title;
|
|
}
|
|
|
|
void qDrawPlot::SetXYRangeChanged(bool disable, double *xy, bool *isXY) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logINFO) << "XY Range has changed";
|
|
xyRangeChanged = true;
|
|
std::copy(xy, xy + 4, xyRange);
|
|
std::copy(isXY, isXY + 4, isXYRange);
|
|
|
|
LOG(logDEBUG) << "Setting Disable zoom to " << std::boolalpha << disable
|
|
<< std::noboolalpha;
|
|
disableZoom = disable;
|
|
}
|
|
|
|
void qDrawPlot::SetZRange(double *z, bool *isZ) {
|
|
std::copy(z, z + 2, zRange);
|
|
std::copy(isZ, isZ + 2, isZRange);
|
|
}
|
|
|
|
double qDrawPlot::GetXMinimum() {
|
|
if (is1d)
|
|
return plot1d->GetXMinimum();
|
|
else
|
|
return plot2d->GetXMinimum();
|
|
}
|
|
|
|
double qDrawPlot::GetXMaximum() {
|
|
if (is1d)
|
|
return plot1d->GetXMaximum();
|
|
else
|
|
return plot2d->GetXMaximum();
|
|
}
|
|
|
|
double qDrawPlot::GetYMinimum() {
|
|
if (is1d)
|
|
return plot1d->GetYMinimum();
|
|
else
|
|
return plot2d->GetYMinimum();
|
|
}
|
|
|
|
double qDrawPlot::GetYMaximum() {
|
|
if (is1d)
|
|
return plot1d->GetYMaximum();
|
|
else
|
|
return plot2d->GetYMaximum();
|
|
}
|
|
|
|
void qDrawPlot::SetDataCallBack(bool enable) {
|
|
LOG(logINFO) << "Setting data call back to " << std::boolalpha << enable
|
|
<< std::noboolalpha;
|
|
try {
|
|
if (enable) {
|
|
isPlot = true;
|
|
det->registerDataCallback(&(GetDataCallBack), this);
|
|
det->setRxZmqDataStream(true);
|
|
} else {
|
|
isPlot = false;
|
|
det->registerDataCallback(nullptr, this);
|
|
det->setRxZmqDataStream(false);
|
|
}
|
|
}
|
|
CATCH_DISPLAY("Could not get set rxr data streaming enable.",
|
|
"qDrawPlot::SetDataCallBack")
|
|
}
|
|
|
|
void qDrawPlot::SetBinary(bool enable, int from, int to) {
|
|
LOG(logINFO) << (enable ? "Enabling" : "Disabling")
|
|
<< " Binary output from " << from << " to " << to;
|
|
binaryFrom = from;
|
|
binaryTo = to;
|
|
isBinary = enable;
|
|
}
|
|
|
|
void qDrawPlot::SetPersistency(int val) {
|
|
LOG(logINFO) << "Setting Persistency to " << val;
|
|
persistency = val;
|
|
}
|
|
|
|
void qDrawPlot::SetLines(bool enable) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logINFO) << "Setting Lines to " << std::boolalpha << enable
|
|
<< std::noboolalpha;
|
|
isLines = enable;
|
|
for (int i = 0; i < nHists; ++i) {
|
|
SlsQtH1D *h = hists1d.at(i);
|
|
h->setStyleLinesorDots(isLines);
|
|
}
|
|
}
|
|
|
|
void qDrawPlot::SetMarkers(bool enable) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logINFO) << "Setting Markers to " << std::boolalpha << enable
|
|
<< std::noboolalpha;
|
|
isMarkers = enable;
|
|
for (int i = 0; i < nHists; ++i) {
|
|
SlsQtH1D *h = hists1d.at(i);
|
|
h->setSymbolMarkers(isMarkers);
|
|
}
|
|
}
|
|
|
|
void qDrawPlot::Set1dLogY(bool enable) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logINFO) << "Setting Log Y to " << std::boolalpha << enable
|
|
<< std::noboolalpha;
|
|
plot1d->SetLogY(enable);
|
|
}
|
|
|
|
void qDrawPlot::SetInterpolate(bool enable) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logINFO) << "Setting Interpolate to " << std::boolalpha << enable
|
|
<< std::noboolalpha;
|
|
plot2d->SetInterpolate(enable);
|
|
}
|
|
|
|
void qDrawPlot::SetContour(bool enable) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logINFO) << "Setting Countour to " << std::boolalpha << enable
|
|
<< std::noboolalpha;
|
|
plot2d->SetContour(enable);
|
|
}
|
|
|
|
void qDrawPlot::SetLogz(bool enable) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logINFO) << "Setting Log Z to " << std::boolalpha << enable
|
|
<< std::noboolalpha;
|
|
plot2d->SetLogz(enable, isZRange[0], isZRange[1], zRange[0], zRange[1]);
|
|
}
|
|
|
|
void qDrawPlot::SetPedestal(bool enable) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logINFO) << (enable ? "Enabling" : "Disabling") << " Pedestal";
|
|
isPedestal = enable;
|
|
resetPedestal = true;
|
|
}
|
|
|
|
void qDrawPlot::RecalculatePedestal() {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logDEBUG) << "Recalculating Pedestal";
|
|
resetPedestal = true;
|
|
}
|
|
|
|
void qDrawPlot::SetAccumulate(bool enable) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logINFO) << (enable ? "Enabling" : "Disabling") << " Accumulation";
|
|
isAccumulate = enable;
|
|
resetAccumulate = true;
|
|
}
|
|
|
|
void qDrawPlot::ResetAccumulate() {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logDEBUG) << "Resetting Accumulation";
|
|
resetAccumulate = true;
|
|
}
|
|
|
|
void qDrawPlot::DisplayStatistics(bool enable) {
|
|
LOG(logINFO) << (enable ? "Enabling" : "Disabling")
|
|
<< " Statistics Display";
|
|
displayStatistics = enable;
|
|
}
|
|
|
|
void qDrawPlot::SetNumDiscardBits(int value) {
|
|
LOG(logINFO) << "Setting number of bits to discard: " << value;
|
|
numDiscardBits = value;
|
|
}
|
|
|
|
void qDrawPlot::EnableGainPlot(bool enable) {
|
|
LOG(logINFO) << (enable ? "Enabling" : "Disabling") << " Gain Plot";
|
|
hasGainData = enable;
|
|
}
|
|
|
|
void qDrawPlot::SetSaveFileName(QString val) {
|
|
LOG(logDEBUG) << "Setting Clone/Save File Name to "
|
|
<< val.toAscii().constData();
|
|
fileSaveName = val;
|
|
}
|
|
|
|
void qDrawPlot::ClonePlot() {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
|
|
SlsQt1DPlot *cloneplot1D = nullptr;
|
|
SlsQt2DPlot *cloneplot2D = nullptr;
|
|
SlsQt1DPlot *clonegainplot1D = nullptr;
|
|
SlsQt2DPlot *clonegainplot2D = nullptr;
|
|
|
|
if (is1d) {
|
|
LOG(logDEBUG) << "Cloning 1D Image";
|
|
cloneplot1D = new SlsQt1DPlot();
|
|
cloneplot1D->setFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
cloneplot1D->SetTitleFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
cloneplot1D->SetXFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
cloneplot1D->SetYFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
cloneplot1D->SetTitle(plot1d->title().text());
|
|
cloneplot1D->SetXTitle(xTitle1d);
|
|
cloneplot1D->SetYTitle(yTitle1d);
|
|
QVector<SlsQtH1D *> cloneplotHists1D;
|
|
for (int iHist = 0; iHist < nHists; ++iHist) {
|
|
SlsQtH1D *h = new SlsQtH1D("", nPixelsX, datax1d, datay1d[iHist]);
|
|
h->SetLineColor(iHist);
|
|
h->setStyleLinesorDots(isLines);
|
|
h->setSymbolMarkers(isMarkers);
|
|
cloneplotHists1D.append(h);
|
|
h->Attach(cloneplot1D);
|
|
}
|
|
if (isGainDataExtracted) {
|
|
SlsQtH1D *h = new SlsQtH1D("", nPixelsX, datax1d, gainDatay1d);
|
|
h->SetLineColor(0);
|
|
h->setStyleLinesorDots(isLines);
|
|
h->setSymbolMarkers(isMarkers);
|
|
h->setItemAttribute(QwtPlotItem::Legend, false);
|
|
clonegainplot1D = new SlsQt1DPlot();
|
|
clonegainplot1D->SetTitleFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
clonegainplot1D->SetYFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
clonegainplot1D->SetTitle("");
|
|
clonegainplot1D->SetYTitle("Gain");
|
|
// set ticks to just 3
|
|
QList<double> majorTicks({0, 1, 2, 3});
|
|
QwtScaleDiv div(0, 3, QList<double>(), QList<double>(), majorTicks);
|
|
clonegainplot1D->setAxisScaleDiv(QwtPlot::yLeft, div);
|
|
h->Attach(clonegainplot1D);
|
|
}
|
|
} else {
|
|
LOG(logDEBUG) << "Cloning 2D Image";
|
|
cloneplot2D = new SlsQt2DPlot();
|
|
cloneplot2D->setFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
cloneplot2D->SetTitleFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
cloneplot2D->SetXFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
cloneplot2D->SetYFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
cloneplot2D->SetZFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
cloneplot2D->setTitle(plot2d->title().text());
|
|
cloneplot2D->SetXTitle(xTitle2d);
|
|
cloneplot2D->SetYTitle(yTitle2d);
|
|
cloneplot2D->SetZTitle(zTitle2d);
|
|
cloneplot2D->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5,
|
|
nPixelsY - 0.5, data2d);
|
|
cloneplot2D->SetZRange(isZRange[0], isZRange[1], zRange[0], zRange[1]);
|
|
|
|
if (isGainDataExtracted) {
|
|
clonegainplot2D = new SlsQt2DPlot();
|
|
clonegainplot2D->SetTitleFont(
|
|
QFont("Sans Serif", qDefs::Q_FONT_SIZE, QFont::Normal));
|
|
clonegainplot2D->SetTitle("Gain");
|
|
clonegainplot2D->SetZTitle("");
|
|
clonegainplot2D->enableAxis(QwtPlot::yLeft, false);
|
|
clonegainplot2D->enableAxis(QwtPlot::xBottom, false);
|
|
// set ticks to just 3
|
|
QList<double> majorTicks({0, 1, 2, 3});
|
|
QwtScaleDiv div(0, 3, QList<double>(), QList<double>(), majorTicks);
|
|
clonegainplot2D->setAxisScaleDiv(QwtPlot::yRight, div);
|
|
|
|
clonegainplot2D->enableAxis(0, false);
|
|
clonegainplot2D->enableAxis(1, false);
|
|
clonegainplot2D->enableAxis(2, false);
|
|
clonegainplot2D->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY,
|
|
-0.5, nPixelsY - 0.5, gainData);
|
|
}
|
|
}
|
|
|
|
new qCloneWidget(this, cloneplot1D, cloneplot2D, clonegainplot1D,
|
|
clonegainplot2D, boxPlot->title(), fileSavePath,
|
|
fileSaveName, currentAcqIndex, displayStatistics,
|
|
lblMinDisp->text(), lblMaxDisp->text(), lblSumDisp->text(),
|
|
completeImage);
|
|
}
|
|
|
|
void qDrawPlot::SavePlot() {
|
|
// render image
|
|
QImage savedImage(size().width(), size().height(), QImage::Format_RGB32);
|
|
QPainter painter(&savedImage);
|
|
render(&painter);
|
|
|
|
QString fName = fileSavePath + QString('/') + fileSaveName + QString('_') +
|
|
(is1d ? plot1d->title().text() : plot2d->title().text()) +
|
|
QString('_') + QString("%1").arg(currentAcqIndex) +
|
|
QString(".png");
|
|
|
|
fName = QFileDialog::getSaveFileName(
|
|
nullptr, tr("Save Image"), fName,
|
|
tr("PNG Files (*.png);;XPM Files(*.xpm);;JPEG Files(*.jpg)"), nullptr,
|
|
QFileDialog::ShowDirsOnly);
|
|
|
|
if (!fName.isEmpty()) {
|
|
if (savedImage.save(fName)) {
|
|
qDefs::Message(qDefs::INFORMATION,
|
|
"The Image has been successfully saved",
|
|
"qDrawPlot::SavePlot");
|
|
fileSavePath = fName.section('/', 0, -2);
|
|
} else {
|
|
qDefs::Message(
|
|
qDefs::WARNING,
|
|
"Attempt to save image failed.\n Formats: .png, .jpg, .xpm.",
|
|
"qDrawPlot::SavePlot");
|
|
}
|
|
}
|
|
}
|
|
|
|
void qDrawPlot::GetStatistics(double &min, double &max, double &sum) {
|
|
LOG(logDEBUG) << "Calculating Statistics";
|
|
double *array = data2d;
|
|
int size = nPixelsX * nPixelsY;
|
|
if (is1d) {
|
|
array = datay1d[0];
|
|
size = nPixelsX;
|
|
}
|
|
for (int i = 0; i < size; ++i) {
|
|
if (array[i] < min)
|
|
min = array[i];
|
|
if (array[i] > max)
|
|
max = array[i];
|
|
sum += array[i];
|
|
}
|
|
}
|
|
|
|
void qDrawPlot::DetachHists() {
|
|
for (QVector<SlsQtH1D *>::iterator h = hists1d.begin(); h != hists1d.end();
|
|
++h) {
|
|
(*h)->Detach(plot1d);
|
|
}
|
|
if (gainhist1d) {
|
|
gainhist1d->Detach(gainplot1d);
|
|
}
|
|
}
|
|
|
|
void qDrawPlot::StartAcquisition() {
|
|
LOG(logDEBUG) << "Starting Acquisition in qDrawPlot";
|
|
progress = 0;
|
|
currentFrame = 0;
|
|
boxPlot->setTitle("Old Plot");
|
|
det->clearAcquiringFlag(); // (from previous exit) or if running
|
|
|
|
// ensure data streaming in receiver (if plot enabled)
|
|
if (isPlot) {
|
|
try {
|
|
if (!det->getRxZmqDataStream().squash(false)) {
|
|
det->setRxZmqDataStream(true);
|
|
}
|
|
}
|
|
CATCH_DISPLAY("Could not enable data streaming in Receiver.",
|
|
"qDrawPlot::StartAcquisition");
|
|
}
|
|
|
|
// refixing all the zooming
|
|
{
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
xyRangeChanged = true;
|
|
}
|
|
|
|
QtConcurrent::run(this, &qDrawPlot::AcquireThread);
|
|
|
|
LOG(logDEBUG) << "End of Starting Acquisition in qDrawPlot";
|
|
}
|
|
|
|
void qDrawPlot::AcquireThread() {
|
|
LOG(logDEBUG) << "Acquire Thread";
|
|
std::string mess;
|
|
try {
|
|
det->acquire();
|
|
} catch (const std::exception &e) {
|
|
mess = std::string(e.what());
|
|
}
|
|
LOG(logINFO) << "Acquisition Finished";
|
|
// exception in acquire will not call acquisition finished call back, so
|
|
// handle it
|
|
if (!mess.empty()) {
|
|
LOG(logERROR) << "Acquisition Finished with an exception: " << mess;
|
|
// qDefs::ExceptionMessage("Acquire unsuccessful.", mess,
|
|
// "qDrawPlot::AcquireFinished");
|
|
try {
|
|
det->stopDetector();
|
|
det->stopReceiver();
|
|
} catch (...) {
|
|
;
|
|
}
|
|
emit AbortSignal(QString(mess.c_str()));
|
|
}
|
|
LOG(logDEBUG) << "End of Acquisition Finished";
|
|
}
|
|
|
|
void qDrawPlot::GetAcquisitionFinishedCallBack(double currentProgress,
|
|
int detectorStatus,
|
|
void *this_pointer) {
|
|
((qDrawPlot *)this_pointer)
|
|
->AcquisitionFinished(currentProgress, detectorStatus);
|
|
LOG(logDEBUG) << "Acquisition Finished Call back successful";
|
|
}
|
|
|
|
void qDrawPlot::GetDataCallBack(detectorData *data, uint64_t frameIndex,
|
|
uint32_t subFrameIndex, void *this_pointer) {
|
|
((qDrawPlot *)this_pointer)->GetData(data, frameIndex, subFrameIndex);
|
|
LOG(logDEBUG) << "Get Data Call back successful";
|
|
}
|
|
|
|
void qDrawPlot::AcquisitionFinished(double currentProgress,
|
|
int detectorStatus) {
|
|
progress = currentProgress;
|
|
std::string status =
|
|
sls::ToString(static_cast<slsDetectorDefs::runStatus>(detectorStatus));
|
|
|
|
if (detectorStatus == slsDetectorDefs::ERROR) {
|
|
qDefs::Message(qDefs::WARNING,
|
|
std::string("<nobr>The acquisiton has ended abruptly. "
|
|
"Current Detector Status: ") +
|
|
status + std::string(".</nobr>"),
|
|
"qDrawPlot::AcquisitionFinished");
|
|
LOG(logERROR) << "Acquisition finished [Status: ERROR]";
|
|
} else {
|
|
LOG(logINFO) << "Acquisition finished [ Status:" << status
|
|
<< ", Progress: " << currentProgress << "% ]";
|
|
}
|
|
emit AcquireFinishedSignal();
|
|
}
|
|
|
|
void qDrawPlot::GetData(detectorData *data, uint64_t frameIndex,
|
|
uint32_t subFrameIndex) {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logDEBUG) << "* GetData Callback *" << std::endl
|
|
<< " frame index: " << frameIndex << std::endl
|
|
<< " sub frame index: "
|
|
<< (((int)subFrameIndex == -1) ? (int)-1 : subFrameIndex)
|
|
<< std::endl
|
|
<< " Data [" << std::endl
|
|
<< " \t progress: " << data->progressIndex << std::endl
|
|
<< " \t file name: " << data->fileName << std::endl
|
|
<< " \t nx: " << data->nx << std::endl
|
|
<< " \t ny: " << data->ny << std::endl
|
|
<< " \t data bytes: " << data->databytes << std::endl
|
|
<< " \t dynamic range: " << data->dynamicRange << std::endl
|
|
<< " \t file index: " << data->fileIndex << std::endl
|
|
<< " \t complete image: " << data->completeImage << std::endl
|
|
<< " ]";
|
|
|
|
progress = data->progressIndex;
|
|
currentAcqIndex = data->fileIndex;
|
|
currentFrame = frameIndex;
|
|
LOG(logDEBUG) << "[ Progress:" << progress << "%, Frame:" << currentFrame
|
|
<< " ]";
|
|
|
|
// 1d check if npixelX has changed (m3 for different counters enabled)
|
|
if (is1d && static_cast<int>(nPixelsX) != data->nx) {
|
|
nPixelsX = data->nx;
|
|
LOG(logINFO) << "Change in Detector Shape:\n\tnPixelsX:" << nPixelsX;
|
|
|
|
delete[] datax1d;
|
|
datax1d = new double[nPixelsX];
|
|
for (unsigned int px = 0; px < nPixelsX; ++px) {
|
|
datax1d[px] = px;
|
|
}
|
|
if (datay1d.size()) {
|
|
for (auto &it : datay1d) {
|
|
delete[] it;
|
|
}
|
|
datay1d.clear();
|
|
}
|
|
datay1d.push_back(new double[nPixelsX]);
|
|
for (unsigned int px = 0; px < nPixelsX; ++px) {
|
|
datax1d[px] = px;
|
|
datay1d[0][px] = 0;
|
|
}
|
|
currentPersistency = 0;
|
|
if (gainDatay1d) {
|
|
delete[] gainDatay1d;
|
|
gainDatay1d = new double[nPixelsX];
|
|
std::fill(gainDatay1d, gainDatay1d + nPixelsX, 0);
|
|
}
|
|
}
|
|
|
|
// 2d (only image, not gain data, not pedestalvals),
|
|
// check if npixelsX and npixelsY is the same (quad is different)
|
|
if (!is1d && (static_cast<int>(nPixelsX) != data->nx ||
|
|
static_cast<int>(nPixelsY) != data->ny)) {
|
|
nPixelsX = data->nx;
|
|
nPixelsY = data->ny;
|
|
LOG(logINFO) << "Change in Detector Shape:\n\tnPixelsX:" << nPixelsX
|
|
<< " nPixelsY:" << nPixelsY;
|
|
|
|
delete[] data2d;
|
|
data2d = new double[nPixelsY * nPixelsX];
|
|
std::fill(data2d, data2d + nPixelsX * nPixelsY, 0);
|
|
if (gainData) {
|
|
delete[] gainData;
|
|
gainData = new double[nPixelsY * nPixelsX];
|
|
std::fill(gainData, gainData + nPixelsX * nPixelsY, 0);
|
|
}
|
|
}
|
|
|
|
// convert data to double
|
|
unsigned int nPixels = nPixelsX * (is1d ? 1 : nPixelsY);
|
|
double *rawData = new double[nPixels];
|
|
if (hasGainData) {
|
|
toDoublePixelData(rawData, data->data, nPixels, data->databytes,
|
|
data->dynamicRange, is1d ? gainDatay1d : gainData);
|
|
isGainDataExtracted = true;
|
|
} else {
|
|
toDoublePixelData(rawData, data->data, nPixels, data->databytes,
|
|
data->dynamicRange);
|
|
isGainDataExtracted = false;
|
|
}
|
|
|
|
// gotthard25um rearranging
|
|
if (gotthard25) {
|
|
rearrangeGotthard25data(rawData);
|
|
}
|
|
|
|
// title and frame index titles
|
|
plotTitle =
|
|
plotTitlePrefix + QString(data->fileName.c_str()).section('/', -1);
|
|
indexTitle = QString("%1").arg(frameIndex);
|
|
if ((int)subFrameIndex != -1) {
|
|
indexTitle = QString("%1 %2").arg(frameIndex).arg(subFrameIndex);
|
|
}
|
|
completeImage = data->completeImage;
|
|
|
|
// reset pedestal
|
|
if (resetPedestal) {
|
|
pedestalCount = 0;
|
|
|
|
delete[] pedestalVals;
|
|
pedestalVals = new double[nPixels];
|
|
std::fill(pedestalVals, pedestalVals + nPixels, 0);
|
|
|
|
delete[] tempPedestalVals;
|
|
tempPedestalVals = new double[nPixels];
|
|
std::fill(tempPedestalVals, tempPedestalVals + nPixels, 0);
|
|
resetPedestal = false;
|
|
}
|
|
|
|
if (isPedestal && pedestalCount <= NUM_PEDESTAL_FRAMES) {
|
|
// add pedestals frames
|
|
if (pedestalCount < NUM_PEDESTAL_FRAMES) {
|
|
for (unsigned int px = 0; px < nPixels; ++px)
|
|
tempPedestalVals[px] += rawData[px];
|
|
pedestalCount++;
|
|
}
|
|
// calculate the pedestal value
|
|
if (pedestalCount == NUM_PEDESTAL_FRAMES) {
|
|
LOG(logINFO) << "Pedestal Calculated after " << NUM_PEDESTAL_FRAMES
|
|
<< " frames";
|
|
for (unsigned int px = 0; px < nPixels; ++px)
|
|
tempPedestalVals[px] =
|
|
tempPedestalVals[px] / (double)NUM_PEDESTAL_FRAMES;
|
|
memcpy(pedestalVals, tempPedestalVals, nPixels * sizeof(double));
|
|
pedestalCount++;
|
|
}
|
|
}
|
|
|
|
if (is1d) {
|
|
Get1dData(rawData);
|
|
} else {
|
|
Get2dData(rawData);
|
|
}
|
|
delete[] rawData;
|
|
|
|
LOG(logDEBUG) << "End of Get Data";
|
|
emit UpdateSignal();
|
|
}
|
|
|
|
void qDrawPlot::Get1dData(double *rawData) {
|
|
|
|
// persistency
|
|
if (currentPersistency < persistency)
|
|
currentPersistency++;
|
|
else
|
|
currentPersistency = persistency; // when reducing persistency
|
|
nHists = currentPersistency + 1;
|
|
if (currentPersistency) {
|
|
// allocate
|
|
for (int i = datay1d.size(); i <= persistency; ++i) {
|
|
datay1d.push_back(new double[nPixelsX]);
|
|
}
|
|
// copy previous data
|
|
for (int i = currentPersistency; i > 0; --i)
|
|
memcpy(datay1d[i], datay1d[i - 1], nPixelsX * sizeof(double));
|
|
}
|
|
// pedestal
|
|
if (isPedestal) {
|
|
for (unsigned int px = 0; px < nPixelsX; ++px) {
|
|
rawData[px] -= (pedestalVals[px]);
|
|
}
|
|
}
|
|
// accumulate
|
|
if (resetAccumulate) {
|
|
std::fill(datay1d[0], datay1d[0] + nPixelsX, 0);
|
|
resetAccumulate = false;
|
|
}
|
|
if (isAccumulate) {
|
|
for (unsigned int px = 0; px < nPixelsX; ++px) {
|
|
rawData[px] += datay1d[0][px];
|
|
}
|
|
}
|
|
// binary
|
|
if (isBinary) {
|
|
int lBinaryFrom = binaryFrom;
|
|
int lBinaryTo = binaryTo;
|
|
for (unsigned int px = 0; px < nPixelsX; ++px) {
|
|
if ((rawData[px] >= lBinaryFrom) && (rawData[px] <= lBinaryTo))
|
|
rawData[px] = 1;
|
|
else
|
|
rawData[px] = 0;
|
|
}
|
|
}
|
|
memcpy(datay1d[0], rawData, nPixelsX * sizeof(double));
|
|
}
|
|
|
|
void qDrawPlot::Get2dData(double *rawData) {
|
|
unsigned int nPixels = nPixelsX * nPixelsY;
|
|
// pedestal
|
|
if (isPedestal) {
|
|
for (unsigned int px = 0; px < nPixels; ++px) {
|
|
rawData[px] -= (pedestalVals[px]);
|
|
}
|
|
}
|
|
// accumulate
|
|
if (resetAccumulate) {
|
|
std::fill(data2d, data2d + nPixels, 0);
|
|
resetAccumulate = false;
|
|
}
|
|
if (isAccumulate) {
|
|
for (unsigned int px = 0; px < nPixels; ++px) {
|
|
rawData[px] += data2d[px];
|
|
}
|
|
}
|
|
// binary
|
|
if (isBinary) {
|
|
int lBinaryFrom = binaryFrom;
|
|
int lBinaryTo = binaryTo;
|
|
for (unsigned int px = 0; px < nPixels; ++px) {
|
|
if ((rawData[px] >= lBinaryFrom) && (rawData[px] <= lBinaryTo))
|
|
rawData[px] = 1;
|
|
else
|
|
rawData[px] = 0;
|
|
}
|
|
}
|
|
memcpy(data2d, rawData, nPixels * sizeof(double));
|
|
}
|
|
|
|
void qDrawPlot::Update1dPlot() {
|
|
DetachHists();
|
|
plot1d->SetTitle(indexTitle);
|
|
plot1d->SetXTitle(xTitle1d);
|
|
plot1d->SetYTitle(yTitle1d);
|
|
for (int i = 0; i < nHists; ++i) {
|
|
if (i < hists1d.size()) {
|
|
SlsQtH1D *h = hists1d.at(i);
|
|
h->SetData(nPixelsX, datax1d, datay1d[i]);
|
|
h->Attach(plot1d);
|
|
} else {
|
|
SlsQtH1D *h = new SlsQtH1D("", nPixelsX, datax1d, datay1d[i]);
|
|
h->SetLineColor(i);
|
|
h->setStyleLinesorDots(isLines);
|
|
h->setSymbolMarkers(isMarkers);
|
|
hists1d.append(h);
|
|
h->Attach(plot1d);
|
|
}
|
|
}
|
|
if (isGainDataExtracted) {
|
|
gainhist1d->SetData(nPixelsX, datax1d, gainDatay1d);
|
|
gainhist1d->SetLineColor(0);
|
|
gainhist1d->setStyleLinesorDots(isLines);
|
|
gainhist1d->setSymbolMarkers(isMarkers);
|
|
gainhist1d->Attach(gainplot1d);
|
|
if (!gainplot1d->isVisible()) {
|
|
gainplot1d->setFixedWidth(plot1d->width());
|
|
gainplot1d->setFixedHeight(plot1d->height() /
|
|
qDefs::DATA_GAIN_PLOT_RATIO);
|
|
gainplot1d->show();
|
|
}
|
|
} else if (gainplot1d->isVisible()) {
|
|
gainplot1d->hide();
|
|
}
|
|
if (xyRangeChanged) {
|
|
Update1dXYRange();
|
|
xyRangeChanged = false;
|
|
}
|
|
plot1d->DisableZoom(disableZoom);
|
|
}
|
|
|
|
void qDrawPlot::Update2dPlot() {
|
|
plot2d->SetTitle(indexTitle);
|
|
plot2d->SetXTitle(xTitle2d);
|
|
plot2d->SetYTitle(yTitle2d);
|
|
plot2d->SetZTitle(zTitle2d);
|
|
plot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5,
|
|
nPixelsY - 0.5, data2d);
|
|
if (isGainDataExtracted) {
|
|
gainplot2d->SetData(nPixelsX, -0.5, nPixelsX - 0.5, nPixelsY, -0.5,
|
|
nPixelsY - 0.5, gainData);
|
|
if (!gainplot2d->isVisible()) {
|
|
gainplot2d->setFixedWidth(plot2d->width() /
|
|
qDefs::DATA_GAIN_PLOT_RATIO);
|
|
gainplot2d->setFixedHeight(plot2d->height() /
|
|
qDefs::DATA_GAIN_PLOT_RATIO);
|
|
gainplot2d->show();
|
|
}
|
|
} else if (gainplot2d->isVisible()) {
|
|
gainplot2d->hide();
|
|
}
|
|
if (xyRangeChanged) {
|
|
Update2dXYRange();
|
|
xyRangeChanged = false;
|
|
}
|
|
plot2d->DisableZoom(disableZoom);
|
|
plot2d->SetZRange(isZRange[0], isZRange[1], zRange[0], zRange[1]);
|
|
}
|
|
|
|
void qDrawPlot::Update1dXYRange() {
|
|
if (!isXYRange[qDefs::XMIN] && !isXYRange[qDefs::XMAX]) {
|
|
plot1d->EnableXAutoScaling();
|
|
} else {
|
|
double xmin = (isXYRange[qDefs::XMIN] ? xyRange[qDefs::XMIN]
|
|
: plot1d->GetXMinimum());
|
|
double xmax = (isXYRange[qDefs::XMAX] ? xyRange[qDefs::XMAX]
|
|
: plot1d->GetXMaximum());
|
|
plot1d->SetXMinMax(xmin, xmax);
|
|
}
|
|
|
|
if (!isXYRange[qDefs::YMIN] && !isXYRange[qDefs::YMAX]) {
|
|
plot1d->EnableYAutoScaling();
|
|
} else {
|
|
double ymin = (isXYRange[qDefs::YMIN] ? xyRange[qDefs::YMIN]
|
|
: plot1d->GetYMinimum());
|
|
double ymax = (isXYRange[qDefs::YMAX] ? xyRange[qDefs::YMAX]
|
|
: plot1d->GetYMaximum());
|
|
plot1d->SetYMinMax(ymin, ymax);
|
|
}
|
|
plot1d->Update();
|
|
}
|
|
|
|
void qDrawPlot::Update2dXYRange() {
|
|
if (!isXYRange[qDefs::XMIN] && !isXYRange[qDefs::XMAX]) {
|
|
plot2d->EnableXAutoScaling();
|
|
} else {
|
|
double xmin = (isXYRange[qDefs::XMIN] ? xyRange[qDefs::XMIN]
|
|
: plot2d->GetXMinimum());
|
|
double xmax = (isXYRange[qDefs::XMAX] ? xyRange[qDefs::XMAX]
|
|
: plot2d->GetXMaximum());
|
|
plot2d->SetXMinMax(xmin, xmax);
|
|
}
|
|
|
|
if (!isXYRange[qDefs::YMIN] && !isXYRange[qDefs::YMAX]) {
|
|
plot2d->EnableYAutoScaling();
|
|
} else {
|
|
double ymin = (isXYRange[qDefs::YMIN] ? xyRange[qDefs::YMIN]
|
|
: plot2d->GetYMinimum());
|
|
double ymax = (isXYRange[qDefs::YMAX] ? xyRange[qDefs::YMAX]
|
|
: plot2d->GetYMaximum());
|
|
plot2d->SetYMinMax(ymin, ymax);
|
|
}
|
|
plot2d->Update();
|
|
}
|
|
|
|
void qDrawPlot::toDoublePixelData(double *dest, char *source, int size,
|
|
int databytes, int dr, double *gaindest) {
|
|
int ichan = 0;
|
|
int ibyte = 0;
|
|
int halfbyte = 0;
|
|
char cbyte = '\0';
|
|
|
|
// mythen3 / gotthard2 debugging
|
|
int discardBits = numDiscardBits;
|
|
|
|
uint16_t temp = 0;
|
|
uint8_t *src = (uint8_t *)source;
|
|
switch (dr) {
|
|
|
|
case 4:
|
|
for (ibyte = 0; ibyte < databytes; ++ibyte) {
|
|
cbyte = source[ibyte];
|
|
for (halfbyte = 1; halfbyte >= 0; --halfbyte) {
|
|
dest[ichan] = (cbyte >> (halfbyte * 4)) & 0xf;
|
|
++ichan;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 8:
|
|
for (ichan = 0; ichan < databytes; ++ichan) {
|
|
dest[ichan] = *((u_int8_t *)source);
|
|
++source;
|
|
}
|
|
break;
|
|
|
|
case 12:
|
|
for (ichan = 0; ichan < size; ++ichan) {
|
|
temp = (*src++ & 0xFF);
|
|
temp |= ((*src & 0xF) << 8u);
|
|
dest[ichan] = (double)temp;
|
|
++ichan;
|
|
|
|
temp = ((*src++ & 0xF0) >> 4u);
|
|
temp |= ((*src++ & 0xFF) << 4u);
|
|
dest[ichan] = (double)temp;
|
|
}
|
|
break;
|
|
|
|
case 16:
|
|
if (detType == slsDetectorDefs::JUNGFRAU ||
|
|
detType == slsDetectorDefs::GOTTHARD2) {
|
|
|
|
// show gain plot
|
|
if (gaindest != nullptr) {
|
|
for (ichan = 0; ichan < size; ++ichan) {
|
|
uint16_t temp = (*((u_int16_t *)source));
|
|
gaindest[ichan] = ((temp & gainMask) >> gainOffset);
|
|
dest[ichan] = (temp & pixelMask);
|
|
source += 2;
|
|
}
|
|
}
|
|
|
|
// only data plot
|
|
else {
|
|
for (ichan = 0; ichan < size; ++ichan) {
|
|
dest[ichan] = ((*((u_int16_t *)source)) & pixelMask);
|
|
source += 2;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
// other detectors
|
|
for (ichan = 0; ichan < size; ++ichan) {
|
|
dest[ichan] = *((u_int16_t *)source);
|
|
source += 2;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (discardBits > 0) {
|
|
for (ichan = 0; ichan < size; ++ichan) {
|
|
dest[ichan] = ((*((u_int32_t *)source)) >> discardBits);
|
|
source += 4;
|
|
}
|
|
} else {
|
|
for (ichan = 0; ichan < size; ++ichan) {
|
|
dest[ichan] = (*((u_int32_t *)source));
|
|
source += 4;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void qDrawPlot::rearrangeGotthard25data(double *data) {
|
|
const int nChans = NUM_GOTTHARD25_CHANS;
|
|
double temp[nChans * 2] = {0.0};
|
|
for (int i = 0; i != nChans; ++i) {
|
|
// master module
|
|
temp[i * 2] = data[i];
|
|
// slave module
|
|
temp[i * 2 + 1] = data[nChans + i];
|
|
}
|
|
memcpy(data, temp, nChans * 2 * sizeof(double));
|
|
}
|
|
|
|
void qDrawPlot::UpdatePlot() {
|
|
std::lock_guard<std::mutex> lock(mPlots);
|
|
LOG(logDEBUG) << "Update Plot";
|
|
|
|
boxPlot->setTitle(plotTitle);
|
|
|
|
// notify of incomplete images
|
|
lblCompleteImage->hide();
|
|
lblInCompleteImage->hide();
|
|
if (completeImage) {
|
|
lblCompleteImage->show();
|
|
} else {
|
|
lblInCompleteImage->show();
|
|
}
|
|
|
|
if (is1d) {
|
|
Update1dPlot();
|
|
} else {
|
|
Update2dPlot();
|
|
}
|
|
|
|
if (displayStatistics) {
|
|
double min = 0, max = 0, sum = 0;
|
|
GetStatistics(min, max, sum);
|
|
lblMinDisp->setText(QString("%1").arg(min));
|
|
lblMaxDisp->setText(QString("%1").arg(max));
|
|
lblSumDisp->setText(QString("%1").arg(sum));
|
|
widgetStatistics->show();
|
|
} else {
|
|
widgetStatistics->hide();
|
|
}
|
|
|
|
LOG(logDEBUG) << "End of Update Plot";
|
|
}
|