remove the old Histogram using QChart, move HistogramXD to a new file
This commit is contained in:
parent
c342f7c8e6
commit
69d25facb8
|
@ -58,30 +58,25 @@ Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QM
|
|||
double nBin = 100;
|
||||
|
||||
for( unsigned int i = 0; i < MaxNDigitizer; i++){
|
||||
for( int j = 0; j < MaxNChannels; j++){
|
||||
for( int j = 0; j < digi[i]->GetNChannels(); j++){
|
||||
if( i < nDigi ) {
|
||||
hist[i][j] = new Histogram("Digi-" + QString::number(digi[i]->GetSerialNumber()) +", Ch-" + QString::number(j), xMin, xMax, nBin);
|
||||
histView[i][j] = new RChartView(hist[i][j]->GetChart());
|
||||
histView[i][j]->SetVRange(0, 10);
|
||||
hist[i][j] = new Histogram1D("Digi-" + QString::number(digi[i]->GetSerialNumber()) +", Ch-" + QString::number(j), "Raw Energy [ch]", nBin, xMin, xMax);
|
||||
}else{
|
||||
hist[i][j] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
histLayout->addWidget(histView[0][0], 0, 0);
|
||||
histLayout->addWidget(hist[0][0], 0, 0);
|
||||
oldBd = -1;
|
||||
oldCh = -1;
|
||||
|
||||
}
|
||||
|
||||
Canvas::~Canvas(){
|
||||
for( int i = 0; i < MaxNDigitizer; i++){
|
||||
for( int j = 0; j < MaxNChannels; j++){
|
||||
if( hist[i][j] ) {
|
||||
delete hist[i][j];
|
||||
delete histView[i][j];
|
||||
}
|
||||
for( unsigned int i = 0; i < nDigi; i++ ){
|
||||
for( int ch = 0; ch < digi[i]->GetNChannels(); ch++){
|
||||
delete hist[i][ch];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,13 +84,13 @@ Canvas::~Canvas(){
|
|||
void Canvas::ChangeHistView(){
|
||||
|
||||
if( oldCh >= 0 ) {
|
||||
histLayout->removeWidget(histView[oldBd][oldCh]);
|
||||
histView[oldBd][oldCh]->setParent(nullptr);
|
||||
histLayout->removeWidget(hist[oldBd][oldCh]);
|
||||
hist[oldBd][oldCh]->setParent(nullptr);
|
||||
}
|
||||
int bd = cbDigi->currentIndex();
|
||||
int ch = cbCh->currentIndex();
|
||||
|
||||
histLayout->addWidget(histView[bd][ch], 0, 0);
|
||||
histLayout->addWidget(hist[bd][ch], 0, 0);
|
||||
|
||||
oldBd = bd;
|
||||
oldCh = ch;
|
||||
|
@ -110,9 +105,14 @@ void Canvas::UpdateCanvas(){
|
|||
int lastIndex = digi[i]->GetData()->DataIndex[ch];
|
||||
int nDecoded = digi[i]->GetData()->NumEventsDecoded[ch];
|
||||
|
||||
if( nDecoded == 0 ) continue;
|
||||
|
||||
for( int j = lastIndex - nDecoded + 1; j <= lastIndex; j ++){
|
||||
hist[i][ch]->Fill( digi[i]->GetData()->Energy[ch][j]);
|
||||
}
|
||||
|
||||
hist[i][ch]->UpdatePlot();
|
||||
|
||||
}
|
||||
digiMTX[i].unlock();
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "ClassDigitizer.h"
|
||||
#include "CustomThreads.h"
|
||||
#include "CustomWidgets.h"
|
||||
#include "CustomHistogram.h"
|
||||
|
||||
|
||||
//^====================================================
|
||||
|
@ -35,8 +36,7 @@ private:
|
|||
Digitizer ** digi;
|
||||
unsigned short nDigi;
|
||||
|
||||
Histogram * hist[MaxNDigitizer][MaxNChannels];
|
||||
RChartView * histView[MaxNDigitizer][MaxNChannels];
|
||||
Histogram1D * hist[MaxNDigitizer][MaxNChannels];
|
||||
|
||||
RComboBox * cbDivision;
|
||||
|
||||
|
|
|
@ -347,8 +347,7 @@ int Digitizer::ProgramPSDBoard(){
|
|||
//ret = CAEN_DGTZ_Reset(handle);
|
||||
Reset();
|
||||
|
||||
ret = CAEN_DGTZ_WriteRegister(handle, DPP::RecordLength_G + 0x7000, 62);
|
||||
ret = CAEN_DGTZ_WriteRegister(handle, DPP::BoardConfiguration, 0x0F3911); /// has Extra2, dual trace, input and CFD
|
||||
ret = CAEN_DGTZ_WriteRegister(handle, DPP::BoardConfiguration, 0x0F0115); /// has Extra2, dual trace, input and CFD
|
||||
|
||||
ret = CAEN_DGTZ_SetAcquisitionMode(handle, CAEN_DGTZ_SW_CONTROLLED); /// software command
|
||||
ret |= CAEN_DGTZ_SetIOLevel(handle, CAEN_DGTZ_IOLevel_NIM);
|
||||
|
@ -358,12 +357,12 @@ int Digitizer::ProgramPSDBoard(){
|
|||
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::ChannelDCOffset) + 0x7000 , 0xEEEE );
|
||||
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PreTrigger) + 0x7000 , 32 );
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::RecordLength_G) + 0x7000 , 128 );
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PreTrigger) + 0x7000 , 20 );
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::RecordLength_G) + 0x7000 , 80 );
|
||||
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::ShortGateWidth) + 0x7000 , 10 );
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::LongGateWidth) + 0x7000 , 30 );
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::GateOffset) + 0x7000 , 3 );
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::ShortGateWidth) + 0x7000 , 32 );
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::LongGateWidth) + 0x7000 , 64 );
|
||||
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(DPP::PSD::GateOffset) + 0x7000 , 19 );
|
||||
|
||||
if( ret != 0 ) { printf("==== set channels error.\n"); return 0;}
|
||||
|
||||
|
|
228
CustomHistogram.h
Normal file
228
CustomHistogram.h
Normal file
|
@ -0,0 +1,228 @@
|
|||
#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);
|
||||
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::iRangeZoom );
|
||||
|
||||
rescaleAxes();
|
||||
yAxis->setRangeLower(0);
|
||||
yAxis->setRangeUpper(10);
|
||||
|
||||
connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){
|
||||
double x = this->xAxis->pixelToCoord(event->pos().x());
|
||||
int bin = (x - xMin)/dX;
|
||||
double z = yList[2*qFloor(bin) + 1];
|
||||
|
||||
QString coordinates = QString("Bin: %1, Value: %2").arg(bin).arg(z);
|
||||
QToolTip::showText(event->globalPosition().toPoint(), coordinates, this);
|
||||
});
|
||||
|
||||
connect(this, &QCustomPlot::mousePress, this, [=](QMouseEvent * event){
|
||||
if (event->button() == Qt::RightButton) {
|
||||
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(0);
|
||||
xAxis->setRangeUpper(xMax);
|
||||
yAxis->setRangeLower(0);
|
||||
yAxis->setRangeUpper(yMax * 1.2);
|
||||
replot();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void UpdatePlot(){
|
||||
graph(0)->setData(xList, yList);
|
||||
xAxis->setRangeLower(0);
|
||||
xAxis->setRangeUpper(xMax);
|
||||
yAxis->setRangeLower(0);
|
||||
yAxis->setRangeUpper(yMax * 1.2 > 10 ? yMax * 1.2 : 10);
|
||||
replot();
|
||||
}
|
||||
|
||||
void Clear(){
|
||||
for( int i = 0; i <= xBin; i++) yList[i] = 0;
|
||||
graph(0)->setData(xList, yList);
|
||||
}
|
||||
|
||||
void Rebin(int xBin, double xMin, double xMax){
|
||||
this->xMin = xMin;
|
||||
this->xMax = xMax;
|
||||
this->xBin = xBin;
|
||||
|
||||
dX = (xMax - xMin)/(xBin);
|
||||
|
||||
xList.clear();
|
||||
yList.clear();
|
||||
|
||||
for( int i = 0; i <= xBin; i ++ ){
|
||||
xList.append(i*dX-(dX)*0.000001);
|
||||
xList.append(i*dX);
|
||||
yList.append(0);
|
||||
yList.append(0);
|
||||
}
|
||||
|
||||
yMax = 0;
|
||||
|
||||
totalEntry = 0;
|
||||
underFlow = 0;
|
||||
overFlow = 0;
|
||||
|
||||
}
|
||||
|
||||
void Fill(double value){
|
||||
|
||||
totalEntry ++;
|
||||
if( value < xMin ) underFlow ++;
|
||||
if( value > xMax ) overFlow ++;
|
||||
|
||||
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<double> xList, yList;
|
||||
|
||||
};
|
||||
|
||||
//^==============================================
|
||||
//^==============================================
|
||||
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){
|
||||
this->xMin = xMin;
|
||||
this->xMax = xMax;
|
||||
this->yMin = yMin;
|
||||
this->yMax = yMax;
|
||||
this->xBin = xBin;
|
||||
this->yBin = yBin;
|
||||
|
||||
axisRect()->setupFullAxesBox(true);
|
||||
xAxis->setLabel(xLabel);
|
||||
yAxis->setLabel(yLabel);
|
||||
|
||||
colorMap = new QCPColorMap(this->xAxis, this->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();
|
||||
|
||||
connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){
|
||||
double x = this->xAxis->pixelToCoord(event->pos().x());
|
||||
double y = this->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);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void UpdatePlot(){
|
||||
// rescale the data dimension (color) such that all data points lie in the span visualized by the color gradient:
|
||||
colorMap->rescaleDataRange();
|
||||
|
||||
// make sure the axis rect and color scale synchronize their bottom and top margins (so they line up):
|
||||
// QCPMarginGroup *marginGroup = new QCPMarginGroup(this);
|
||||
// this->axisRect()->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
|
||||
// colorScale->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
|
||||
|
||||
// rescale the key (x) and value (y) axes so the whole color map is visible:
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
105
CustomWidgets.h
105
CustomWidgets.h
|
@ -179,109 +179,4 @@ private:
|
|||
QLabel * m_coordinateLabel;
|
||||
};
|
||||
|
||||
//^====================================================
|
||||
class Histogram {
|
||||
public:
|
||||
Histogram(QString title, double xMin, double xMax, int nBin){
|
||||
|
||||
plot = new RChart();
|
||||
dataSeries = new QLineSeries();
|
||||
|
||||
Rebin(xMin, xMax, nBin);
|
||||
|
||||
maxBin = -1;
|
||||
maxBinValue = 0;
|
||||
|
||||
//dataSeries->setPen(QPen(Qt::blue, 1));
|
||||
areaSeries = new QAreaSeries(dataSeries);
|
||||
areaSeries->setName(title);
|
||||
areaSeries->setBrush(Qt::blue);
|
||||
|
||||
plot->addSeries(areaSeries);
|
||||
|
||||
plot->setAnimationDuration(1); // msec
|
||||
plot->setAnimationOptions(QChart::NoAnimation);
|
||||
plot->createDefaultAxes();
|
||||
|
||||
QValueAxis * xaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Horizontal).first());
|
||||
xaxis->setRange(xMin, xMax);
|
||||
xaxis->setTickCount( nBin + 1 > 11 ? 11 : nBin + 1);
|
||||
//xaxis->setLabelFormat("%.1f");
|
||||
//xaxis->setTitleText("Time [ns]");
|
||||
|
||||
QValueAxis * yaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Vertical).first());
|
||||
yaxis->setRange(0, 10);
|
||||
|
||||
}
|
||||
~Histogram(){
|
||||
delete areaSeries;
|
||||
delete dataSeries;
|
||||
delete plot;
|
||||
}
|
||||
|
||||
RChart * GetChart() { return plot;}
|
||||
|
||||
void Clear(){
|
||||
for( int i = 0; i <= nBin; i++) {
|
||||
dataSeries->replace(2*i, xMin + i * dX, 0);
|
||||
dataSeries->replace(2*i+1, xMin + i * dX, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void SetColor(Qt::GlobalColor color){ areaSeries->setBrush(color);}
|
||||
|
||||
void Rebin(double xMin, double xMax, int nBin){
|
||||
dataSeries->clear();
|
||||
this->xMin = xMin;
|
||||
this->xMax = xMax;
|
||||
this->nBin = nBin;
|
||||
dX = (xMax-xMin)/nBin;
|
||||
for( int i = 0; i <= nBin; i++) {
|
||||
dataSeries->append(xMin + i * dX, 0 );
|
||||
dataSeries->append(xMin + i * dX, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void Fill(double value){
|
||||
|
||||
double bin = (value - xMin)/dX;
|
||||
if( bin < 0 || bin >= nBin ) return;
|
||||
|
||||
int index1 = 2*qFloor(bin) + 1;
|
||||
int index2 = index1 + 1;
|
||||
|
||||
QPointF point1 = dataSeries->at(index1);
|
||||
dataSeries->replace(index1, point1.x(), point1.y() + 1);
|
||||
|
||||
QPointF point2 = dataSeries->at(index2);
|
||||
dataSeries->replace(index2, point2.x(), point2.y() + 1);
|
||||
|
||||
if( point2.y() + 1 > maxBinValue ){
|
||||
maxBinValue = point2.y() + 1;
|
||||
maxBin = index2/2;
|
||||
}
|
||||
|
||||
QValueAxis * yaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Vertical).first());
|
||||
yaxis->setRange(0, maxBinValue < 10 ? 10 : ((double)maxBinValue) * 1.2 );
|
||||
//yaxis->setTickInterval(1);
|
||||
//yaxis->setTickCount(10);
|
||||
//yaxis->setLabelFormat("%.0f");
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
RChart * plot;
|
||||
QLineSeries * dataSeries;
|
||||
QAreaSeries * areaSeries;
|
||||
|
||||
double dX, xMin, xMax;
|
||||
int nBin;
|
||||
|
||||
int maxBin;
|
||||
int maxBinValue;
|
||||
|
||||
};
|
||||
|
||||
//^====================================================
|
||||
|
||||
#endif
|
|
@ -26,6 +26,7 @@ HEADERS += ClassData.h \
|
|||
ClassDigitizer.h \
|
||||
CustomThreads.h \
|
||||
CustomWidgets.h \
|
||||
CustomHistogram.h \
|
||||
DigiSettingsPanel.h \
|
||||
FSUDAQ.h \
|
||||
macro.h \
|
||||
|
|
|
@ -51,33 +51,37 @@ void OnlineAnalyzer::StopThread(){
|
|||
|
||||
void OnlineAnalyzer::SetUpCanvas(){
|
||||
|
||||
h2 = new Histogram2D("testing", "x", "y", 100, 0, 4000, 100, 0, 4000, this);
|
||||
h2 = new Histogram2D("testing", "x", "y", 400, 0, 4000, 400, 0, 4000, this);
|
||||
layout->addWidget(h2);
|
||||
|
||||
h1 = new Histogram1D("testing", "x", 400, 0, 4000, this);
|
||||
layout->addWidget(h1);
|
||||
|
||||
|
||||
//Histogram * h1 = new Histogram("h1", 0, 5000, 200);
|
||||
|
||||
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::normal_distribution<double> distribution(2000.0, 500);
|
||||
std::normal_distribution<double> distribution(2000.0, 1000);
|
||||
for( int i = 0; i < 1000 ; i++ ){
|
||||
h2->Fill(distribution(gen), distribution(gen));
|
||||
//h2->Fill(distribution(gen), distribution(gen));
|
||||
h1->Fill(distribution(gen));
|
||||
}
|
||||
|
||||
h1->UpdatePlot();
|
||||
|
||||
}
|
||||
|
||||
void OnlineAnalyzer::UpdateHistograms(){
|
||||
|
||||
//Set with digitizer to be event build
|
||||
digiMTX[0].lock();
|
||||
//digi[0]->GetData()->PrintAllData();
|
||||
oeb[0]->BuildEvents(100, false);
|
||||
digiMTX[0].unlock();
|
||||
|
||||
//============ Get events, and do analysis
|
||||
long eventBuilt = oeb[0]->eventbuilt;
|
||||
printf("------------- eventBuilt %ld \n", eventBuilt);
|
||||
if( eventBuilt == 0 ) return;
|
||||
|
||||
long eventIndex = oeb[0]->eventIndex;
|
||||
|
@ -87,7 +91,6 @@ void OnlineAnalyzer::UpdateHistograms(){
|
|||
|
||||
unsigned short e1 = 0, e2 = 0;
|
||||
|
||||
int count = 0;
|
||||
for( long i = eventStart ; i <= eventIndex; i ++ ){
|
||||
std::vector<dataPoint> event = oeb[0]->events[i];
|
||||
|
||||
|
@ -97,8 +100,10 @@ void OnlineAnalyzer::UpdateHistograms(){
|
|||
}
|
||||
|
||||
h2->Fill(e1, e2);
|
||||
count ++;
|
||||
if( count > 500 ) break;
|
||||
|
||||
//h1->Fill(e1);
|
||||
}
|
||||
|
||||
h2->UpdatePlot();
|
||||
|
||||
}
|
106
OnlineAnalyser.h
106
OnlineAnalyser.h
|
@ -28,110 +28,7 @@ This is the mother of all other derivative analysis class.
|
|||
derivative class should define the SetUpCanvas() and UpdateHistogram();
|
||||
|
||||
***************************************/
|
||||
|
||||
#include "qcustomplot.h"
|
||||
|
||||
//^==============================================
|
||||
//^==============================================
|
||||
class Histogram1D : public QCustomPlot{
|
||||
public:
|
||||
Histogram1D(QString title, QString xLabel, int xBin, double xMin, double xMax, QWidget * parent = nullptr) : QCustomPlot(parent){
|
||||
this->xMin = xMin;
|
||||
this->xMax = xMax;
|
||||
this->xBin = xBin;
|
||||
|
||||
this->xAxis->setLabel(xLabel);
|
||||
|
||||
bars = new QCPBars(this->xAxis, this->yAxis);
|
||||
bars->setWidth((xMax- xMin)/xBin);
|
||||
}
|
||||
|
||||
private:
|
||||
double xMin, xMax, xBin;
|
||||
|
||||
QCPBars *bars;
|
||||
|
||||
};
|
||||
|
||||
//^==============================================
|
||||
//^==============================================
|
||||
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){
|
||||
this->xMin = xMin;
|
||||
this->xMax = xMax;
|
||||
this->yMin = yMin;
|
||||
this->yMax = yMax;
|
||||
this->xBin = xBin;
|
||||
this->yBin = yBin;
|
||||
|
||||
axisRect()->setupFullAxesBox(true);
|
||||
this->xAxis->setLabel(xLabel);
|
||||
this->yAxis->setLabel(yLabel);
|
||||
|
||||
colorMap = new QCPColorMap(this->xAxis, this->yAxis);
|
||||
colorMap->data()->setSize(xBin, yBin);
|
||||
colorMap->data()->setRange(QCPRange(xMin, xMax), QCPRange(yMin, yMax));
|
||||
colorMap->setInterpolate(false);
|
||||
|
||||
colorScale = new QCPColorScale(this);
|
||||
this->plotLayout()->addElement(0, 1, colorScale);
|
||||
colorScale->setType(QCPAxis::atRight);
|
||||
colorMap->setColorScale(colorScale);
|
||||
|
||||
QCPColorGradient color;
|
||||
color.clearColorStops();
|
||||
color.setColorStopAt( 0, QColor("white" ));
|
||||
color.setColorStopAt( 1, QColor("blue"));
|
||||
colorMap->setGradient(color);
|
||||
|
||||
this->rescaleAxes();
|
||||
|
||||
connect(this, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event){
|
||||
double x = this->xAxis->pixelToCoord(event->pos().x());
|
||||
double y = this->yAxis->pixelToCoord(event->pos().y());
|
||||
int xI, yI;
|
||||
colorMap->data()->coordToCell(x, y, &xI, &yI);
|
||||
double z = colorMap->data()->cell(xI, yI);
|
||||
|
||||
// Format the coordinates as desired
|
||||
QString coordinates = QString("X: %1, Y: %2, Z: %3").arg(x).arg(y).arg(z);
|
||||
|
||||
// Show the coordinates as a tooltip
|
||||
QToolTip::showText(event->globalPosition().toPoint(), coordinates, this);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void Fill(double x, double y){
|
||||
int xIndex, yIndex;
|
||||
colorMap->data()->coordToCell(x, y, &xIndex, &yIndex);
|
||||
//printf("%d %d\n", xIndex, yIndex);
|
||||
if( xIndex < 0 || xBin < xIndex || yIndex < 0 || yBin < yIndex ) return;
|
||||
double value = colorMap->data()->cell(xIndex, yIndex);
|
||||
colorMap->data()->setCell(xIndex, yIndex, value + 1);
|
||||
|
||||
// rescale the data dimension (color) such that all data points lie in the span visualized by the color gradient:
|
||||
colorMap->rescaleDataRange();
|
||||
|
||||
// make sure the axis rect and color scale synchronize their bottom and top margins (so they line up):
|
||||
// QCPMarginGroup *marginGroup = new QCPMarginGroup(this);
|
||||
// this->axisRect()->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
|
||||
// colorScale->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
|
||||
|
||||
// rescale the key (x) and value (y) axes so the whole color map is visible:
|
||||
this->rescaleAxes();
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
double xMin, xMax, yMin, yMax;
|
||||
int xBin, yBin;
|
||||
|
||||
QCPColorMap * colorMap;
|
||||
QCPColorScale *colorScale;
|
||||
|
||||
};
|
||||
#include "CustomHistogram.h"
|
||||
|
||||
//^==============================================
|
||||
//^==============================================
|
||||
|
@ -164,6 +61,7 @@ private:
|
|||
|
||||
//======================== custom histograms
|
||||
Histogram2D * h2;
|
||||
Histogram1D * h1;
|
||||
|
||||
};
|
||||
#endif
|
|
@ -57,7 +57,6 @@ void OnlineEventBuilder::FindEarlistTimeAndCh(){
|
|||
}
|
||||
|
||||
void OnlineEventBuilder::FindLatestTime(){
|
||||
|
||||
latestTime = 0;
|
||||
for( unsigned ch = 0; ch < nCh; ch++ ){
|
||||
int index = data->DataIndex[ch];
|
||||
|
@ -66,8 +65,7 @@ void OnlineEventBuilder::FindLatestTime(){
|
|||
latestTime = data->Timestamp[ch][index];
|
||||
}
|
||||
}
|
||||
|
||||
printf("--- latest time %lld \n", latestTime);
|
||||
//printf("--- latest time %lld \n", latestTime);
|
||||
}
|
||||
|
||||
void OnlineEventBuilder::BuildEvents(unsigned short timeWindow, bool verbose){
|
||||
|
|
49
README.md
49
README.md
|
@ -2,23 +2,36 @@
|
|||
|
||||
This is a DAQ for 1st gen CAEN digitizer for V1725, V17255S, V1230 with PHA and PSD firmware.
|
||||
|
||||
It has scope (updated every half-sec), allow full control of the digitizer (except LVDS), and allow saving waevform.
|
||||
It has scope (updated every half-sec), allow full control of the digitizer (except LVDS), and allow saving waveform.
|
||||
|
||||
It can be connected to InfluxDB v1.8 and Elog.
|
||||
|
||||
# Undergoing
|
||||
|
||||
the following additional functions are planned and I am working on them
|
||||
|
||||
- 1-D and 2-D histogram
|
||||
- Online Analyzer
|
||||
- support V1740 DPP-QDC
|
||||
- synchronization helper
|
||||
|
||||
# Required / Development enviroment
|
||||
|
||||
Ubuntu 22.04
|
||||
|
||||
CAENVMELib_v3.3
|
||||
- CAENVMELib_v3.3
|
||||
- CAENCOmm_v1.5.3
|
||||
- CAENDigitizer_v2.17.1
|
||||
- CAEN A3818 Driver
|
||||
|
||||
CAENCOmm_v1.5.3
|
||||
- qt6-base-dev
|
||||
- libqt6charts6-dec
|
||||
- libcurl4-openssl-dev
|
||||
- elog
|
||||
|
||||
CAENDigitizer_v2.17.1
|
||||
The CAEN Libraries need to download and install manually. The other libraries can be installed using the following command:
|
||||
|
||||
CAEN A3818 Driver
|
||||
|
||||
`sudo apt install qt6-base-dev libcurl4-openssl-dev libqt6charts6-dev qt6-webengine-dev elog`
|
||||
`sudo apt install qt6-base-dev libqt6charts6-dev libcurl4-openssl-dev elog`
|
||||
|
||||
The elog installed using apt is 3.1.3. If a higher version is needed. Please go to https://elog.psi.ch/elog/
|
||||
|
||||
|
@ -32,10 +45,28 @@ use `qmake6 -project ` to generate the *.pro
|
|||
|
||||
in the *.pro, add
|
||||
|
||||
` QT += core widgets charts`
|
||||
` QT += core widgets charts printsupport`
|
||||
|
||||
` LIBS += -lCAENDigitizer -lcurl`
|
||||
|
||||
then run ` qmake6 *.pro` it will generate Makefile
|
||||
|
||||
then ` make`
|
||||
then ` make`
|
||||
|
||||
if you want to use GDB debugger, in the *.pro file add
|
||||
|
||||
` QMAKE_CXXFLAGS += -g`
|
||||
|
||||
## exclude some files from the auto-gen *.pro
|
||||
|
||||
The following files must be excluded from the *.pro, as they are not related to the GUI
|
||||
|
||||
- DataGenerator.cpp
|
||||
- DataReaderScript.cpp
|
||||
- EventBuilder.cpp
|
||||
- test.cpp
|
||||
- test_indep.cpp
|
||||
|
||||
Those file can be compiled using
|
||||
|
||||
`make -f Makefile_test`
|
Loading…
Reference in New Issue
Block a user