Compare commits

...

12 Commits

Author SHA1 Message Date
splitPoleDAQ 9e514216af add influx and elog parameter in program settings 2023-05-24 17:10:36 -04:00
splitPoleDAQ bb74e0d308 add influxdb 2023-05-24 16:04:32 -04:00
splitPoleDAQ 1ae7309eb2 uncomment filling histograms, added UpdateOtherPanels() 2023-05-23 17:02:39 -04:00
splitPoleDAQ b18610a406 fix the crashgit add -A! 2023-05-23 14:52:23 -04:00
splitPoleDAQ c895037896 snapshot 2023-05-23 11:19:43 -04:00
splitPoleDAQ 8bead5a54b added ZeroTotalFileSize() for Data Class, this is for new run 2023-05-22 18:23:24 -04:00
splitPoleDAQ 8a662c3407 disbale channel conntrol if channel disabled 2023-05-22 17:13:48 -04:00
splitPoleDAQ 7e12a2d6a6 modified readDataThread, few bugs fixed 2023-05-22 17:00:11 -04:00
splitPoleDAQ 38c4d0d992 scope can fill histogram 2023-05-19 16:49:01 -04:00
splitPoleDAQ 3b9d47bbef when ACQ start, fill histograms 2023-05-19 16:23:04 -04:00
splitPoleDAQ 73c2286005 created a histogram class for 1D histogram 2023-05-18 17:14:24 -04:00
splitPoleDAQ a3deb59e0c add Canvas, try to make a hostorgam class 2023-05-17 17:40:32 -04:00
19 changed files with 1014 additions and 102 deletions

View File

@ -150,6 +150,7 @@
"cinttypes": "cpp", "cinttypes": "cpp",
"typeinfo": "cpp", "typeinfo": "cpp",
"variant": "cpp", "variant": "cpp",
"qmainwindow": "cpp" "qmainwindow": "cpp",
"qchartview": "cpp"
} }
} }

120
CanvasClass.cpp Normal file
View File

@ -0,0 +1,120 @@
#include "CanvasClass.h"
#include <QValueAxis>
#include <QRandomGenerator>
#include <QGroupBox>
#include <QStandardItemModel>
#include <QLabel>
#include <QRandomGenerator>
Canvas::Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent) : QMainWindow(parent){
this->digi = digi;
this->nDigi = nDigi;
setWindowTitle("Canvas");
setGeometry(0, 0, 1000, 800);
//setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint );
QWidget * layoutWidget = new QWidget(this);
setCentralWidget(layoutWidget);
QVBoxLayout * layout = new QVBoxLayout(layoutWidget);
layoutWidget->setLayout(layout);
//========================
QGroupBox * controlBox = new QGroupBox("Control", this);
layout->addWidget(controlBox);
QGridLayout * ctrlLayout = new QGridLayout(controlBox);
controlBox->setLayout(ctrlLayout);
QPushButton * bnClearHist = new QPushButton("Clear Hist.", this);
ctrlLayout->addWidget(bnClearHist, 0, 0);
connect(bnClearHist, &QPushButton::clicked, this, [=](){
for( int i = 0; i < MaxNDigitizer; i++){
for( int j = 0; j < MaxNChannels; j++){
if( hist[i][j] ) hist[i][j]->Clear();
}
}
});
cbDigi = new RComboBox(this);
for( unsigned int i = 0; i < nDigi; i++) cbDigi->addItem("Digi-" + QString::number( digi[i]->GetSerialNumber() ), i);
ctrlLayout->addWidget(cbDigi, 1, 0);
connect( cbDigi, &RComboBox::currentIndexChanged, this, &Canvas::ChangeHistView);
cbCh = new RComboBox(this);
for( int i = 0; i < MaxNChannels; i++) cbCh->addItem("ch-" + QString::number( i ), i);
ctrlLayout->addWidget(cbCh, 1, 1);
connect( cbCh, &RComboBox::currentIndexChanged, this, &Canvas::ChangeHistView);
//========================
histBox = new QGroupBox("Histgrams", this);
layout->addWidget(histBox);
histLayout = new QGridLayout(histBox);
histBox->setLayout(histLayout);
double xMax = 4000;
double xMin = 0;
double nBin = 100;
for( unsigned int i = 0; i < MaxNDigitizer; i++){
for( int j = 0; j < MaxNChannels; 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 TraceView(hist[i][j]->GetTrace());
histView[i][j]->SetVRange(0, 10);
}else{
hist[i][j] = nullptr;
}
}
}
histLayout->addWidget(histView[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];
}
}
}
}
void Canvas::ChangeHistView(){
if( oldCh >= 0 ) {
histLayout->removeWidget(histView[oldBd][oldCh]);
histView[oldBd][oldCh]->setParent(nullptr);
}
int bd = cbDigi->currentIndex();
int ch = cbCh->currentIndex();
histLayout->addWidget(histView[bd][ch], 0, 0);
oldBd = bd;
oldCh = ch;
}
void Canvas::UpdateCanvas(){
for( int i = 0; i < nDigi; i++){
digiMTX[i].lock();
for( int ch = 0; ch < digi[i]->GetNChannels(); ch ++ ){
int lastIndex = digi[i]->GetData()->EventIndex[ch];
int nDecoded = digi[i]->GetData()->NumEventsDecoded[ch];
for( int j = lastIndex - nDecoded + 1; j <= lastIndex; j ++){
hist[i][ch]->Fill( digi[i]->GetData()->Energy[ch][j]);
}
}
digiMTX[i].unlock();
}
}

59
CanvasClass.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef CANVAS_H
#define CANVAS_H
#include <QMainWindow>
#include <QChart>
#include <QChartView>
#include <QSpinBox>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QLineEdit>
#include <QComboBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QLineSeries>
#include <QRubberBand>
#include <QMouseEvent>
#include <QGestureEvent>
#include "macro.h"
#include "ClassDigitizer.h"
#include "CustomThreads.h"
#include "CustomWidgets.h"
//^====================================================
//^====================================================
class Canvas : public QMainWindow{
Q_OBJECT
public:
Canvas(Digitizer ** digi, unsigned int nDigi, QMainWindow * parent = nullptr);
~Canvas();
public slots:
void UpdateCanvas();
void ChangeHistView();
private:
Digitizer ** digi;
unsigned short nDigi;
Histogram * hist[MaxNDigitizer][MaxNChannels];
TraceView * histView[MaxNDigitizer][MaxNChannels];
RComboBox * cbDivision;
RComboBox * cbDigi;
RComboBox * cbCh;
QGroupBox * histBox;
QGridLayout * histLayout;
int oldBd, oldCh;
};
#endif

View File

@ -80,7 +80,7 @@ class Data{
void CloseSaveFile(); void CloseSaveFile();
unsigned int GetFileSize() const {return outFileSize;} unsigned int GetFileSize() const {return outFileSize;}
uint64_t GetTotalFileSize() const {return FinishedOutFilesSize + outFileSize;} uint64_t GetTotalFileSize() const {return FinishedOutFilesSize + outFileSize;}
void ZeroTotalFileSize() { FinishedOutFilesSize = 0; }
protected: protected:
@ -188,6 +188,7 @@ inline void Data::ClearData(){
} }
inline void Data::ClearBuffer(){ inline void Data::ClearBuffer(){
printf("==== Data::%s \n", __func__);
delete buffer; delete buffer;
buffer = nullptr; buffer = nullptr;
AllocatedSize = 0; AllocatedSize = 0;
@ -222,6 +223,11 @@ inline bool Data::OpenSaveFile(std::string fileNamePrefix){
inline void Data::SaveData(){ inline void Data::SaveData(){
if( buffer == nullptr) {
printf("buffer is null.\n");
return;
}
if( outFileSize > (unsigned int) MaxSaveFileSize){ if( outFileSize > (unsigned int) MaxSaveFileSize){
FinishedOutFilesSize += ftell(outFile); FinishedOutFilesSize += ftell(outFile);
CloseSaveFile(); CloseSaveFile();

View File

@ -406,6 +406,7 @@ void Digitizer::StopACQ(){
AcqRun = false; AcqRun = false;
data->ClearTriggerRate(); data->ClearTriggerRate();
data->ClearBuffer(); data->ClearBuffer();
data->ZeroTotalFileSize();
} }
unsigned int Digitizer::CalByteForBuffer(){ unsigned int Digitizer::CalByteForBuffer(){
@ -661,7 +662,7 @@ void Digitizer::ProgramSettingsToBoard(){
if( DPPType == V1730_DPP_PSD_CODE ){ if( DPPType == V1730_DPP_PSD_CODE ){
for( int p = 0; p < (int) RegisterPSDList.size(); p++){ for( int p = 0; p < (int) RegisterPSDList.size(); p++){
if( RegisterPSDList[p].GetType() == RW::ReadWrite){ if( RegisterPSDList[p].GetType() == RW::ReadWrite){
haha = RegisterPHAList[p]; haha = RegisterPSDList[p];
WriteRegister(haha, GetSettingFromMemory(haha, ch), ch, false); WriteRegister(haha, GetSettingFromMemory(haha, ch), ch, false);
usleep(1 * 1000); usleep(1 * 1000);
} }
@ -730,13 +731,13 @@ int Digitizer::LoadSettingBinaryToMemory(std::string fileName){
}else{ }else{
/// load binary to memoery /// load binary to memoery
DPPType = fileDPP; DPPType = fileDPP;
printf("DPPType in the file is %s(0x%X). \n", GetDPPString(fileDPP).c_str(), fileDPP); printf("DPPType in the file is %s(0x%X). Board Type is %s \n", GetDPPString(fileDPP).c_str(), fileDPP, GetDPPString().c_str());
settingFile = fopen(fileName.c_str(), "r"); settingFile = fopen(fileName.c_str(), "r");
size_t dummy = fread( setting, SETTINGSIZE * sizeof(unsigned int), 1, settingFile); size_t dummy = fread( setting, SETTINGSIZE * sizeof(unsigned int), 1, settingFile);
fclose (settingFile); fclose (settingFile);
if( dummy == 0 ) printf("reach the end of file\n"); if( dummy != 0 ) printf("reach the end of file (read %ld).\n", dummy);
uint32_t boardInfo = GetSettingFromMemory(DPP::BoardInfo_R); uint32_t boardInfo = GetSettingFromMemory(DPP::BoardInfo_R);
if( (boardInfo & 0xFF) == 0x0E ) ch2ns = 4.0; if( (boardInfo & 0xFF) == 0x0E ) ch2ns = 4.0;

View File

@ -103,8 +103,8 @@ class Digitizer{
CAEN_DGTZ_BoardInfo_t GetBoardInfo() const {return BoardInfo;} CAEN_DGTZ_BoardInfo_t GetBoardInfo() const {return BoardInfo;}
std::string GetModelName() const {return BoardInfo.ModelName;} std::string GetModelName() const {return BoardInfo.ModelName;}
int GetSerialNumber() const {return BoardInfo.SerialNumber;} int GetSerialNumber() const {return BoardInfo.SerialNumber;}
int GetChannelMask() const {return channelMask;} int GetChannelMask() { channelMask = GetSettingFromMemory(DPP::ChannelEnableMask); return channelMask;}
bool GetChannelOnOff(unsigned ch) const {return (channelMask & ( 1 << ch) );} bool GetChannelOnOff(unsigned ch) { channelMask = GetSettingFromMemory(DPP::ChannelEnableMask); return (channelMask & ( 1 << ch) );}
float GetCh2ns() const {return ch2ns;} float GetCh2ns() const {return ch2ns;}
int GetNChannels() const {return NChannel;} int GetNChannels() const {return NChannel;}
int GetHandle() const {return handle;} int GetHandle() const {return handle;}
@ -152,10 +152,10 @@ class Digitizer{
// bool IsEnabledAutoDataFlush() {return ( GetSettingFromMemory(DPP::BoardConfiguration) & 0x1 );} // bool IsEnabledAutoDataFlush() {return ( GetSettingFromMemory(DPP::BoardConfiguration) & 0x1 );}
// bool IsDecimateTrace() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 1) & 0x1 );} // bool IsDecimateTrace() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 1) & 0x1 );}
// bool IsTriggerPropagate() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 2) & 0x1 );} // bool IsTriggerPropagate() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 2) & 0x1 );}
bool IsDualTrace() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 11) & 0x1 );} bool IsDualTrace_PHA() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 11) & 0x1 );}
// unsigned short AnaProbe1Type() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 12) & 0x3 );} // unsigned short AnaProbe1Type() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 12) & 0x3 );}
// unsigned short AnaProbe2Type() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 14) & 0x3 );} // unsigned short AnaProbe2Type() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 14) & 0x3 );}
// bool IsRecordTrace() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 16) & 0x1 );} bool IsRecordTrace() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 16) & 0x1 );}
// bool IsEnabledExtra2() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 17) & 0x1 );} // bool IsEnabledExtra2() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 17) & 0x1 );}
// bool IsRecordTimeStamp() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 18) & 0x1 );} // bool IsRecordTimeStamp() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 18) & 0x1 );}
// bool IsRecordEnergy() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 19) & 0x1 );} // bool IsRecordEnergy() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 19) & 0x1 );}

View File

@ -18,47 +18,72 @@ public:
this->ID = digiID; this->ID = digiID;
isSaveData = false; isSaveData = false;
isScope = false; isScope = false;
readCount = 0;
stop = false;
} }
void Stop() { this->stop = true;}
void SetSaveData(bool onOff) {this->isSaveData = onOff;} void SetSaveData(bool onOff) {this->isSaveData = onOff;}
void SetScopeMode(bool onOff) {this->isScope = onOff;} void SetScopeMode(bool onOff) {this->isScope = onOff;}
void run(){ void run(){
clock_gettime(CLOCK_REALTIME, &ta); clock_gettime(CLOCK_REALTIME, &t0);
while(true){ ta = t0;
// clock_gettime(CLOCK_REALTIME, &t1);
stop = false;
do{
if( stop) break;
digiMTX[ID].lock(); digiMTX[ID].lock();
int ret = digi->ReadData(); int ret = digi->ReadData();
digiMTX[ID].unlock(); digiMTX[ID].unlock();
readCount ++;
if( ret == CAEN_DGTZ_Success ){ if( stop) break;
if( ret == CAEN_DGTZ_Success && !stop){
digiMTX[ID].lock(); digiMTX[ID].lock();
digi->GetData()->DecodeBuffer(!isScope); digi->GetData()->DecodeBuffer(!isScope, 0);
if( isSaveData ) digi->GetData()->SaveData(); if( isSaveData ) digi->GetData()->SaveData();
digiMTX[ID].unlock(); digiMTX[ID].unlock();
// clock_gettime(CLOCK_REALTIME, &t2);
// if( t2.tv_sec - t1.tv_sec > 2 ) {
// printf("----Digi-%d read %ld / sec.\n", ID, readCount / 3);
// readCount = 0;
// t1 = t2;
// }
}else{ }else{
printf("ReadDataThread::%s------------ ret : %d \n", __func__, ret); printf("ReadDataThread::%s------------ ret : %d \n", __func__, ret);
digiMTX[ID].lock();
digi->StopACQ(); digi->StopACQ();
digiMTX[ID].unlock();
break; break;
} }
if( isSaveData ) { if( isSaveData && !stop ) {
clock_gettime(CLOCK_REALTIME, &tb); clock_gettime(CLOCK_REALTIME, &tb);
if( tb.tv_sec - ta.tv_sec > 2 ) { if( tb.tv_sec - ta.tv_sec > 2 ) {
emit sendMsg("FileSize ("+ QString::number(digi->GetSerialNumber()) +"): " + QString::number(digi->GetData()->GetTotalFileSize()/1024./1024.) + " MB"); digiMTX[ID].lock();
emit sendMsg("FileSize ("+ QString::number(digi->GetSerialNumber()) +"): " + QString::number(digi->GetData()->GetTotalFileSize()/1024./1024., 'f', 4) + " MB [" + QString::number(tb.tv_sec-t0.tv_sec) + " sec]");
//digi->GetData()->PrintStat();
digiMTX[ID].unlock();
ta = tb; ta = tb;
} }
} }
} }while(!stop);
printf("ReadDataThread stopped.\n"); printf("ReadDataThread stopped.\n");
} }
signals: signals:
void sendMsg(const QString &msg); void sendMsg(const QString &msg);
private: private:
Digitizer * digi; Digitizer * digi;
bool stop;
int ID; int ID;
timespec ta, tb; timespec ta, tb, t1, t2, t0;
bool isSaveData; bool isSaveData;
bool isScope; bool isScope;
unsigned long readCount;
}; };
//^#======================================================= Timing Thread //^#======================================================= Timing Thread

View File

@ -13,8 +13,11 @@
#include <QRubberBand> #include <QRubberBand>
#include <QMouseEvent> #include <QMouseEvent>
#include <QGestureEvent> #include <QGestureEvent>
#include <QLineSeries>
#include <QAreaSeries>
#include <QValueAxis>
//^======================================= //^====================================================
class RSpinBox : public QDoubleSpinBox{ class RSpinBox : public QDoubleSpinBox{
Q_OBJECT Q_OBJECT
public : public :
@ -46,7 +49,7 @@ class RSpinBox : public QDoubleSpinBox{
} }
}; };
//^======================================= //^====================================================
class RComboBox : public QComboBox{ class RComboBox : public QComboBox{
public : public :
RComboBox(QWidget * parent = nullptr): QComboBox(parent){ RComboBox(QWidget * parent = nullptr): QComboBox(parent){
@ -90,6 +93,7 @@ private:
}; };
//^====================================================
class TraceView : public QChartView{ class TraceView : public QChartView{
public: public:
TraceView(QChart * chart, QWidget * parent = nullptr): QChartView(chart, parent){ TraceView(QChart * chart, QWidget * parent = nullptr): QChartView(chart, parent){
@ -101,13 +105,21 @@ public:
m_coordinateLabel->setVisible(false); m_coordinateLabel->setVisible(false);
m_coordinateLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); m_coordinateLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
setMouseTracking(true); setMouseTracking(true);
setRenderHints(QPainter::Antialiasing);
vRangeMin = -(0x1FFF);
vRangeMax = 0x1FFF;
} }
void SetHRange(int min, int max) { void SetHRange(int min, int max) {
this->hRangeMin = min; this->hRangeMin = min;
this->hRangeMax = max; this->hRangeMax = max;
}
void SetVRange(int min, int max) {
this->vRangeMin = min;
this->vRangeMax = max;
} }
protected: protected:
bool viewportEvent(QEvent *event) override{ bool viewportEvent(QEvent *event) override{
if (event->type() == QEvent::TouchBegin) { if (event->type() == QEvent::TouchBegin) {
@ -121,7 +133,6 @@ protected:
QChartView::mousePressEvent(event); QChartView::mousePressEvent(event);
} }
void mouseMoveEvent(QMouseEvent *event) override{ void mouseMoveEvent(QMouseEvent *event) override{
QPointF chartPoint = this->chart()->mapToValue(event->pos()); QPointF chartPoint = this->chart()->mapToValue(event->pos());
QString coordinateText = QString("x: %1, y: %2").arg(QString::number(chartPoint.x(), 'f', 0)).arg(QString::number(chartPoint.y(), 'f', 0)); QString coordinateText = QString("x: %1, y: %2").arg(QString::number(chartPoint.x(), 'f', 0)).arg(QString::number(chartPoint.y(), 'f', 0));
m_coordinateLabel->setText(coordinateText); m_coordinateLabel->setText(coordinateText);
@ -129,7 +140,6 @@ protected:
m_coordinateLabel->setVisible(true); m_coordinateLabel->setVisible(true);
if (m_isTouching) return; if (m_isTouching) return;
QChartView::mouseMoveEvent(event); QChartView::mouseMoveEvent(event);
} }
void mouseReleaseEvent(QMouseEvent *event) override{ void mouseReleaseEvent(QMouseEvent *event) override{
if (m_isTouching) m_isTouching = false; if (m_isTouching) m_isTouching = false;
@ -149,20 +159,126 @@ protected:
case Qt::Key_Up: chart()->scroll(0, 10); break; case Qt::Key_Up: chart()->scroll(0, 10); break;
case Qt::Key_Down: chart()->scroll(0, -10); break; case Qt::Key_Down: chart()->scroll(0, -10); break;
case Qt::Key_R : case Qt::Key_R :
chart()->axes(Qt::Vertical).first()->setRange(-(0x1FFF), 0x1FFF); //chart()->axes(Qt::Vertical).first()->setRange(-(0x1FFF), 0x1FFF);
chart()->axes(Qt::Vertical).first()->setRange(vRangeMin, vRangeMax);
//chart()->axes(Qt::Horizontal).first()->setRange(hRangeMin, hRangeMax); //chart()->axes(Qt::Horizontal).first()->setRange(hRangeMin, hRangeMax);
break; break;
default: QGraphicsView::keyPressEvent(event); break; default: QGraphicsView::keyPressEvent(event); break;
} }
} }
private: private:
bool m_isTouching; bool m_isTouching;
int hRangeMin; int hRangeMin;
int hRangeMax; int hRangeMax;
int vRangeMin;
int vRangeMax;
QLabel * m_coordinateLabel; QLabel * m_coordinateLabel;
}; };
//^====================================================
class Histogram {
public:
Histogram(QString title, double xMin, double xMax, int nBin){
plot = new Trace();
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;
}
Trace * GetTrace() { 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:
Trace * plot;
QLineSeries * dataSeries;
QAreaSeries * areaSeries;
double dX, xMin, xMax;
int nBin;
int maxBin;
int maxBinValue;
};
//^====================================================
#endif #endif

View File

@ -174,6 +174,7 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
leSaveFilePath[iDigi] = new QLineEdit(this); leSaveFilePath[iDigi] = new QLineEdit(this);
leSaveFilePath[iDigi]->setReadOnly(true); leSaveFilePath[iDigi]->setReadOnly(true);
buttonLayout->addWidget(leSaveFilePath[iDigi], rowID, 1, 1, 3); buttonLayout->addWidget(leSaveFilePath[iDigi], rowID, 1, 1, 3);
leSaveFilePath[iDigi]->setText(QString::fromStdString(digi[ID]->GetSettingFileName()));
rowID ++; //--------------------------- rowID ++; //---------------------------
bnRefreshSetting = new QPushButton("Refresh Settings", this); bnRefreshSetting = new QPushButton("Refresh Settings", this);
@ -193,7 +194,7 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
bnClearBuffer = new QPushButton("Clear Buffer/FIFO", this); bnClearBuffer = new QPushButton("Clear Buffer/FIFO", this);
buttonLayout->addWidget(bnClearBuffer, rowID, 2); buttonLayout->addWidget(bnClearBuffer, rowID, 2);
connect(bnClearBuffer, &QPushButton::clicked, this, [=](){ digi[ID]->WriteRegister(DPP::SoftwareClear_W, 1);}); connect(bnClearBuffer, &QPushButton::clicked, this, [=](){ digi[ID]->WriteRegister(DPP::SoftwareClear_W, 1); UpdateBoardAndChannelsStatus();});
bnLoadSettings = new QPushButton("Load Settings", this); bnLoadSettings = new QPushButton("Load Settings", this);
buttonLayout->addWidget(bnLoadSettings, rowID, 3); buttonLayout->addWidget(bnLoadSettings, rowID, 3);
@ -202,11 +203,11 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
rowID ++; //--------------------------- rowID ++; //---------------------------
bnSendSoftwareTriggerSignal = new QPushButton("Send SW Trigger Signal", this); bnSendSoftwareTriggerSignal = new QPushButton("Send SW Trigger Signal", this);
buttonLayout->addWidget(bnSendSoftwareTriggerSignal, rowID, 0); buttonLayout->addWidget(bnSendSoftwareTriggerSignal, rowID, 0);
connect(bnSendSoftwareTriggerSignal, &QPushButton::clicked, this, [=](){ digi[ID]->WriteRegister(DPP::SoftwareTrigger_W, 1);}); connect(bnSendSoftwareTriggerSignal, &QPushButton::clicked, this, [=](){ digi[ID]->WriteRegister(DPP::SoftwareTrigger_W, 1); UpdateBoardAndChannelsStatus();});
bnSendSoftwareClockSyncSignal = new QPushButton("Send SW Clock-Sync Signal", this); bnSendSoftwareClockSyncSignal = new QPushButton("Send SW Clock-Sync Signal", this);
buttonLayout->addWidget(bnSendSoftwareClockSyncSignal, rowID, 1); buttonLayout->addWidget(bnSendSoftwareClockSyncSignal, rowID, 1);
connect(bnSendSoftwareClockSyncSignal, &QPushButton::clicked, this, [=](){ digi[ID]->WriteRegister(DPP::SoftwareClockSync_W, 1);}); connect(bnSendSoftwareClockSyncSignal, &QPushButton::clicked, this, [=](){ digi[ID]->WriteRegister(DPP::SoftwareClockSync_W, 1); UpdateBoardAndChannelsStatus();});
bnSaveSettings = new QPushButton("Save Settings (bin)", this); bnSaveSettings = new QPushButton("Save Settings (bin)", this);
buttonLayout->addWidget(bnSaveSettings, rowID, 2); buttonLayout->addWidget(bnSaveSettings, rowID, 2);
@ -395,6 +396,14 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
}); });
cbBdReg->currentIndexChanged(0); cbBdReg->currentIndexChanged(0);
connect(cbCh, &RComboBox::currentIndexChanged, this, [=](int index){
if( !enableSignalSlot ) return;
int regIndex = cbChReg->currentIndex();
uint32_t value = digi[ cbDigi->currentIndex() ] ->ReadRegister(chRegList[regIndex], cbCh->currentIndex(), index);
leChRegValue->setText( "0x" + QString::number(value, 16).toUpper());
});
connect(cbChReg, &RComboBox::currentIndexChanged, this, [=](int index){ connect(cbChReg, &RComboBox::currentIndexChanged, this, [=](int index){
if( !enableSignalSlot ) return; if( !enableSignalSlot ) return;
@ -457,7 +466,8 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
uint32_t value = std::stoul(text.toStdString(), nullptr, 16); uint32_t value = std::stoul(text.toStdString(), nullptr, 16);
int index = cbDigi->currentIndex(); int index = cbDigi->currentIndex();
int regID = cbChReg->currentIndex(); int regID = cbChReg->currentIndex();
digi[index]->WriteRegister(chRegList[regID], value); int ch = cbCh->currentIndex();
digi[index]->WriteRegister(chRegList[regID], value, ch);
leChRegSet->setStyleSheet(""); leChRegSet->setStyleSheet("");
cbChReg->currentIndexChanged(regID); cbChReg->currentIndexChanged(regID);
@ -645,6 +655,7 @@ void DigiSettingsPanel::SetUpCheckBox(QCheckBox * &chkBox, QString label, QGridL
digi[ID]->SetBits(para, bit, state ? 1 : 0, chID); digi[ID]->SetBits(para, bit, state ? 1 : 0, chID);
if( para.IsCoupled() == true && chID >= 0 ) digi[ID]->SetBits(para, bit, state ? 1 : 0, chID%2 == 0 ? chID + 1 : chID - 1); if( para.IsCoupled() == true && chID >= 0 ) digi[ID]->SetBits(para, bit, state ? 1 : 0, chID%2 == 0 ? chID + 1 : chID - 1);
UpdatePanelFromMemory(); UpdatePanelFromMemory();
emit UpdateOtherPanels();
}); });
} }
@ -673,6 +684,7 @@ void DigiSettingsPanel::SetUpComboBoxBit(RComboBox * &cb, QString label, QGridLa
digi[ID]->SetBits(para, bit, cb->currentData().toUInt(), chID); digi[ID]->SetBits(para, bit, cb->currentData().toUInt(), chID);
if( para.IsCoupled() == true && chID >= 0 ) digi[ID]->SetBits(para, bit, cb->currentData().toUInt(), chID%2 == 0 ? chID + 1 : chID - 1); if( para.IsCoupled() == true && chID >= 0 ) digi[ID]->SetBits(para, bit, cb->currentData().toUInt(), chID%2 == 0 ? chID + 1 : chID - 1);
UpdatePanelFromMemory(); UpdatePanelFromMemory();
emit UpdateOtherPanels();
}); });
} }
@ -701,6 +713,7 @@ void DigiSettingsPanel::SetUpComboBox(RComboBox * &cb, QString label, QGridLayou
digi[ID]->WriteRegister(para, cb->currentData().toUInt(), chID); digi[ID]->WriteRegister(para, cb->currentData().toUInt(), chID);
if( para.IsCoupled() == true && chID >= 0 ) digi[ID]->WriteRegister(para, cb->currentData().toUInt(), chID%2 == 0 ? chID + 1 : chID - 1); if( para.IsCoupled() == true && chID >= 0 ) digi[ID]->WriteRegister(para, cb->currentData().toUInt(), chID%2 == 0 ? chID + 1 : chID - 1);
UpdatePanelFromMemory(); UpdatePanelFromMemory();
emit UpdateOtherPanels();
}); });
} }
@ -752,18 +765,21 @@ void DigiSettingsPanel::SetUpSpinBox(RSpinBox * &sb, QString label, QGridLayout
if( para == DPP::ChannelDCOffset ){ if( para == DPP::ChannelDCOffset ){
digi[ID]->WriteRegister(para, 0xFFFF * (1.0 - sb->value() / 100. ), chID); digi[ID]->WriteRegister(para, 0xFFFF * (1.0 - sb->value() / 100. ), chID);
UpdatePanelFromMemory(); UpdatePanelFromMemory();
emit UpdateOtherPanels();
return; return;
} }
if( para == DPP::PSD::CFDSetting ){ if( para == DPP::PSD::CFDSetting ){
digi[ID]->SetBits(para, DPP::PSD::Bit_CFDSetting::CFDDealy, sb->value()/digi[ID]->GetCh2ns(), chID); digi[ID]->SetBits(para, DPP::PSD::Bit_CFDSetting::CFDDealy, sb->value()/digi[ID]->GetCh2ns(), chID);
UpdatePanelFromMemory(); UpdatePanelFromMemory();
emit UpdateOtherPanels();
return; return;
} }
if( para == DPP::DPPAlgorithmControl ){ if( para == DPP::DPPAlgorithmControl ){
digi[ID]->SetBits(para, {5,0}, sb->value(), chID); digi[ID]->SetBits(para, {5,0}, sb->value(), chID);
UpdatePanelFromMemory(); UpdatePanelFromMemory();
emit UpdateOtherPanels();
return; return;
} }
@ -773,6 +789,7 @@ void DigiSettingsPanel::SetUpSpinBox(RSpinBox * &sb, QString label, QGridLayout
if( para.IsCoupled() == true && chID >= 0 ) digi[ID]->WriteRegister(para, bit, chID%2 == 0 ? chID + 1 : chID - 1); if( para.IsCoupled() == true && chID >= 0 ) digi[ID]->WriteRegister(para, bit, chID%2 == 0 ? chID + 1 : chID - 1);
UpdatePanelFromMemory(); UpdatePanelFromMemory();
emit UpdateOtherPanels();
}); });
} }
@ -1201,6 +1218,11 @@ void DigiSettingsPanel::SetUpChannelMask(){
bnChEnableMask[ID][i]->setStyleSheet(""); bnChEnableMask[ID][i]->setStyleSheet("");
digi[ID]->SetBits(DPP::ChannelEnableMask, {1, i}, 0, i); digi[ID]->SetBits(DPP::ChannelEnableMask, {1, i}, 0, i);
} }
if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) UpdatePHASetting();
if( digi[ID]->GetDPPType() == V1730_DPP_PSD_CODE ) UpdatePSDSetting();
emit UpdateOtherPanels();
}); });
} }
@ -2092,10 +2114,10 @@ void DigiSettingsPanel::SetUpPSDChannel(){
QLabel * lb4 = new QLabel("Local Trig. Valid. [G]", this); lb4->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb4, 0, 9); QLabel * lb4 = new QLabel("Local Trig. Valid. [G]", this); lb4->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb4, 0, 9);
} }
SetUpCheckBox(chkDisableSelfTrigger[ID][ch], "Disable Self Trigger", tabLayout, ch + 1, 1, DPP::DPPAlgorithmControl, DPP::Bit_DPPAlgorithmControl_PHA::DisableSelfTrigger, ch); SetUpCheckBox(chkDisableSelfTrigger[ID][ch], "Disable Self Trigger", tabLayout, ch + 1, 1, DPP::DPPAlgorithmControl, DPP::Bit_DPPAlgorithmControl_PHA::DisableSelfTrigger, ch);
SetUpSpinBox(sbThreshold[ID][ch], "", tabLayout, ch + 1, 2, DPP::PHA::TriggerThreshold, ch); SetUpSpinBox(sbThreshold[ID][ch], "", tabLayout, ch + 1, 2, DPP::PSD::TriggerThreshold, ch);
SetUpComboBoxBit(cbTrigMode[ID][ch], "", tabLayout, ch + 1, 4, DPP::Bit_DPPAlgorithmControl_PHA::ListTrigMode, DPP::DPPAlgorithmControl, DPP::Bit_DPPAlgorithmControl_PHA::TriggerMode, 1, ch); SetUpComboBoxBit(cbTrigMode[ID][ch], "", tabLayout, ch + 1, 4, DPP::Bit_DPPAlgorithmControl_PHA::ListTrigMode, DPP::DPPAlgorithmControl, DPP::Bit_DPPAlgorithmControl_PHA::TriggerMode, 1, ch);
SetUpSpinBox(sbTriggerHoldOff[ID][ch], "", tabLayout, ch + 1, 6, DPP::PHA::TriggerHoldOffWidth, ch); SetUpSpinBox(sbTriggerHoldOff[ID][ch], "", tabLayout, ch + 1, 6, DPP::PSD::TriggerHoldOffWidth, ch);
SetUpComboBoxBit(cbLocalTriggerValid[ID][ch], "", tabLayout, ch + 1, 8, DPP::PHA::Bit_DPPAlgorithmControl2::ListLocalTrigValidMode, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::LocalTrigValidMode, 1, ch); SetUpComboBoxBit(cbLocalTriggerValid[ID][ch], "", tabLayout, ch + 1, 8, DPP::PSD::Bit_DPPAlgorithmControl2::ListLocalTrigValidMode, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::LocalTrigValidMode, 1, ch);
} }
if( i == 1 ){ if( i == 1 ){
@ -2105,9 +2127,8 @@ void DigiSettingsPanel::SetUpPSDChannel(){
QLabel * lb1 = new QLabel("Trig. Counter Flag [G]", this); lb1->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb1, 0, 6); QLabel * lb1 = new QLabel("Trig. Counter Flag [G]", this); lb1->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb1, 0, 6);
} }
SetUpSpinBox(sbShapedTrigWidth[ID][ch], "", tabLayout, ch + 1, 1, DPP::PSD::ShapedTriggerWidth, ch); SetUpSpinBox(sbShapedTrigWidth[ID][ch], "", tabLayout, ch + 1, 1, DPP::PSD::ShapedTriggerWidth, ch);
SetUpComboBoxBit(cbLocalShapedTrigger[ID][ch], "", tabLayout, ch + 1, 3, DPP::PHA::Bit_DPPAlgorithmControl2::ListLocalShapeTrigMode, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::LocalShapeTriggerMode, 1, ch); SetUpComboBoxBit(cbLocalShapedTrigger[ID][ch], "", tabLayout, ch + 1, 3, DPP::PSD::Bit_DPPAlgorithmControl2::ListLocalShapeTrigMode, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::LocalShapeTriggerMode, 1, ch);
SetUpComboBoxBit(cbTrigCount[ID][ch], "", tabLayout, ch + 1, 5, DPP::PHA::Bit_DPPAlgorithmControl2::ListTrigCounter, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::TriggerCounterFlag, 1, ch); SetUpComboBoxBit(cbTrigCount[ID][ch], "", tabLayout, ch + 1, 5, DPP::PSD::Bit_DPPAlgorithmControl2::ListTrigCounter, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::TriggerCounterFlag, 1, ch);
} }
if( i == 2 ){ if( i == 2 ){
@ -2214,7 +2235,7 @@ void DigiSettingsPanel::SetUpPSDChannel(){
QTabWidget * othersTab = new QTabWidget(this); QTabWidget * othersTab = new QTabWidget(this);
otherLayout->addWidget(othersTab); otherLayout->addWidget(othersTab);
QStringList tabName = {"Tab-1", "Test Pulse", "Veto", "Extra2"}; QStringList tabName = {"Tab-1", "Test Pulse", "Veto", "Extra"};
const int nTab = tabName.count(); const int nTab = tabName.count();
@ -2273,7 +2294,7 @@ void DigiSettingsPanel::SetUpPSDChannel(){
if( i == 3 ){ if( i == 3 ){
if( ch == 0 ){ if( ch == 0 ){
QLabel * lb2 = new QLabel("Extra2 Option [G]", this); lb2->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb2, 0, 2); QLabel * lb2 = new QLabel("Extra Option [G]", this); lb2->setAlignment(Qt::AlignHCenter); tabLayout->addWidget(lb2, 0, 2);
} }
SetUpComboBoxBit(cbExtra2Option[ID][ch], "", tabLayout, ch + 1, 1, DPP::PHA::Bit_DPPAlgorithmControl2::ListExtra2, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::Extra2Option, 2, ch); SetUpComboBoxBit(cbExtra2Option[ID][ch], "", tabLayout, ch + 1, 1, DPP::PHA::Bit_DPPAlgorithmControl2::ListExtra2, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::Extra2Option, 2, ch);
} }
@ -2370,8 +2391,6 @@ void DigiSettingsPanel::UpdatePanelFromMemory(){
chkTraceRecording[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::RecordTrace) ); chkTraceRecording[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::RecordTrace) );
chkEnableExtra2[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::EnableExtra2) ); chkEnableExtra2[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::EnableExtra2) );
if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) { if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) {
chkDecimateTrace[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::DecimateTrace) ); chkDecimateTrace[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::DecimateTrace) );
chkDualTrace[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::DualTrace) ); chkDualTrace[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::DualTrace) );
@ -2553,8 +2572,6 @@ void DigiSettingsPanel::UpdatePanelFromMemory(){
} }
} }
if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) UpdatePHASetting(); if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) UpdatePHASetting();
if( digi[ID]->GetDPPType() == V1730_DPP_PSD_CODE ) UpdatePSDSetting(); if( digi[ID]->GetDPPType() == V1730_DPP_PSD_CODE ) UpdatePSDSetting();
@ -2632,6 +2649,8 @@ void DigiSettingsPanel::SyncSpinBox(RSpinBox *(&spb)[][MaxNChannels+1]){
const int value = spb[ID][0]->value(); const int value = spb[ID][0]->value();
for( int i = 1; i < nCh; i ++){ for( int i = 1; i < nCh; i ++){
if( spb[ID][i]->value() == value ) count++; if( spb[ID][i]->value() == value ) count++;
spb[ID][i]->setEnabled(bnChEnableMask[ID][i]->styleSheet() == "" ? false : true );
} }
//printf("%d =? %d , %d, %f\n", count, nCh, value, spb[ID][0]->value()); //printf("%d =? %d , %d, %f\n", count, nCh, value, spb[ID][0]->value());
@ -2663,6 +2682,7 @@ void DigiSettingsPanel::SyncComboBox(RComboBox *(&cb)[][MaxNChannels+1]){
const QString text = cb[ID][0]->currentText(); const QString text = cb[ID][0]->currentText();
for( int i = 1; i < nCh; i ++){ for( int i = 1; i < nCh; i ++){
if( cb[ID][i]->currentText() == text ) count++; if( cb[ID][i]->currentText() == text ) count++;
cb[ID][i]->setEnabled(bnChEnableMask[ID][i]->styleSheet() == "" ? false : true );
} }
//printf("%d =? %d , %s\n", count, nCh, text.toStdString().c_str()); //printf("%d =? %d , %s\n", count, nCh, text.toStdString().c_str());
@ -2691,6 +2711,7 @@ void DigiSettingsPanel::SyncCheckBox(QCheckBox *(&chk)[][MaxNChannels+1]){
const Qt::CheckState state = chk[ID][0]->checkState(); const Qt::CheckState state = chk[ID][0]->checkState();
for( int i = 1; i < nCh; i ++){ for( int i = 1; i < nCh; i ++){
if( chk[ID][i]->checkState() == state ) count++; if( chk[ID][i]->checkState() == state ) count++;
chk[ID][i]->setEnabled(bnChEnableMask[ID][i]->styleSheet() == "" ? false : true );
} }
//printf("%d =? %d , %s\n", count, nCh, text.toStdString().c_str()); //printf("%d =? %d , %s\n", count, nCh, text.toStdString().c_str());
@ -2753,7 +2774,7 @@ void DigiSettingsPanel::UpdatePHASetting(){
enableSignalSlot = false; enableSignalSlot = false;
printf("------ %s \n", __func__); //printf("------ %s \n", __func__);
for( int ch = 0; ch < digi[ID]->GetNChannels(); ch ++){ for( int ch = 0; ch < digi[ID]->GetNChannels(); ch ++){
UpdateSpinBox(sbRecordLength[ID][ch], DPP::RecordLength_G, ch); UpdateSpinBox(sbRecordLength[ID][ch], DPP::RecordLength_G, ch);
@ -2805,8 +2826,8 @@ void DigiSettingsPanel::UpdatePHASetting(){
uint32_t vetoBit = digi[ID]->GetSettingFromMemory(DPP::VetoWidth, ch); uint32_t vetoBit = digi[ID]->GetSettingFromMemory(DPP::VetoWidth, ch);
UpdateComboBoxBit(cbVetoStep[ID][ch], vetoBit, DPP::Bit_VetoWidth::VetoStep); UpdateComboBoxBit(cbVetoStep[ID][ch], vetoBit, DPP::Bit_VetoWidth::VetoStep);
}
}
enableSignalSlot = true; enableSignalSlot = true;
@ -2870,13 +2891,12 @@ void DigiSettingsPanel::SyncAllChannelsTab_PSD(){
SyncComboBox(cbVetoMode); SyncComboBox(cbVetoMode);
SyncComboBox(cbVetoStep); SyncComboBox(cbVetoStep);
} }
void DigiSettingsPanel::UpdatePSDSetting(){ void DigiSettingsPanel::UpdatePSDSetting(){
enableSignalSlot = false; enableSignalSlot = false;
printf("------ %s \n", __func__); //printf("------ %s \n", __func__);
for(int ch = 0; ch < digi[ID]->GetNChannels(); ch ++){ for(int ch = 0; ch < digi[ID]->GetNChannels(); ch ++){

View File

@ -21,7 +21,7 @@ public:
DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr); DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr);
~DigiSettingsPanel(); ~DigiSettingsPanel();
private slots: public slots:
void UpdatePanelFromMemory(); void UpdatePanelFromMemory();
void ReadSettingsFromBoard(); void ReadSettingsFromBoard();
@ -30,6 +30,7 @@ private slots:
signals: signals:
void SendLogMsg(const QString &msg); void SendLogMsg(const QString &msg);
void UpdateOtherPanels();
private: private:
@ -68,7 +69,6 @@ private:
void CheckRadioAndCheckedButtons(); void CheckRadioAndCheckedButtons();
Digitizer ** digi; Digitizer ** digi;
unsigned int nDigi; unsigned int nDigi;
unsigned short ID; unsigned short ID;

View File

@ -12,10 +12,6 @@
#include <QFileDialog> #include <QFileDialog>
#include <QScrollArea> #include <QScrollArea>
#include <TH1.h>
#include "CustomWidgets.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
setWindowTitle("FSU DAQ"); setWindowTitle("FSU DAQ");
@ -27,6 +23,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
scalar = nullptr; scalar = nullptr;
scope = nullptr; scope = nullptr;
digiSettings = nullptr; digiSettings = nullptr;
canvas = nullptr;
QWidget * mainLayoutWidget = new QWidget(this); QWidget * mainLayoutWidget = new QWidget(this);
setCentralWidget(mainLayoutWidget); setCentralWidget(mainLayoutWidget);
@ -43,16 +40,92 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
connect(bnOpenDigitizers, &QPushButton::clicked, this, &MainWindow::OpenDigitizers); connect(bnOpenDigitizers, &QPushButton::clicked, this, &MainWindow::OpenDigitizers);
bnCloseDigitizers = new QPushButton("Close Digitizers", this); bnCloseDigitizers = new QPushButton("Close Digitizers", this);
layout->addWidget(bnCloseDigitizers, 0, 1); layout->addWidget(bnCloseDigitizers, 1, 0);
connect(bnCloseDigitizers, &QPushButton::clicked, this, &MainWindow::CloseDigitizers); connect(bnCloseDigitizers, &QPushButton::clicked, this, &MainWindow::CloseDigitizers);
bnDigiSettings = new QPushButton("Digitizers Settings", this);
layout->addWidget(bnDigiSettings, 0, 1);
connect(bnDigiSettings, &QPushButton::clicked, this, &MainWindow::OpenDigiSettings);
bnOpenScope = new QPushButton("Open Scope", this); bnOpenScope = new QPushButton("Open Scope", this);
layout->addWidget(bnOpenScope, 1, 0); layout->addWidget(bnOpenScope, 1, 1);
connect(bnOpenScope, &QPushButton::clicked, this, &MainWindow::OpenScope); connect(bnOpenScope, &QPushButton::clicked, this, &MainWindow::OpenScope);
bnDigiSettings = new QPushButton("Digitizers Settings", this); bnCanvas = new QPushButton("Online 1D Histograms", this);
layout->addWidget(bnDigiSettings, 1, 1); layout->addWidget(bnCanvas, 1, 2);
connect(bnDigiSettings, &QPushButton::clicked, this, &MainWindow::OpenDigiSettings); connect(bnCanvas, &QPushButton::clicked, this, &MainWindow::OpenCanvas);
}
{//^====================== influx and Elog
QGroupBox * otherBox = new QGroupBox("Misc.", mainLayoutWidget);
layoutMain->addWidget(otherBox);
QGridLayout * layout = new QGridLayout(otherBox);
layout->setSpacing(2);
QLabel * lbInfluxIP = new QLabel("Influx IP : ", this);
lbInfluxIP->setAlignment(Qt::AlignRight | Qt::AlignCenter);
layout->addWidget(lbInfluxIP, 0, 0);
leInfluxIP = new QLineEdit(this);
leInfluxIP->setReadOnly(true);
layout->addWidget(leInfluxIP, 0, 1);
QLabel * lbDatabaseName = new QLabel("Database Name : ", this);
lbDatabaseName->setAlignment(Qt::AlignRight | Qt::AlignCenter);
layout->addWidget(lbDatabaseName, 0, 2);
leDatabaseName = new QLineEdit(this);
leDatabaseName->setReadOnly(true);
layout->addWidget(leDatabaseName, 0, 3);
QLabel * lbElogIP = new QLabel("Elog IP : ", this);
lbElogIP->setAlignment(Qt::AlignRight | Qt::AlignCenter);
layout->addWidget(lbElogIP, 1, 0);
leElogIP = new QLineEdit(this);
leElogIP->setReadOnly(true);
layout->addWidget(leElogIP, 1, 1);
bnLock = new QPushButton("Unlock", this);
bnLock->setChecked(true);
layout->addWidget(bnLock, 1, 3);
connect(bnLock, &QPushButton::clicked, this, [=](){
if( leInfluxIP->isReadOnly() ){
bnLock->setText("Lock and Set");
leInfluxIP->setReadOnly(false);
leDatabaseName->setReadOnly(false);
leElogIP->setReadOnly(false);
leInfluxIP->setStyleSheet("color : blue;");
leDatabaseName->setStyleSheet("color : blue;");
leElogIP->setStyleSheet("color : blue;");
}else{
bnLock->setText("Unlock");
leInfluxIP->setReadOnly(true);
leDatabaseName->setReadOnly(true);
leElogIP->setReadOnly(true);
leInfluxIP->setStyleSheet("");
leDatabaseName->setStyleSheet("");
leElogIP->setStyleSheet("");
influxIP = leInfluxIP->text();
dataBaseName = leDatabaseName->text();
elogIP = leElogIP->text();
SaveProgramSettings();
SetUpInflux();
}
});
} }
@ -88,7 +161,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
leRunID->setAlignment(Qt::AlignHCenter); leRunID->setAlignment(Qt::AlignHCenter);
chkSaveData = new QCheckBox("Save Data", this); chkSaveData = new QCheckBox("Save Data", this);
cbAutoRun = new QComboBox(this); cbAutoRun = new RComboBox(this);
cbAutoRun->addItem("Single Infinite", 0); cbAutoRun->addItem("Single Infinite", 0);
cbAutoRun->addItem("Single 30 mins", 30); cbAutoRun->addItem("Single 30 mins", 30);
cbAutoRun->addItem("Single 60 mins", 60); cbAutoRun->addItem("Single 60 mins", 60);
@ -145,7 +218,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
layoutMain->setStretchFactor(box3, 1); layoutMain->setStretchFactor(box3, 1);
QVBoxLayout * layout3 = new QVBoxLayout(box3); QVBoxLayout * layout3 = new QVBoxLayout(box3);
logInfo = new QPlainTextEdit(this); logInfo = new QPlainTextEdit(this);
logInfo->isReadOnly(); logInfo->setReadOnly(true);
QFont font; QFont font;
font.setFamily("Courier New"); font.setFamily("Courier New");
logInfo->setFont(font); logInfo->setFont(font);
@ -165,6 +238,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
//=========== disable widget //=========== disable widget
WaitForDigitizersOpen(true); WaitForDigitizersOpen(true);
SetUpInflux();
} }
MainWindow::~MainWindow(){ MainWindow::~MainWindow(){
@ -176,6 +251,8 @@ MainWindow::~MainWindow(){
if( digiSettings ) delete digiSettings; if( digiSettings ) delete digiSettings;
if( canvas ) delete canvas;
if( scalar ) { if( scalar ) {
CleanUpScalar(); CleanUpScalar();
scalarThread->Stop(); scalarThread->Stop();
@ -184,6 +261,8 @@ MainWindow::~MainWindow(){
delete scalarThread; delete scalarThread;
} }
delete influx;
} }
//*************************************************************** //***************************************************************
@ -201,6 +280,8 @@ void MainWindow::OpenDataPath(){
leDataPath->clear(); leDataPath->clear();
} }
SaveProgramSettings();
} }
void MainWindow::LoadProgramSettings(){ void MainWindow::LoadProgramSettings(){
@ -220,12 +301,19 @@ void MainWindow::LoadProgramSettings(){
if( line.left(6) == "//----") break; if( line.left(6) == "//----") break;
if( count == 0 ) rawDataPath = line; if( count == 0 ) rawDataPath = line;
if( count == 1 ) influxIP = line;
if( count == 2 ) dataBaseName = line;
if( count == 3 ) elogIP = line;
count ++; count ++;
line = in.readLine(); line = in.readLine();
} }
//looking for the lastRun.sh for //looking for the lastRun.sh for
leDataPath->setText(rawDataPath); leDataPath->setText(rawDataPath);
leInfluxIP->setText(influxIP);
leDatabaseName->setText(dataBaseName);
leElogIP->setText(elogIP);
//check is rawDataPath exist, if not, create one //check is rawDataPath exist, if not, create one
QDir rawDataDir; QDir rawDataDir;
@ -252,7 +340,10 @@ void MainWindow::SaveProgramSettings(){
file.open(QIODevice::Text | QIODevice::WriteOnly); file.open(QIODevice::Text | QIODevice::WriteOnly);
file.write((rawDataPath+"\n").toStdString().c_str()); file.write((rawDataPath+"\n").toStdString().c_str());
file.write("//------------end of file."); file.write((influxIP+"\n").toStdString().c_str());
file.write((dataBaseName+"\n").toStdString().c_str());
file.write((elogIP+"\n").toStdString().c_str());
file.write("//------------end of file.\n");
file.close(); file.close();
LogMsg("Saved program settings to <b>"+ programSettingsFilePath + "<b>."); LogMsg("Saved program settings to <b>"+ programSettingsFilePath + "<b>.");
@ -390,6 +481,14 @@ void MainWindow::OpenDigitizers(){
QCoreApplication::processEvents(); //to prevent Qt said application not responding. QCoreApplication::processEvents(); //to prevent Qt said application not responding.
} }
canvas = new Canvas(digi, nDigi);
histThread = new TimingThread(this);
histThread->SetWaitTimeinSec(0.5);
connect(histThread, &TimingThread::timeUp, this, [=](){
if( canvas == nullptr ) return;
canvas->UpdateCanvas();
});
LogMsg(QString("Done. Opened %1 digitizer(s).").arg(nDigi)); LogMsg(QString("Done. Opened %1 digitizer(s).").arg(nDigi));
WaitForDigitizersOpen(false); WaitForDigitizersOpen(false);
@ -422,6 +521,13 @@ void MainWindow::CloseDigitizers(){
for(unsigned int i = 0; i < nDigi; i ++){ for(unsigned int i = 0; i < nDigi; i ++){
digi[i]->CloseDigitizer(); digi[i]->CloseDigitizer();
delete digi[i]; delete digi[i];
if(readDataThread[i]->isRunning()){
readDataThread[i]->Stop();
readDataThread[i]->quit();
readDataThread[i]->wait();
}
delete readDataThread[i]; delete readDataThread[i];
} }
delete [] digi; delete [] digi;
@ -447,6 +553,7 @@ void MainWindow::WaitForDigitizersOpen(bool onOff){
bnStartACQ->setEnabled(!onOff); bnStartACQ->setEnabled(!onOff);
bnStopACQ->setEnabled(!onOff); bnStopACQ->setEnabled(!onOff);
chkSaveData->setEnabled(!onOff); chkSaveData->setEnabled(!onOff);
bnCanvas->setEnabled(!onOff);
} }
@ -478,7 +585,7 @@ void MainWindow::SetupScalar(){
scalarThread = new TimingThread(); scalarThread = new TimingThread();
connect(scalarThread, &TimingThread::timeUp, this, &MainWindow::UpdateScalar); connect(scalarThread, &TimingThread::timeUp, this, &MainWindow::UpdateScalar);
scalar->setGeometry(0, 0, 10 + nDigi * 200, 110 + MaxNChannels * 25); scalar->setGeometry(0, 0, 10 + nDigi * 200, 110 + MaxNChannels * 20);
if( lbLastUpdateTime == nullptr ){ if( lbLastUpdateTime == nullptr ){
lbLastUpdateTime = new QLabel("Last update : NA", scalar); lbLastUpdateTime = new QLabel("Last update : NA", scalar);
@ -515,6 +622,7 @@ void MainWindow::SetupScalar(){
rowID = 2; rowID = 2;
leTrigger[iDigi] = new QLineEdit *[digi[iDigi]->GetNChannels()]; leTrigger[iDigi] = new QLineEdit *[digi[iDigi]->GetNChannels()];
leAccept[iDigi] = new QLineEdit *[digi[iDigi]->GetNChannels()]; leAccept[iDigi] = new QLineEdit *[digi[iDigi]->GetNChannels()];
uint32_t chMask = digi[iDigi]->GetChannelMask();
for( int ch = 0; ch < MaxNChannels; ch++){ for( int ch = 0; ch < MaxNChannels; ch++){
if( ch == 0 ){ if( ch == 0 ){
@ -533,7 +641,6 @@ void MainWindow::SetupScalar(){
} }
rowID ++; rowID ++;
leTrigger[iDigi][ch] = new QLineEdit(scalar); leTrigger[iDigi][ch] = new QLineEdit(scalar);
leTrigger[iDigi][ch]->setReadOnly(true); leTrigger[iDigi][ch]->setReadOnly(true);
leTrigger[iDigi][ch]->setAlignment(Qt::AlignRight); leTrigger[iDigi][ch]->setAlignment(Qt::AlignRight);
@ -543,6 +650,10 @@ void MainWindow::SetupScalar(){
leAccept[iDigi][ch]->setReadOnly(true); leAccept[iDigi][ch]->setReadOnly(true);
leAccept[iDigi][ch]->setAlignment(Qt::AlignRight); leAccept[iDigi][ch]->setAlignment(Qt::AlignRight);
leAccept[iDigi][ch]->setStyleSheet("background-color: #F0F0F0;"); leAccept[iDigi][ch]->setStyleSheet("background-color: #F0F0F0;");
leTrigger[iDigi][ch]->setEnabled( (chMask >> ch) & 0x1 );
leAccept[iDigi][ch]->setEnabled( (chMask >> ch) & 0x1 );
scalarLayout->addWidget(leAccept[iDigi][ch], rowID, 2*iDigi+2); scalarLayout->addWidget(leAccept[iDigi][ch], rowID, 2*iDigi+2);
} }
} }
@ -584,17 +695,31 @@ void MainWindow::OpenScalar(){
void MainWindow::UpdateScalar(){ void MainWindow::UpdateScalar(){
if( digi == nullptr ) return; if( digi == nullptr ) return;
if( scalar == nullptr ) return; if( scalar == nullptr ) return;
if( !scalar->isVisible() ) return; //if( !scalar->isVisible() ) return;
lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss")); lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss"));
//printf("----------------------\n");
for( unsigned int iDigi = 0; iDigi < nDigi; iDigi++){ for( unsigned int iDigi = 0; iDigi < nDigi; iDigi++){
Data * data = digi[iDigi]->GetData(); digiMTX[iDigi].lock();
for( int i = 0; i < digi[iDigi]->GetNChannels(); i++){ for( int i = 0; i < digi[iDigi]->GetNChannels(); i++){
leTrigger[iDigi][i]->setText(QString::number(data->TriggerRate[i])); if( digi[iDigi]->GetChannelOnOff(i) == true ) {
leAccept[iDigi][i]->setText(QString::number(data->NonPileUpRate[i])); //printf(" %3d %2d | %7.2f %7.2f \n", digi[iDigi]->GetSerialNumber(), i, digi[iDigi]->GetData()->TriggerRate[i], digi[iDigi]->GetData()->NonPileUpRate[i]);
leTrigger[iDigi][i]->setText(QString::number(digi[iDigi]->GetData()->TriggerRate[i], 'f', 2));
leAccept[iDigi][i]->setText(QString::number(digi[iDigi]->GetData()->NonPileUpRate[i], 'f', 2));
if( influx ){
influx->AddDataPoint("Rate,Bd="+std::to_string(digi[iDigi]->GetSerialNumber()) + ",Ch=" + QString::number(i).rightJustified(2, '0').toStdString() + " value=" + QString::number(digi[iDigi]->GetData()->TriggerRate[i], 'f', 2).toStdString());
}
}
} }
digiMTX[iDigi].unlock();
}
if( influx ){
influx->WriteData(dataBaseName.toStdString());
influx->ClearDataPointsBuffer();
} }
} }
@ -609,7 +734,11 @@ void MainWindow::StartACQ(){
if( chkSaveData->isChecked() ) commentResult = CommentDialog(true); if( chkSaveData->isChecked() ) commentResult = CommentDialog(true);
if( commentResult == false) return; if( commentResult == false) return;
LogMsg("===================== Start a new Run-" + QString::number(runID)); if( chkSaveData->isChecked() ) {
LogMsg("<font style=\"color: orange;\">===================== <b>Start a new Run-" + QString::number(runID) + "</b></font>");
}else{
LogMsg("<font style=\"color: orange;\">===================== <b>Start a non-save Run</b></font>");
}
for( unsigned int i = 0; i < nDigi ; i++){ for( unsigned int i = 0; i < nDigi ; i++){
if( chkSaveData->isChecked() ) { if( chkSaveData->isChecked() ) {
@ -620,10 +749,13 @@ void MainWindow::StartACQ(){
} }
readDataThread[i]->SetSaveData(chkSaveData->isChecked()); readDataThread[i]->SetSaveData(chkSaveData->isChecked());
LogMsg("Digi-" + QString::number(digi[i]->GetSerialNumber()) + " is starting ACQ." ); LogMsg("Digi-" + QString::number(digi[i]->GetSerialNumber()) + " is starting ACQ." );
digi[i]->WriteRegister(DPP::SoftwareClear_W, 1);
digi[i]->GetData()->SetSaveWaveToMemory(false);
digi[i]->StartACQ(); digi[i]->StartACQ();
readDataThread[i]->start(); readDataThread[i]->start();
} }
if( chkSaveData->isChecked() ) SaveLastRunFile(); if( chkSaveData->isChecked() ) SaveLastRunFile();
scalarThread->start(); scalarThread->start();
if( !scalar->isVisible() ) { if( !scalar->isVisible() ) {
@ -633,6 +765,8 @@ void MainWindow::StartACQ(){
} }
lbScalarACQStatus->setText("<font style=\"color: green;\"><b>ACQ On</b></font>"); lbScalarACQStatus->setText("<font style=\"color: green;\"><b>ACQ On</b></font>");
if( canvas != nullptr ) histThread->start();
bnStartACQ->setEnabled(false); bnStartACQ->setEnabled(false);
bnStopACQ->setEnabled(true); bnStopACQ->setEnabled(true);
bnOpenScope->setEnabled(false); bnOpenScope->setEnabled(false);
@ -641,21 +775,28 @@ void MainWindow::StartACQ(){
void MainWindow::StopACQ(){ void MainWindow::StopACQ(){
if( digi == nullptr ) return; if( digi == nullptr ) return;
LogMsg("===================== Stop Run-" + QString::number(runID));
bool commentResult = true; bool commentResult = true;
if( chkSaveData->isChecked() ) commentResult = CommentDialog(true); if( chkSaveData->isChecked() ) commentResult = CommentDialog(true);
if( commentResult == false) return; if( commentResult == false) return;
if( chkSaveData->isChecked() ) {
LogMsg("===================== Stop Run-" + QString::number(runID));
}else{
LogMsg("===================== Stop a non-save Run");
}
for( unsigned int i = 0; i < nDigi; i++){ for( unsigned int i = 0; i < nDigi; i++){
LogMsg("Digi-" + QString::number(digi[i]->GetSerialNumber()) + " is stoping ACQ." ); LogMsg("Digi-" + QString::number(digi[i]->GetSerialNumber()) + " is stoping ACQ." );
digi[i]->StopACQ();
if( chkSaveData->isChecked() ) digi[i]->GetData()->CloseSaveFile();
if( readDataThread[i]->isRunning() ) { if( readDataThread[i]->isRunning() ) {
readDataThread[i]->Stop();
readDataThread[i]->quit(); readDataThread[i]->quit();
readDataThread[i]->wait(); readDataThread[i]->wait();
} }
digiMTX[i].lock();
digi[i]->StopACQ();
digiMTX[i].unlock();
if( chkSaveData->isChecked() ) digi[i]->GetData()->CloseSaveFile();
} }
if( scalarThread->isRunning()){ if( scalarThread->isRunning()){
@ -663,6 +804,12 @@ void MainWindow::StopACQ(){
scalarThread->quit(); scalarThread->quit();
scalarThread->wait(); scalarThread->wait();
} }
if( histThread->isRunning()){
histThread->Stop();
histThread->quit();
histThread->wait();
}
lbScalarACQStatus->setText("<font style=\"color: red;\"><b>ACQ Off</b></font>"); lbScalarACQStatus->setText("<font style=\"color: red;\"><b>ACQ Off</b></font>");
@ -671,7 +818,7 @@ void MainWindow::StopACQ(){
bnOpenScope->setEnabled(true); bnOpenScope->setEnabled(true);
} }
void MainWindow::AutoRun(){ void MainWindow::AutoRun(){ //TODO
} }
@ -783,15 +930,31 @@ void MainWindow::OpenScope(){
bnStopACQ->setEnabled(false); bnStopACQ->setEnabled(false);
}); });
connect(scope, &Scope::TellACQOnOff, this, [=](bool onOff){ connect(scope, &Scope::TellACQOnOff, this, [=](bool onOff){
if( scope == nullptr ) return; if( scope ) {
if( onOff ) { if( onOff ) {
lbScalarACQStatus->setText("<font style=\"color: green;\"><b>ACQ On</b></font>"); lbScalarACQStatus->setText("<font style=\"color: green;\"><b>ACQ On</b></font>");
}else{ }else{
lbScalarACQStatus->setText("<font style=\"color: red;\"><b>ACQ Off</b></font>"); lbScalarACQStatus->setText("<font style=\"color: red;\"><b>ACQ Off</b></font>");
}
}
if( canvas ){
if( onOff ) {
histThread->start();
}else{
if( histThread->isRunning()){
histThread->Stop();
histThread->quit();
histThread->wait();
}
}
} }
}); });
connect(scope, &Scope::UpdateScaler, this, &MainWindow::UpdateScalar); connect(scope, &Scope::UpdateScaler, this, &MainWindow::UpdateScalar);
connect(scope, &Scope::UpdateOtherPanels, this, [=](){ UpdateAllPanels(1); });
scope->show(); scope->show();
}else{ }else{
scope->show(); scope->show();
@ -801,6 +964,8 @@ void MainWindow::OpenScope(){
bnStartACQ->setEnabled(false); bnStartACQ->setEnabled(false);
bnStopACQ->setEnabled(false); bnStopACQ->setEnabled(false);
chkSaveData->setChecked(false);
} }
//*************************************************************** //***************************************************************
@ -810,6 +975,8 @@ void MainWindow::OpenDigiSettings(){
if( digiSettings == nullptr ) { if( digiSettings == nullptr ) {
digiSettings = new DigiSettingsPanel(digi, nDigi, rawDataPath); digiSettings = new DigiSettingsPanel(digi, nDigi, rawDataPath);
//connect(scope, &Scope::SendLogMsg, this, &MainWindow::LogMsg); //connect(scope, &Scope::SendLogMsg, this, &MainWindow::LogMsg);
connect(digiSettings, &DigiSettingsPanel::UpdateOtherPanels, this, [=](){ UpdateAllPanels(2); });
digiSettings->show(); digiSettings->show();
}else{ }else{
digiSettings->show(); digiSettings->show();
@ -818,6 +985,94 @@ void MainWindow::OpenDigiSettings(){
} }
//***************************************************************
//***************************************************************
void MainWindow::OpenCanvas(){
if( canvas == nullptr ) {
canvas = new Canvas(digi, nDigi);
canvas->show();
}else{
canvas->show();
canvas->activateWindow();
}
}
//***************************************************************
//***************************************************************
void MainWindow::UpdateAllPanels(int panelID){
//panelID is the source panel that call
// scope = 1;
// digiSetting = 2;
if( panelID == 1 ){ // from scope
if( digiSettings && digiSettings->isVisible() ) digiSettings->UpdatePanelFromMemory();
}
if( panelID == 2 ){
if(scope && scope->isVisible() ) scope->UpdatePanelFromMomeory();
if(scalar) {
for( unsigned int iDigi = 0; iDigi < nDigi; iDigi++){
uint32_t chMask = digi[iDigi]->GetChannelMask();
for( int i = 0; i < digi[iDigi]->GetNChannels(); i++){
leTrigger[iDigi][i]->setEnabled( (chMask >> i) & 0x1 );
leAccept[iDigi][i]->setEnabled( (chMask >> i) & 0x1 );
}
}
}
}
}
//***************************************************************
//***************************************************************
void MainWindow::SetUpInflux(){
if( influxIP == "" ) return;
if( influx ) {
delete influx;
influx = nullptr;
}
influx = new InfluxDB(influxIP.toStdString(), false);
if( influx->TestingConnection() ){
LogMsg("<font style=\"color : green;\"> InfluxDB URL (<b>"+ influxIP + "</b>) is Valid </font>");
//==== chck database exist
//LogMsg("List of database:");
std::vector<std::string> databaseList = influx->GetDatabaseList();
bool foundDatabase = false;
for( int i = 0; i < (int) databaseList.size(); i++){
if( databaseList[i] == dataBaseName.toStdString() ) foundDatabase = true;
//LogMsg(QString::number(i) + "|" + QString::fromStdString(databaseList[i]));
}
if( foundDatabase ){
LogMsg("<font style=\"color : green;\"> Database <b>" + dataBaseName + "</b> found.");
influx->AddDataPoint("ProgramStart value=1");
influx->WriteData(dataBaseName.toStdString());
influx->ClearDataPointsBuffer();
if( influx->IsWriteOK() ){
LogMsg("<font style=\"color : green;\">test write database OK.</font>");
}else{
LogMsg("<font style=\"color : red;\">test write database FAIL.</font>");
}
}else{
LogMsg("<font style=\"color : red;\"> Database <b>" + dataBaseName + "</b> NOT found.");
delete influx;
influx = nullptr;
}
}else{
LogMsg("<font style=\"color : red;\"> InfluxDB URL (<b>"+ influxIP + "</b>) is NOT Valid </font>");
delete influx;
influx = nullptr;
}
}
//*************************************************************** //***************************************************************
//*************************************************************** //***************************************************************
void MainWindow::LogMsg(QString msg){ void MainWindow::LogMsg(QString msg){
@ -829,6 +1084,6 @@ void MainWindow::LogMsg(QString msg){
} }
QScrollBar *v = logInfo->verticalScrollBar(); QScrollBar *v = logInfo->verticalScrollBar();
v->setValue(v->maximum()); v->setValue(v->maximum());
//qDebug() << msg; qDebug() << outputStr;
logInfo->repaint(); logInfo->repaint();
} }

View File

@ -13,8 +13,11 @@
#include "ClassDigitizer.h" #include "ClassDigitizer.h"
#include "CustomThreads.h" #include "CustomThreads.h"
#include "CustomWidgets.h"
#include "Scope.h" #include "Scope.h"
#include "DigiSettingsPanel.h" #include "DigiSettingsPanel.h"
#include "CanvasClass.h"
#include "influxdb.h"
//^#===================================================== MainWindow //^#===================================================== MainWindow
class MainWindow : public QMainWindow{ class MainWindow : public QMainWindow{
@ -26,6 +29,7 @@ public:
void closeEvent(QCloseEvent * event){ void closeEvent(QCloseEvent * event){
if( scope ) scope->close(); if( scope ) scope->close();
if( digiSettings ) digiSettings->close(); if( digiSettings ) digiSettings->close();
if( canvas ) canvas->close();
event->accept(); event->accept();
} }
@ -56,6 +60,12 @@ private slots:
void OpenDigiSettings(); void OpenDigiSettings();
void OpenCanvas();
void UpdateAllPanels(int panelID);
void SetUpInflux();
private: private:
Digitizer ** digi; Digitizer ** digi;
@ -66,6 +76,9 @@ private:
QString prefix; QString prefix;
unsigned int runID; unsigned int runID;
unsigned int elogID; unsigned int elogID;
QString influxIP;
QString dataBaseName;
QString elogIP;
QPushButton * bnOpenDigitizers; QPushButton * bnOpenDigitizers;
QPushButton * bnCloseDigitizers; QPushButton * bnCloseDigitizers;
@ -76,6 +89,18 @@ private:
QPushButton * bnStartACQ; QPushButton * bnStartACQ;
QPushButton * bnStopACQ; QPushButton * bnStopACQ;
QPushButton * bnCanvas;
//@----- influx
InfluxDB * influx;
QLineEdit * leInfluxIP;
QLineEdit * leDatabaseName;
QPushButton * bnLock;
//@----- Elog
QLineEdit * leElogIP;
//@----- log msg //@----- log msg
QPlainTextEdit * logInfo; QPlainTextEdit * logInfo;
void LogMsg(QString msg); void LogMsg(QString msg);
@ -88,7 +113,7 @@ private:
QLineEdit * leRunID; QLineEdit * leRunID;
QCheckBox * chkSaveData; QCheckBox * chkSaveData;
QComboBox * cbAutoRun; RComboBox * cbAutoRun;
QString startComment; QString startComment;
QString stopComment; QString stopComment;
@ -111,6 +136,10 @@ private:
//@----- DigiSettings //@----- DigiSettings
DigiSettingsPanel * digiSettings; DigiSettingsPanel * digiSettings;
//@----- Canvas
Canvas * canvas;
TimingThread * histThread;
}; };

View File

@ -8,8 +8,11 @@ INCLUDEPATH += .
QT += core widgets charts QT += core widgets charts
QMAKE_CXXFLAGS += `root-config --cflags --glibs` #QMAKE_CXXFLAGS += `root-config --cflags --glibs`
LIBS += -lCAENDigitizer `root-config --cflags --glibs` #LIBS += -lCAENDigitizer `root-config --cflags --glibs`
#QMAKE_CXXFLAGS += -g
LIBS += -lCAENDigitizer -lcurl
# You can make your code fail to compile if you use deprecated APIs. # You can make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line. # In order to do so, uncomment the following line.
@ -27,9 +30,13 @@ HEADERS += ClassData.h \
FSUDAQ.h \ FSUDAQ.h \
macro.h \ macro.h \
RegisterAddress.h \ RegisterAddress.h \
Scope.h influxdb.h\
Scope.h \
CanvasClass.h
SOURCES += ClassDigitizer.cpp \ SOURCES += ClassDigitizer.cpp \
DigiSettingsPanel.cpp \ DigiSettingsPanel.cpp \
FSUDAQ.cpp \ FSUDAQ.cpp \
main.cpp \ main.cpp \
Scope.cpp influxdb.cpp\
Scope.cpp \
CanvasClass.cpp

View File

@ -5,7 +5,8 @@
CC = g++ CC = g++
COPTS = -fPIC -DLINUX -O2 -std=c++17 -lpthread #COPTS = -fPIC -DLINUX -O2 -std=c++17 -lpthread
COPTS = -fPIC -DLINUX -g -std=c++17 -lpthread
CAENLIBS = -lCAENDigitizer CAENLIBS = -lCAENDigitizer

31
README.md Normal file
View File

@ -0,0 +1,31 @@
# Introduction
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.
# Required / Development enviroment
Ubuntu 22.04
CAENVMELib_v3.3
CAENCOmm_v1.5.3
CAENDigitizer_v2.17.1
`sudo apt install qt6-base-dev libcurl4-openssl-dev libqt6charts6-dev`
# Compile
use `qmake6 -project ` to generate the *.pro
in the *.pro, add
` QT += core widgets charts`
` LIBS += -lCAENDigitizer -lcurl`
then run ` qmake6 *.pro` it will generate Makefile
then ` make`

View File

@ -116,16 +116,20 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) SetUpPHAPanel(); if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) SetUpPHAPanel();
if( digi[ID]->GetDPPType() == V1730_DPP_PSD_CODE ) SetUpPSDPanel(); if( digi[ID]->GetDPPType() == V1730_DPP_PSD_CODE ) SetUpPSDPanel();
//ReadSettingsFromBoard(); ReadSettingsFromBoard();
}); });
connect(cbScopeCh, &RComboBox::currentIndexChanged, this, [=](){
if( !enableSignalSlot ) return;
ReadSettingsFromBoard();
});
bnReadSettingsFromBoard = new QPushButton("Refresh Settings", this); bnReadSettingsFromBoard = new QPushButton("Refresh Settings", this);
layout->addWidget(bnReadSettingsFromBoard, rowID, 2); layout->addWidget(bnReadSettingsFromBoard, rowID, 2);
connect(bnReadSettingsFromBoard, &QPushButton::clicked, this, &Scope::ReadSettingsFromBoard); connect(bnReadSettingsFromBoard, &QPushButton::clicked, this, &Scope::ReadSettingsFromBoard);
QPushButton * bnClearMemory = new QPushButton("Clear Memory", this); QPushButton * bnClearMemory = new QPushButton("Clear Memory", this);
layout->addWidget(bnClearMemory, rowID, 3); layout->addWidget(bnClearMemory, rowID, 3);
connect(bnClearMemory, &QPushButton::clicked, this, [=](){ connect(bnClearMemory, &QPushButton::clicked, this, [=](){
@ -150,7 +154,6 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
//================ Plot view //================ Plot view
rowID ++; rowID ++;
plotView = new TraceView(plot, this); plotView = new TraceView(plot, this);
plotView->setRenderHints(QPainter::Antialiasing);
layout->addWidget(plotView, rowID, 0, 1, 6); layout->addWidget(plotView, rowID, 0, 1, 6);
@ -227,17 +230,25 @@ void Scope::StartScope(){
for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){ for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){
traceOn[iDigi] = digi[iDigi]->IsRecordTrace(); //remember setting
digi[iDigi]->SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::RecordTrace, 1, -1);
digi[iDigi]->GetData()->SetSaveWaveToMemory(true); digi[iDigi]->GetData()->SetSaveWaveToMemory(true);
digi[iDigi]->StartACQ(); digi[iDigi]->StartACQ();
printf("----- readDataThread running ? %d.\n", readDataThread[iDigi]->isRunning());
if( readDataThread[iDigi]->isRunning() ){
readDataThread[iDigi]->quit();
readDataThread[iDigi]->wait();
}
readDataThread[iDigi]->SetScopeMode(true); readDataThread[iDigi]->SetScopeMode(true);
readDataThread[iDigi]->SetSaveData(false); readDataThread[iDigi]->SetSaveData(false);
readDataThread[iDigi]->start(); readDataThread[iDigi]->start();
} }
emit UpdateOtherPanels();
updateTraceThread->start(); updateTraceThread->start();
bnScopeStart->setEnabled(false); bnScopeStart->setEnabled(false);
@ -252,20 +263,27 @@ void Scope::StartScope(){
void Scope::StopScope(){ void Scope::StopScope(){
if( !digi ) return; if( !digi ) return;
// printf("------ Scope::%s \n", __func__);
updateTraceThread->Stop(); updateTraceThread->Stop();
updateTraceThread->quit(); updateTraceThread->quit();
updateTraceThread->exit(); updateTraceThread->exit();
for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){ for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){
if( readDataThread[iDigi]->isRunning() ){
readDataThread[iDigi]->Stop();
readDataThread[iDigi]->quit();
readDataThread[iDigi]->wait();
}
digiMTX[iDigi].lock(); digiMTX[iDigi].lock();
digi[iDigi]->StopACQ(); digi[iDigi]->StopACQ();
digiMTX[iDigi].unlock(); digiMTX[iDigi].unlock();
readDataThread[iDigi]->quit(); digi[iDigi]->SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::RecordTrace, traceOn[iDigi], -1);
readDataThread[iDigi]->wait();
} }
emit UpdateOtherPanels();
bnScopeStart->setEnabled(true); bnScopeStart->setEnabled(true);
bnScopeStop->setEnabled(false); bnScopeStop->setEnabled(false);
@ -273,25 +291,28 @@ void Scope::StopScope(){
TellACQOnOff(false); TellACQOnOff(false);
// printf("----- end of %s\n", __func__);
} }
void Scope::UpdateScope(){ void Scope::UpdateScope(){
//printf("---- %s \n", __func__);
if( !digi ) return; if( !digi ) return;
int ch = cbScopeCh->currentIndex(); int ch = cbScopeCh->currentIndex();
int ch2ns = digi[ID]->GetCh2ns();
int factor = digi[ID]->IsDualTrace() ? 2 : 1;
Data * data = digi[ID]->GetData(); if( digi[ID]->GetChannelOnOff(ch) == false) return;
int ch2ns = digi[ID]->GetCh2ns();
int factor = digi[ID]->IsDualTrace_PHA() ? 2 : 1;
digiMTX[ID].lock(); digiMTX[ID].lock();
Data * data = digi[ID]->GetData();
//leTriggerRate->setText(QString::number(data->TriggerRate[ch]) + " [" + QString::number(data->NumEventsDecoded[ch]) + "]"); //leTriggerRate->setText(QString::number(data->TriggerRate[ch]) + " [" + QString::number(data->NumEventsDecoded[ch]) + "]");
leTriggerRate->setText(QString::number(data->TriggerRate[ch])); leTriggerRate->setText(QString::number(data->TriggerRate[ch]));
unsigned short index = data->EventIndex[ch] - 1; unsigned short index = data->EventIndex[ch];
unsigned short traceLength = data->Waveform1[ch][index].size(); unsigned short traceLength = data->Waveform1[ch][index].size();
if( data->TriggerRate[ch] > 0 ){ if( data->TriggerRate[ch] > 0 ){
@ -365,6 +386,7 @@ void Scope::SetUpComboBox(RComboBox * &cb, QString str, int row, int col, const
if( digi[ID]->GetErrorCode() == CAEN_DGTZ_Success ){ if( digi[ID]->GetErrorCode() == CAEN_DGTZ_Success ){
SendLogMsg(msg + " | OK."); SendLogMsg(msg + " | OK.");
cb->setStyleSheet(""); cb->setStyleSheet("");
emit UpdateOtherPanels();
}else{ }else{
SendLogMsg(msg + " | Fail."); SendLogMsg(msg + " | Fail.");
cb->setStyleSheet("color:red;"); cb->setStyleSheet("color:red;");
@ -412,7 +434,7 @@ void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, int row, int col, const Re
uint32_t value = sb->value() / ch2ns / abs(para.GetPartialStep()); uint32_t value = sb->value() / ch2ns / abs(para.GetPartialStep());
if( para == DPP::RecordLength_G){ if( para == DPP::RecordLength_G){
int factor = digi[ID]->IsDualTrace() ? 2 : 1; int factor = digi[ID]->IsDualTrace_PHA() ? 2 : 1;
value = value * factor; value = value * factor;
} }
@ -432,6 +454,7 @@ void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, int row, int col, const Re
if( digi[ID]->GetErrorCode() == CAEN_DGTZ_Success ){ if( digi[ID]->GetErrorCode() == CAEN_DGTZ_Success ){
SendLogMsg(msg + " | OK."); SendLogMsg(msg + " | OK.");
sb->setStyleSheet(""); sb->setStyleSheet("");
emit UpdateOtherPanels();
}else{ }else{
SendLogMsg(msg + " | Fail."); SendLogMsg(msg + " | Fail.");
sb->setStyleSheet("color:red;"); sb->setStyleSheet("color:red;");
@ -452,7 +475,6 @@ void Scope::CleanUpSettingsGroupBox(){
} }
void Scope::SetUpPHAPanel(){ void Scope::SetUpPHAPanel(){
printf("--- %s \n", __func__); printf("--- %s \n", __func__);
@ -696,6 +718,8 @@ void Scope::UpdatePanelFromMomeory(){
if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) UpdatePHAPanel(); if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) UpdatePHAPanel();
if( digi[ID]->GetDPPType() == V1730_DPP_PSD_CODE ) UpdatePSDPanel(); if( digi[ID]->GetDPPType() == V1730_DPP_PSD_CODE ) UpdatePSDPanel();
settingGroup->setEnabled(digi[ID]->GetChannelOnOff(ch));
} }
void Scope::UpdatePHAPanel(){ void Scope::UpdatePHAPanel(){

View File

@ -37,11 +37,12 @@ public:
event->accept(); event->accept();
} }
private slots: public slots:
void StartScope(); void StartScope();
void StopScope(); void StopScope();
void UpdateScope(); void UpdateScope();
void ReadSettingsFromBoard(); void ReadSettingsFromBoard();
void UpdatePanelFromMomeory();
signals: signals:
@ -49,6 +50,7 @@ signals:
void SendLogMsg(const QString &msg); void SendLogMsg(const QString &msg);
void TellACQOnOff(const bool onOff); void TellACQOnOff(const bool onOff);
void UpdateScaler(); void UpdateScaler();
void UpdateOtherPanels();
private: private:
@ -63,7 +65,6 @@ private:
void UpdateComobox(RComboBox * &cb, const Reg para); void UpdateComobox(RComboBox * &cb, const Reg para);
void UpdateSpinBox(RSpinBox * &sb, const Reg para); void UpdateSpinBox(RSpinBox * &sb, const Reg para);
void UpdatePanelFromMomeory();
void UpdatePHAPanel(); void UpdatePHAPanel();
void UpdatePSDPanel(); void UpdatePSDPanel();
@ -71,6 +72,7 @@ private:
unsigned short nDigi; unsigned short nDigi;
unsigned short ID; // the id of digi, index of cbScopeDigi unsigned short ID; // the id of digi, index of cbScopeDigi
int ch2ns; int ch2ns;
bool traceOn[MaxNDigitizer];
ReadDataThread ** readDataThread; ReadDataThread ** readDataThread;
TimingThread * updateTraceThread; TimingThread * updateTraceThread;

157
influxdb.cpp Normal file
View File

@ -0,0 +1,157 @@
#include "influxdb.h"
InfluxDB::InfluxDB(std::string url, bool verbose){
curl = curl_easy_init();
if( verbose) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
SetURL(url);
respondCode = 0;
dataPoints = "";
}
InfluxDB::~InfluxDB(){
curl_easy_cleanup(curl);
}
void InfluxDB::SetURL(std::string url){
// check the last char of url is "/"
if( url.back() != '/') {
this->databaseIP = url + "/";
}else{
this->databaseIP = url;
}
}
bool InfluxDB::TestingConnection(){
CheckDatabases();
if( respond != CURLE_OK ) return false;
return true;
}
std::string InfluxDB::CheckDatabases(){
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_URL, (databaseIP + "query").c_str());
std::string postFields="q=Show databases";
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(postFields.length()));
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallBack);
std::string readBuffer;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
Execute();
//printf("|%s|\n", readBuffer.c_str());
if( respond != CURLE_OK) return "";
databaseList.clear();
size_t pos = readBuffer.find("values");
if( pos > 0 ){
std::string kaka = readBuffer.substr(pos+8);
pos = kaka.find("}");
kaka = kaka.substr(0, pos);
int len = kaka.length();
bool startFlag = false;
std::string lala;
char yaya = '"';
for( int i = 0; i < len; i++){
if( startFlag == false && kaka[i] == yaya ) {
startFlag = true;
lala = "";
continue;
}
if( startFlag && kaka[i] == yaya ){
startFlag = false;
databaseList.push_back(lala);
continue;
}
if( startFlag ) lala += kaka[i];
}
}
return readBuffer;
}
std::string InfluxDB::Query(std::string databaseName, std::string query){
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_URL, (databaseIP + "query?db=" + databaseName).c_str());
std::string postFields = "q=" + query;
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(postFields.length()));
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallBack);
std::string readBuffer;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
Execute();
//printf("|%s|\n", readBuffer.c_str());
return readBuffer;
}
void InfluxDB::CreateDatabase(std::string databaseName){
curl_easy_setopt(curl, CURLOPT_URL, (databaseIP + "query").c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1);
std::string postFields = "q=CREATE DATABASE " + databaseName;
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(postFields.length()));
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields.c_str());
Execute();
}
void InfluxDB::AddDataPoint(std::string fullString){
dataPoints += fullString + "\n";
}
void InfluxDB::ClearDataPointsBuffer(){
dataPoints = "";
}
void InfluxDB::PrintDataPoints(){
printf("%s\n", dataPoints.c_str());
}
void InfluxDB::WriteData(std::string databaseName){
if( dataPoints.length() == 0 ) return;
//printf("|%s|\n", (databaseIP + "write?db=" + databaseName).c_str());
curl_easy_setopt(curl, CURLOPT_URL, (databaseIP + "write?db=" + databaseName).c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(dataPoints.length()));
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, dataPoints.c_str());
Execute();
}
void InfluxDB::Execute(){
try{
respond = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &respondCode);
//printf("==== respond %d (OK = %d)\n", respond, CURLE_OK);
if( respond != CURLE_OK) printf("############# InfluxDB::Execute fail\n");
} catch (std::exception& e){ // in case of unexpected error
printf("%s\n", e.what());
respond = CURLE_SEND_ERROR;
}
}
size_t InfluxDB::WriteCallBack(char *contents, size_t size, size_t nmemb, void *userp){
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}

58
influxdb.h Normal file
View File

@ -0,0 +1,58 @@
#ifndef INFLUXDB_H
#define INFLUXDB_H
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <curl/curl.h>
class InfluxDB{
private:
bool isURLValid;
CURL * curl;
CURLcode respond;
long respondCode;
std::string databaseIP;
std::string dataPoints;
std::vector<std::string> databaseList;
static size_t WriteCallBack(char *contents, size_t size, size_t nmemb, void *userp);
void Execute();
public:
InfluxDB(std::string url, bool verbose = false);
~InfluxDB();
void SetURL(std::string url);
bool TestingConnection();
bool IsURLValid() const {return isURLValid;}
/// Query
std::string CheckDatabases(); /// this save the list of database into databaseList
std::string Query(std::string databaseName, std::string query);
/// the CheckDatabases() function must be called before
std::vector<std::string> GetDatabaseList() {return databaseList;}
void CreateDatabase(std::string databaseName);
/// for single or batch write,
/// 1, addDataPoint first, you can add as many as you like
/// 2, writeData.
void AddDataPoint(std::string fullString);
unsigned int GetDataLength() const {return dataPoints.length();}
void ClearDataPointsBuffer();
void PrintDataPoints();
void WriteData(std::string databaseName);
bool IsWriteOK() const {return (respond == CURLE_OK) ? true: false;}
};
#endif