From 37fdeaedbc6013c9edcdfa11aae06ca3b19988f8 Mon Sep 17 00:00:00 2001 From: splitPoleDAQ Date: Fri, 2 Jun 2023 18:13:47 -0400 Subject: [PATCH] separate Histogram Classes into spearate file. making 2D Cut --- Analyser.cpp | 19 ++- Analyser.h | 3 +- CustomHistogram.h | 305 ---------------------------------------------- FSUDAQ_Qt6.pro | 3 +- Histogram1D.h | 208 +++++++++++++++++++++++++++++++ Histogram2D.h | 267 ++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- SingleSpectra.h | 2 +- 8 files changed, 489 insertions(+), 320 deletions(-) delete mode 100644 CustomHistogram.h create mode 100644 Histogram1D.h create mode 100644 Histogram2D.h diff --git a/Analyser.cpp b/Analyser.cpp index abfe326..17b91c9 100644 --- a/Analyser.cpp +++ b/Analyser.cpp @@ -27,14 +27,11 @@ Analyzer::Analyzer(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent ) // layout->addWidget(bnSetting); SetUpCanvas(); - } Analyzer::~Analyzer(){ - for( unsigned int i = 0; i < nDigi; i++ ) delete oeb[i]; delete [] oeb; - } void Analyzer::StartThread(){ @@ -51,22 +48,22 @@ void Analyzer::StopThread(){ void Analyzer::SetUpCanvas(){ + setGeometry(0, 0, 1600, 800); + h2 = new Histogram2D("testing", "x", "y", 400, 0, 4000, 400, 0, 4000, this); - layout->addWidget(h2); + layout->addWidget(h2, 0, 0); h1 = new Histogram1D("testing", "x", 400, 0, 4000, this); - layout->addWidget(h1); - - - //Histogram * h1 = new Histogram("h1", 0, 5000, 200); - + layout->addWidget(h1, 0, 1); std::random_device rd; std::mt19937 gen(rd()); std::normal_distribution distribution(2000.0, 1000); for( int i = 0; i < 1000 ; i++ ){ - h2->Fill(distribution(gen), distribution(gen)); - h1->Fill(distribution(gen)); + double x = distribution(gen); + double y = distribution(gen); + h2->Fill(x, y); + h1->Fill(x); } h1->UpdatePlot(); diff --git a/Analyser.h b/Analyser.h index 66c7593..fad6d48 100644 --- a/Analyser.h +++ b/Analyser.h @@ -28,7 +28,8 @@ This is the mother of all other derivative analysis class. derivative class should define the SetUpCanvas() and UpdateHistogram(); ***************************************/ -#include "CustomHistogram.h" +#include "Histogram1D.h" +#include "Histogram2D.h" //^============================================== //^============================================== diff --git a/CustomHistogram.h b/CustomHistogram.h deleted file mode 100644 index eee1db5..0000000 --- a/CustomHistogram.h +++ /dev/null @@ -1,305 +0,0 @@ -#ifndef CUSTOM_HIST_H -#define CUSTOM_HIST_H - -#include "qcustomplot.h" - -//^============================================== -//^============================================== -class Histogram1D : public QCustomPlot{ -public: - Histogram1D(QString title, QString xLabel, int xbin, double xmin, double xmax, QWidget * parent = nullptr) : QCustomPlot(parent){ - Rebin(xbin, xmin, xmax); - - xAxis->setLabel(xLabel); - - legend->setVisible(true); - QPen borderPen = legend->borderPen(); - borderPen.setWidth(0); - borderPen.setColor(Qt::transparent); - legend->setBorderPen(borderPen); - legend->setFont(QFont("Helvetica", 9)); - - addGraph(); - graph(0)->setName(title); - graph(0)->setPen(QPen(Qt::blue)); - graph(0)->setBrush(QBrush(QColor(0, 0, 255, 20))); - - xAxis2->setVisible(true); - xAxis2->setTickLabels(false); - yAxis2->setVisible(true); - yAxis2->setTickLabels(false); - // make left and bottom axes always transfer their ranges to right and top axes: - connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); - connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); - - graph(0)->setData(xList, yList); - - //setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); - //setInteractions( QCP::iRangeDrag | QCP::iRangeZoom ); - - //setSelectionRectMode(QCP::SelectionRectMode::srmZoom); - - rescaleAxes(); - yAxis->setRangeLower(0); - yAxis->setRangeUpper(10); - - txtTotEntry = new QCPItemText(this); - txtTotEntry->setPositionAlignment(Qt::AlignLeft); - txtTotEntry->position->setType(QCPItemPosition::ptAxisRectRatio); - txtTotEntry->position->setCoords(0.1, 0.1);; - txtTotEntry->setText("Total Entry : 0"); - txtTotEntry->setFont(QFont("Helvetica", 9)); - - txtUnderFlow = new QCPItemText(this); - txtUnderFlow->setPositionAlignment(Qt::AlignLeft); - txtUnderFlow->position->setType(QCPItemPosition::ptAxisRectRatio); - txtUnderFlow->position->setCoords(0.1, 0.15);; - txtUnderFlow->setText("Under Flow : 0"); - txtUnderFlow->setFont(QFont("Helvetica", 9)); - - txtOverFlow = new QCPItemText(this); - txtOverFlow->setPositionAlignment(Qt::AlignLeft); - txtOverFlow->position->setType(QCPItemPosition::ptAxisRectRatio); - txtOverFlow->position->setCoords(0.1, 0.2);; - txtOverFlow->setText("Over Flow : 0"); - txtOverFlow->setFont(QFont("Helvetica", 9)); - - usingMenu = false; - - connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){ - double x = this->xAxis->pixelToCoord(event->pos().x()); - double bin = (x - xMin)/dX; - double z = yList[2*qFloor(bin) + 1]; - - QString coordinates = QString("Bin: %1, Value: %2").arg(qFloor(bin)).arg(z); - QToolTip::showText(event->globalPosition().toPoint(), coordinates, this); - }); - - connect(this, &QCustomPlot::mousePress, this, [=](QMouseEvent * event){ - if (event->button() == Qt::LeftButton && !usingMenu){ - setSelectionRectMode(QCP::SelectionRectMode::srmZoom); - } - if (event->button() == Qt::RightButton) { - usingMenu = true; - setSelectionRectMode(QCP::SelectionRectMode::srmNone); - QMenu *menu = new QMenu(this); - menu->setAttribute(Qt::WA_DeleteOnClose); - - QAction * a1 = menu->addAction("UnZoom"); - //TODO QAction * a2 = menu->addAction("Fit Guass"); - - QAction *selectedAction = menu->exec(event->globalPosition().toPoint()); - if( selectedAction == a1 ){ - xAxis->setRangeLower(xMin); - xAxis->setRangeUpper(xMax); - yAxis->setRangeLower(0); - yAxis->setRangeUpper(yMax * 1.2 > 10 ? yMax * 1.2 : 10); - replot(); - usingMenu = false; - } - } - }); - - } - - int GetNBin() const {return xBin;} - double GetXMin() const {return xMin;} - double GetXMax() const {return xMax;} - - void UpdatePlot(){ - graph(0)->setData(xList, yList); - xAxis->setRangeLower(xMin); - xAxis->setRangeUpper(xMax); - yAxis->setRangeLower(0); - yAxis->setRangeUpper(yMax * 1.2 > 10 ? yMax * 1.2 : 10); - replot(); - } - - void Clear(){ - for( int i = 0; i <= yList.count(); i++) yList[i] = 0; - yMax = 0; - UpdatePlot(); - } - - void Rebin(int xbin, double xmin, double xmax){ - xMin = xmin; - xMax = xmax; - xBin = xbin; - - dX = (xMax - xMin)/(xBin); - - xList.clear(); - yList.clear(); - - for( int i = 0; i <= xBin; i ++ ){ - xList.append(xMin + i*dX-(dX)*0.000001); - xList.append(xMin + i*dX); - yList.append(0); - yList.append(0); - } - - yMax = 0; - - totalEntry = 0; - underFlow = 0; - overFlow = 0; - - } - - void Fill(double value){ - totalEntry ++; - txtTotEntry->setText("Total Entry : "+ QString::number(totalEntry)); - - if( value < xMin ) { - underFlow ++; - txtUnderFlow->setText("Under Flow : "+ QString::number(underFlow)); - return; - } - if( value > xMax ) { - overFlow ++; - txtOverFlow->setText("Over Flow : "+ QString::number(overFlow)); - return; - } - - double bin = (value - xMin)/dX; - int index1 = 2*qFloor(bin) + 1; - int index2 = index1 + 1; - - if( 0 <= index1 && index1 <= 2*xBin) yList[index1] += 1; - if( 0 <= index1 && index2 <= 2*xBin) yList[index2] += 1; - - if( yList[index1] > yMax ) yMax = yList[index1]; - } - - void Print(){ - for( int i = 0; i < xList.count(); i++){ - printf("%f %f\n", xList[i], yList[i]); - } - } - -private: - double xMin, xMax, dX; - int xBin; - - double yMax; - - int totalEntry; - int underFlow; - int overFlow; - - QVector xList, yList; - - QCPItemText * txtTotEntry; - QCPItemText * txtUnderFlow; - QCPItemText * txtOverFlow; - - bool usingMenu; - -}; - -//^============================================== -//^============================================== -class Histogram2D : public QCustomPlot{ -public: - Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent = nullptr) : QCustomPlot(parent){ - xMin = xmin; - xMax = xmax; - yMin = ymin; - yMax = ymax; - xBin = xbin; - yBin = ybin; - - axisRect()->setupFullAxesBox(true); - xAxis->setLabel(xLabel); - yAxis->setLabel(yLabel); - - colorMap = new QCPColorMap(xAxis, yAxis); - colorMap->data()->setSize(xBin, yBin); - colorMap->data()->setRange(QCPRange(xMin, xMax), QCPRange(yMin, yMax)); - colorMap->setInterpolate(false); - - QCPTextElement *titleEle = new QCPTextElement(this, title, QFont("sans", 12)); - plotLayout()->addElement(0, 0, titleEle); - - colorScale = new QCPColorScale(this); - plotLayout()->addElement(0, 1, colorScale); - colorScale->setType(QCPAxis::atRight); - colorMap->setColorScale(colorScale); - - QCPColorGradient color; - color.clearColorStops(); - color.setColorStopAt( 0, QColor("white" )); - color.setColorStopAt( 0.5, QColor("blue")); - color.setColorStopAt( 1, QColor("yellow")); - colorMap->setGradient(color); - - rescaleAxes(); - - usingMenu = false; - - connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){ - double x = xAxis->pixelToCoord(event->pos().x()); - double y = yAxis->pixelToCoord(event->pos().y()); - int xI, yI; - colorMap->data()->coordToCell(x, y, &xI, &yI); - double z = colorMap->data()->cell(xI, yI); - - QString coordinates = QString("X: %1, Y: %2, Z: %3").arg(x).arg(y).arg(z); - QToolTip::showText(event->globalPosition().toPoint(), coordinates, this); - }); - - connect(this, &QCustomPlot::mousePress, this, [=](QMouseEvent * event){ - if (event->button() == Qt::LeftButton && !usingMenu){ - setSelectionRectMode(QCP::SelectionRectMode::srmZoom); - } - if (event->button() == Qt::RightButton) { - usingMenu = true; - setSelectionRectMode(QCP::SelectionRectMode::srmNone); - - QMenu *menu = new QMenu(this); - menu->setAttribute(Qt::WA_DeleteOnClose); - - QAction * a1 = menu->addAction("UnZoom"); - - QAction *selectedAction = menu->exec(event->globalPosition().toPoint()); - - if( selectedAction == a1 ){ - xAxis->setRangeLower(xMin); - xAxis->setRangeUpper(xMax); - yAxis->setRangeLower(yMin); - yAxis->setRangeUpper(yMax); - replot(); - usingMenu = false; - } - } - }); - - } - - void UpdatePlot(){ - colorMap->rescaleDataRange(); - rescaleAxes(); - replot(); - } - - void Fill(double x, double y){ - int xIndex, yIndex; - colorMap->data()->coordToCell(x, y, &xIndex, &yIndex); - //printf("%f, %d %d| %f, %d %d\n", x, xIndex, xBin, y, yIndex, yBin); - if( xIndex < 0 || xBin < xIndex || yIndex < 0 || yBin < yIndex ) return; - double value = colorMap->data()->cell(xIndex, yIndex); - colorMap->data()->setCell(xIndex, yIndex, value + 1); - } - -private: - double xMin, xMax, yMin, yMax; - int xBin, yBin; - - QCPColorMap * colorMap; - QCPColorScale *colorScale; - - bool usingMenu; - -}; - -#endif \ No newline at end of file diff --git a/FSUDAQ_Qt6.pro b/FSUDAQ_Qt6.pro index 60a90b7..79ba307 100644 --- a/FSUDAQ_Qt6.pro +++ b/FSUDAQ_Qt6.pro @@ -26,7 +26,8 @@ HEADERS += ClassData.h \ ClassDigitizer.h \ CustomThreads.h \ CustomWidgets.h \ - CustomHistogram.h \ + Histogram1D.h \ + Histogram2D.h \ DigiSettingsPanel.h \ FSUDAQ.h \ macro.h \ diff --git a/Histogram1D.h b/Histogram1D.h new file mode 100644 index 0000000..59e9b2a --- /dev/null +++ b/Histogram1D.h @@ -0,0 +1,208 @@ +#ifndef HISTOGRAM_1D_H +#define HISTOGRAM_1D_H + +#include "qcustomplot.h" + +//^============================================== +//^============================================== +class Histogram1D : public QCustomPlot{ +public: + Histogram1D(QString title, QString xLabel, int xbin, double xmin, double xmax, QWidget * parent = nullptr) : QCustomPlot(parent){ + Rebin(xbin, xmin, xmax); + + xAxis->setLabel(xLabel); + + legend->setVisible(true); + QPen borderPen = legend->borderPen(); + borderPen.setWidth(0); + borderPen.setColor(Qt::transparent); + legend->setBorderPen(borderPen); + legend->setFont(QFont("Helvetica", 9)); + + addGraph(); + graph(0)->setName(title); + graph(0)->setPen(QPen(Qt::blue)); + graph(0)->setBrush(QBrush(QColor(0, 0, 255, 20))); + + xAxis2->setVisible(true); + xAxis2->setTickLabels(false); + yAxis2->setVisible(true); + yAxis2->setTickLabels(false); + // make left and bottom axes always transfer their ranges to right and top axes: + connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); + connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); + + graph(0)->setData(xList, yList); + + //setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); + //setInteractions( QCP::iRangeDrag | QCP::iRangeZoom ); + + //setSelectionRectMode(QCP::SelectionRectMode::srmZoom); + + rescaleAxes(); + yAxis->setRangeLower(0); + yAxis->setRangeUpper(10); + + for( int i = 0; i < 3; i ++){ + txt[i] = new QCPItemText(this); + txt[i]->setPositionAlignment(Qt::AlignLeft); + txt[i]->position->setType(QCPItemPosition::ptAxisRectRatio); + txt[i]->position->setCoords(0.1, 0.1 + 0.1*i);; + txt[i]->setFont(QFont("Helvetica", 9)); + if( i == 0 ) txt[i]->setText("Under Flow : 0"); + if( i == 1 ) txt[i]->setText("Total Entry : 0"); + if( i == 2 ) txt[i]->setText("Over Flow : 0"); + } + + usingMenu = false; + + connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){ + double x = this->xAxis->pixelToCoord(event->pos().x()); + double bin = (x - xMin)/dX; + double z = yList[2*qFloor(bin) + 1]; + + QString coordinates = QString("Bin: %1, Value: %2").arg(qFloor(bin)).arg(z); + QToolTip::showText(event->globalPosition().toPoint(), coordinates, this); + }); + + connect(this, &QCustomPlot::mousePress, this, [=](QMouseEvent * event){ + if (event->button() == Qt::LeftButton && !usingMenu){ + setSelectionRectMode(QCP::SelectionRectMode::srmZoom); + } + if (event->button() == Qt::RightButton) { + usingMenu = true; + setSelectionRectMode(QCP::SelectionRectMode::srmNone); + + QMenu menu(this); + + QAction * a1 = menu.addAction("UnZoom"); + QAction * a2 = menu.addAction("Clear hist."); + QAction * a3 = menu.addAction("Toggle Stat."); + + //TODO rebin + //TODO fitGuass + + QAction *selectedAction = menu.exec(event->globalPosition().toPoint()); + if( selectedAction == a1 ){ + xAxis->setRangeLower(xMin); + xAxis->setRangeUpper(xMax); + yAxis->setRangeLower(0); + yAxis->setRangeUpper(yMax * 1.2 > 10 ? yMax * 1.2 : 10); + replot(); + usingMenu = false; + } + + if( selectedAction == a2 ){ + Clear(); + usingMenu = false; + } + + if( selectedAction == a3 ){ + for( int i = 0; i < 3; i++){ + txt[i]->setVisible( !txt[i]->visible()); + } + replot(); + usingMenu = false; + } + } + }); + + } + + int GetNBin() const {return xBin;} + double GetXMin() const {return xMin;} + double GetXMax() const {return xMax;} + + void UpdatePlot(){ + graph(0)->setData(xList, yList); + xAxis->setRangeLower(xMin); + xAxis->setRangeUpper(xMax); + yAxis->setRangeLower(0); + yAxis->setRangeUpper(yMax * 1.2 > 10 ? yMax * 1.2 : 10); + replot(); + } + + void Clear(){ + for( int i = 0; i <= yList.count(); i++) yList[i] = 0; + yMax = 0; + txt[0]->setText("Under Flow : 0"); + txt[1]->setText("Total Entry : 0"); + txt[2]->setText("Over Flow : 0"); + UpdatePlot(); + } + + void Rebin(int xbin, double xmin, double xmax){ + xMin = xmin; + xMax = xmax; + xBin = xbin; + + dX = (xMax - xMin)/(xBin); + + xList.clear(); + yList.clear(); + + for( int i = 0; i <= xBin; i ++ ){ + xList.append(xMin + i*dX-(dX)*0.000001); + xList.append(xMin + i*dX); + yList.append(0); + yList.append(0); + } + + yMax = 0; + + totalEntry = 0; + underFlow = 0; + overFlow = 0; + + } + + void Fill(double value){ + totalEntry ++; + txt[1]->setText("Total Entry : "+ QString::number(totalEntry)); + + if( value < xMin ) { + underFlow ++; + txt[0]->setText("Under Flow : "+ QString::number(underFlow)); + return; + } + if( value > xMax ) { + overFlow ++; + txt[2]->setText("Over Flow : "+ QString::number(overFlow)); + return; + } + + double bin = (value - xMin)/dX; + int index1 = 2*qFloor(bin) + 1; + int index2 = index1 + 1; + + if( 0 <= index1 && index1 <= 2*xBin) yList[index1] += 1; + if( 0 <= index1 && index2 <= 2*xBin) yList[index2] += 1; + + if( yList[index1] > yMax ) yMax = yList[index1]; + } + + void Print(){ + for( int i = 0; i < xList.count(); i++){ + printf("%f %f\n", xList[i], yList[i]); + } + } + +private: + double xMin, xMax, dX; + int xBin; + + double yMax; + + int totalEntry; + int underFlow; + int overFlow; + + QVector xList, yList; + + QCPItemText * txt[3]; + + bool usingMenu; + +}; + +#endif \ No newline at end of file diff --git a/Histogram2D.h b/Histogram2D.h new file mode 100644 index 0000000..75807a5 --- /dev/null +++ b/Histogram2D.h @@ -0,0 +1,267 @@ +#ifndef HISTOGRAM_2D_H +#define HISTOGRAM_2D_H + +#include "qcustomplot.h" + +const QList colorCycle = { QColor(Qt::red), + QColor(Qt::blue), + QColor(Qt::darkGreen), + QColor(Qt::darkCyan), + QColor(Qt::darkYellow), + QColor(Qt::magenta), + QColor(Qt::darkMagenta), + QColor(Qt::gray)}; + +//^============================================== +//^============================================== +class Histogram2D : public QCustomPlot{ +public: + Histogram2D(QString title, QString xLabel, QString yLabel, int xbin, double xmin, double xmax, int ybin, double ymin, double ymax, QWidget * parent = nullptr) : QCustomPlot(parent){ + xMin = xmin; + xMax = xmax; + yMin = ymin; + yMax = ymax; + xBin = xbin; + yBin = ybin; + + axisRect()->setupFullAxesBox(true); + xAxis->setLabel(xLabel); + yAxis->setLabel(yLabel); + + colorMap = new QCPColorMap(xAxis, yAxis); + colorMap->data()->setSize(xBin, yBin); + colorMap->data()->setRange(QCPRange(xMin, xMax), QCPRange(yMin, yMax)); + colorMap->setInterpolate(false); + + QCPTextElement *titleEle = new QCPTextElement(this, title, QFont("sans", 12)); + plotLayout()->insertRow(0); + plotLayout()->addElement(0, 0, titleEle); + + colorScale = new QCPColorScale(this); + plotLayout()->addElement(1, 1, colorScale); + colorScale->setType(QCPAxis::atRight); + colorMap->setColorScale(colorScale); + + QCPColorGradient color; + color.clearColorStops(); + color.setColorStopAt( 0, QColor("white" )); + color.setColorStopAt( 0.5, QColor("blue")); + color.setColorStopAt( 1, QColor("yellow")); + colorMap->setGradient(color); + + cutList.clear(); + + double xPosStart = 0.02; + double xPosStep = 0.07; + double yPosStart = 0.02; + double yPosStep = 0.05; + + for( int i = 0; i < 3; i ++ ){ + for( int j = 0; j < 3; j ++ ){ + entry[i][j] = 0; + box[i][j] = new QCPItemRect(this); + + box[i][j]->topLeft->setType(QCPItemPosition::ptAxisRectRatio); + box[i][j]->topLeft->setCoords(xPosStart + xPosStep*i, yPosStart + yPosStep*j); + box[i][j]->bottomRight->setType(QCPItemPosition::ptAxisRectRatio); + box[i][j]->bottomRight->setCoords(xPosStart + xPosStep*(i+1), yPosStart + yPosStep*(j+1)); + + txt[i][j] = new QCPItemText(this); + txt[i][j]->setPositionAlignment(Qt::AlignLeft); + txt[i][j]->position->setType(QCPItemPosition::ptAxisRectRatio); + txt[i][j]->position->setCoords(xPosStart + xPosStep/2 + xPosStep*i, yPosStart + yPosStep*j);; + txt[i][j]->setText("0"); + txt[i][j]->setFont(QFont("Helvetica", 9)); + + } + } + + + rescaleAxes(); + + usingMenu = false; + isDrawCut = false; + + connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){ + double x = xAxis->pixelToCoord(event->pos().x()); + double y = yAxis->pixelToCoord(event->pos().y()); + int xI, yI; + colorMap->data()->coordToCell(x, y, &xI, &yI); + double z = colorMap->data()->cell(xI, yI); + + QString coordinates = QString("X: %1, Y: %2, Z: %3").arg(x).arg(y).arg(z); + QToolTip::showText(event->globalPosition().toPoint(), coordinates, this); + + //TODO, when drawing cut, show dashhed line + + + }); + + connect(this, &QCustomPlot::mousePress, this, [=](QMouseEvent * event){ + if (event->button() == Qt::LeftButton && !usingMenu && !isDrawCut){ + setSelectionRectMode(QCP::SelectionRectMode::srmZoom); + } + if (event->button() == Qt::LeftButton && isDrawCut){ + + double x = xAxis->pixelToCoord(event->pos().x()); + double y = yAxis->pixelToCoord(event->pos().y()); + + tempCut.push_back(QPointF(x,y)); + + DrawCut(); + } + + if (event->button() == Qt::RightButton) { + usingMenu = true; + setSelectionRectMode(QCP::SelectionRectMode::srmNone); + + QMenu *menu = new QMenu(this); + menu->setAttribute(Qt::WA_DeleteOnClose); + + QAction * a1 = menu->addAction("UnZoom"); + QAction * a2 = menu->addAction("Clear hist."); + QAction * a3 = menu->addAction("Toggle Stat."); + QAction * a4 = menu->addAction("Create a Cut"); + for( int i = 0; i < cutList.size(); i++){ + menu->addAction("Delete Cut-" + QString::number(i)); + } + + QAction *selectedAction = menu->exec(event->globalPosition().toPoint()); + + if( selectedAction == a1 ){ + xAxis->setRangeLower(xMin); + xAxis->setRangeUpper(xMax); + yAxis->setRangeLower(yMin); + yAxis->setRangeUpper(yMax); + replot(); + usingMenu = false; + } + + if( selectedAction == a2 ) { + Clear(); + usingMenu = false; + } + + if( selectedAction == a3 ){ + for( int i = 0; i < 3; i ++ ){ + for( int j = 0; j < 3; j ++ ){ + box[i][j]->setVisible( !box[i][j]->visible()); + txt[i][j]->setVisible( !txt[i][j]->visible()); + } + } + replot(); + usingMenu = false; + } + + if( selectedAction == a4 ){ + tempCut.clear(); + isDrawCut= true; + usingMenu = false; + } + + // if( selectedAction->text().contains("Delete Cut") ){ + // qDebug() << "delete Cut"; + // } + + } + }); + + //connect( this, &QCustomPlot::mouseDoubleClick, this, [=](QMouseEvent *event){ + connect( this, &QCustomPlot::mouseDoubleClick, this, [=](){ + isDrawCut = false; + tempCut.push_back(tempCut[0]); + cutList.push_back(tempCut); + DrawCut(); + }); + + connect(this, &QCustomPlot::mouseRelease, this, [=](){ + + + }); + } + + void UpdatePlot(){ + colorMap->rescaleDataRange(); + rescaleAxes(); + replot(); + } + + void Clear(){ + colorMap->data()->clear(); + for( int i = 0; i < 3; i ++){ + for( int j = 0; j < 3; j ++){ + entry[i][j] = 0; + txt[i][j]->setText("0"); + } + } + UpdatePlot(); + } + + void Fill(double x, double y){ + int xIndex, yIndex; + colorMap->data()->coordToCell(x, y, &xIndex, &yIndex); + //printf("%f, %d %d| %f, %d %d\n", x, xIndex, xBin, y, yIndex, yBin); + + int xk = 1, yk = 1; + if( xIndex < 0 ) xk = 0; + if( xIndex >= xBin ) xk = 2; + if( yIndex < 0 ) yk = 0; + if( yIndex >= yBin ) yk = 2; + entry[xk][yk] ++; + + txt[xk][yk]->setText(QString::number(entry[xk][yk])); + + if( xk == 1 && yk == 1 ) { + double value = colorMap->data()->cell(xIndex, yIndex); + colorMap->data()->setCell(xIndex, yIndex, value + 1); + } + } + + void DrawCut(){ + + //TODO how to delete cut from plot and from QList + + plottableCount(); + + //TODO how to not double plot? + + if(tempCut.size() > 1) { + QCPCurve *polygon = new QCPCurve(xAxis, yAxis); + + QPen pen(Qt::blue); + pen.setWidth(1); + polygon->setPen(pen); + + QVector dataPoints; + for (const QPointF& point : tempCut) { + dataPoints.append(QCPCurveData(dataPoints.size(), point.x(), point.y())); + } + polygon->data()->set(dataPoints, false); + } + + replot(); + } + + QList GetCutList() const{return cutList;} + +private: + double xMin, xMax, yMin, yMax; + int xBin, yBin; + + QCPColorMap * colorMap; + QCPColorScale *colorScale; + + bool usingMenu; + + int entry[3][3]; // overflow counter, entrt[1][1] is entry in the plot; + + QCPItemRect * box[3][3]; + QCPItemText * txt[3][3]; + + QPolygonF tempCut; + QList cutList; + bool isDrawCut; + +}; + +#endif \ No newline at end of file diff --git a/README.md b/README.md index f907f81..4378a31 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ It has scope (updated every half-sec), allow full control of the digitizer (exce It can be connected to InfluxDB v1.8 and Elog. -Each channel has it own 1D histogram. It will not be filled by default, but can enable it in the "Online 1D histgram" panel. +Each channel has it own 1D histogram. It will not be filled by default, but can enable it in the "Online 1D histgram" panel. The binning of each histogram will be saved under the raw data path as singleSpectaSetting.txt # Operation diff --git a/SingleSpectra.h b/SingleSpectra.h index 16ee5bb..3910495 100644 --- a/SingleSpectra.h +++ b/SingleSpectra.h @@ -15,7 +15,7 @@ #include "ClassDigitizer.h" #include "CustomThreads.h" #include "CustomWidgets.h" -#include "CustomHistogram.h" +#include "Histogram1D.h" //^====================================================