Compare commits
12 Commits
2db8f90ae6
...
9e514216af
Author | SHA1 | Date | |
---|---|---|---|
|
9e514216af | ||
|
bb74e0d308 | ||
|
1ae7309eb2 | ||
|
b18610a406 | ||
|
c895037896 | ||
|
8bead5a54b | ||
|
8a662c3407 | ||
|
7e12a2d6a6 | ||
|
38c4d0d992 | ||
|
3b9d47bbef | ||
|
73c2286005 | ||
|
a3deb59e0c |
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -150,6 +150,7 @@
|
|||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"variant": "cpp",
|
||||
"qmainwindow": "cpp"
|
||||
"qmainwindow": "cpp",
|
||||
"qchartview": "cpp"
|
||||
}
|
||||
}
|
120
CanvasClass.cpp
Normal file
120
CanvasClass.cpp
Normal 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
59
CanvasClass.h
Normal 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
|
|
@ -80,7 +80,7 @@ class Data{
|
|||
void CloseSaveFile();
|
||||
unsigned int GetFileSize() const {return outFileSize;}
|
||||
uint64_t GetTotalFileSize() const {return FinishedOutFilesSize + outFileSize;}
|
||||
|
||||
void ZeroTotalFileSize() { FinishedOutFilesSize = 0; }
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -188,6 +188,7 @@ inline void Data::ClearData(){
|
|||
}
|
||||
|
||||
inline void Data::ClearBuffer(){
|
||||
printf("==== Data::%s \n", __func__);
|
||||
delete buffer;
|
||||
buffer = nullptr;
|
||||
AllocatedSize = 0;
|
||||
|
@ -222,6 +223,11 @@ inline bool Data::OpenSaveFile(std::string fileNamePrefix){
|
|||
|
||||
inline void Data::SaveData(){
|
||||
|
||||
if( buffer == nullptr) {
|
||||
printf("buffer is null.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if( outFileSize > (unsigned int) MaxSaveFileSize){
|
||||
FinishedOutFilesSize += ftell(outFile);
|
||||
CloseSaveFile();
|
||||
|
|
|
@ -406,6 +406,7 @@ void Digitizer::StopACQ(){
|
|||
AcqRun = false;
|
||||
data->ClearTriggerRate();
|
||||
data->ClearBuffer();
|
||||
data->ZeroTotalFileSize();
|
||||
}
|
||||
|
||||
unsigned int Digitizer::CalByteForBuffer(){
|
||||
|
@ -661,7 +662,7 @@ void Digitizer::ProgramSettingsToBoard(){
|
|||
if( DPPType == V1730_DPP_PSD_CODE ){
|
||||
for( int p = 0; p < (int) RegisterPSDList.size(); p++){
|
||||
if( RegisterPSDList[p].GetType() == RW::ReadWrite){
|
||||
haha = RegisterPHAList[p];
|
||||
haha = RegisterPSDList[p];
|
||||
WriteRegister(haha, GetSettingFromMemory(haha, ch), ch, false);
|
||||
usleep(1 * 1000);
|
||||
}
|
||||
|
@ -730,13 +731,13 @@ int Digitizer::LoadSettingBinaryToMemory(std::string fileName){
|
|||
}else{
|
||||
/// load binary to memoery
|
||||
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");
|
||||
size_t dummy = fread( setting, SETTINGSIZE * sizeof(unsigned int), 1, 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);
|
||||
if( (boardInfo & 0xFF) == 0x0E ) ch2ns = 4.0;
|
||||
|
|
|
@ -103,8 +103,8 @@ class Digitizer{
|
|||
CAEN_DGTZ_BoardInfo_t GetBoardInfo() const {return BoardInfo;}
|
||||
std::string GetModelName() const {return BoardInfo.ModelName;}
|
||||
int GetSerialNumber() const {return BoardInfo.SerialNumber;}
|
||||
int GetChannelMask() const {return channelMask;}
|
||||
bool GetChannelOnOff(unsigned ch) const {return (channelMask & ( 1 << ch) );}
|
||||
int GetChannelMask() { channelMask = GetSettingFromMemory(DPP::ChannelEnableMask); return channelMask;}
|
||||
bool GetChannelOnOff(unsigned ch) { channelMask = GetSettingFromMemory(DPP::ChannelEnableMask); return (channelMask & ( 1 << ch) );}
|
||||
float GetCh2ns() const {return ch2ns;}
|
||||
int GetNChannels() const {return NChannel;}
|
||||
int GetHandle() const {return handle;}
|
||||
|
@ -152,10 +152,10 @@ class Digitizer{
|
|||
// bool IsEnabledAutoDataFlush() {return ( GetSettingFromMemory(DPP::BoardConfiguration) & 0x1 );}
|
||||
// bool IsDecimateTrace() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 1) & 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 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 IsRecordTimeStamp() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 18) & 0x1 );}
|
||||
// bool IsRecordEnergy() {return ( (GetSettingFromMemory(DPP::BoardConfiguration) >> 19) & 0x1 );}
|
||||
|
|
|
@ -18,47 +18,72 @@ public:
|
|||
this->ID = digiID;
|
||||
isSaveData = false;
|
||||
isScope = false;
|
||||
readCount = 0;
|
||||
stop = false;
|
||||
}
|
||||
void Stop() { this->stop = true;}
|
||||
void SetSaveData(bool onOff) {this->isSaveData = onOff;}
|
||||
void SetScopeMode(bool onOff) {this->isScope = onOff;}
|
||||
void run(){
|
||||
clock_gettime(CLOCK_REALTIME, &ta);
|
||||
while(true){
|
||||
clock_gettime(CLOCK_REALTIME, &t0);
|
||||
ta = t0;
|
||||
// clock_gettime(CLOCK_REALTIME, &t1);
|
||||
stop = false;
|
||||
do{
|
||||
|
||||
if( stop) break;
|
||||
|
||||
digiMTX[ID].lock();
|
||||
int ret = digi->ReadData();
|
||||
digiMTX[ID].unlock();
|
||||
readCount ++;
|
||||
|
||||
if( ret == CAEN_DGTZ_Success ){
|
||||
if( stop) break;
|
||||
if( ret == CAEN_DGTZ_Success && !stop){
|
||||
digiMTX[ID].lock();
|
||||
digi->GetData()->DecodeBuffer(!isScope);
|
||||
digi->GetData()->DecodeBuffer(!isScope, 0);
|
||||
if( isSaveData ) digi->GetData()->SaveData();
|
||||
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{
|
||||
printf("ReadDataThread::%s------------ ret : %d \n", __func__, ret);
|
||||
digiMTX[ID].lock();
|
||||
digi->StopACQ();
|
||||
digiMTX[ID].unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
if( isSaveData ) {
|
||||
if( isSaveData && !stop ) {
|
||||
clock_gettime(CLOCK_REALTIME, &tb);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}while(!stop);
|
||||
printf("ReadDataThread stopped.\n");
|
||||
}
|
||||
signals:
|
||||
void sendMsg(const QString &msg);
|
||||
private:
|
||||
Digitizer * digi;
|
||||
bool stop;
|
||||
int ID;
|
||||
timespec ta, tb;
|
||||
timespec ta, tb, t1, t2, t0;
|
||||
bool isSaveData;
|
||||
bool isScope;
|
||||
unsigned long readCount;
|
||||
};
|
||||
|
||||
//^#======================================================= Timing Thread
|
||||
|
|
130
CustomWidgets.h
130
CustomWidgets.h
|
@ -13,8 +13,11 @@
|
|||
#include <QRubberBand>
|
||||
#include <QMouseEvent>
|
||||
#include <QGestureEvent>
|
||||
#include <QLineSeries>
|
||||
#include <QAreaSeries>
|
||||
#include <QValueAxis>
|
||||
|
||||
//^=======================================
|
||||
//^====================================================
|
||||
class RSpinBox : public QDoubleSpinBox{
|
||||
Q_OBJECT
|
||||
public :
|
||||
|
@ -46,7 +49,7 @@ class RSpinBox : public QDoubleSpinBox{
|
|||
}
|
||||
};
|
||||
|
||||
//^=======================================
|
||||
//^====================================================
|
||||
class RComboBox : public QComboBox{
|
||||
public :
|
||||
RComboBox(QWidget * parent = nullptr): QComboBox(parent){
|
||||
|
@ -90,6 +93,7 @@ private:
|
|||
|
||||
};
|
||||
|
||||
//^====================================================
|
||||
class TraceView : public QChartView{
|
||||
public:
|
||||
TraceView(QChart * chart, QWidget * parent = nullptr): QChartView(chart, parent){
|
||||
|
@ -101,13 +105,21 @@ public:
|
|||
m_coordinateLabel->setVisible(false);
|
||||
m_coordinateLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
setMouseTracking(true);
|
||||
|
||||
setRenderHints(QPainter::Antialiasing);
|
||||
|
||||
vRangeMin = -(0x1FFF);
|
||||
vRangeMax = 0x1FFF;
|
||||
}
|
||||
|
||||
void SetHRange(int min, int max) {
|
||||
this->hRangeMin = min;
|
||||
this->hRangeMax = max;
|
||||
}
|
||||
void SetVRange(int min, int max) {
|
||||
this->vRangeMin = min;
|
||||
this->vRangeMax = max;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool viewportEvent(QEvent *event) override{
|
||||
if (event->type() == QEvent::TouchBegin) {
|
||||
|
@ -121,7 +133,6 @@ protected:
|
|||
QChartView::mousePressEvent(event);
|
||||
}
|
||||
void mouseMoveEvent(QMouseEvent *event) override{
|
||||
|
||||
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));
|
||||
m_coordinateLabel->setText(coordinateText);
|
||||
|
@ -129,7 +140,6 @@ protected:
|
|||
m_coordinateLabel->setVisible(true);
|
||||
if (m_isTouching) return;
|
||||
QChartView::mouseMoveEvent(event);
|
||||
|
||||
}
|
||||
void mouseReleaseEvent(QMouseEvent *event) override{
|
||||
if (m_isTouching) m_isTouching = false;
|
||||
|
@ -149,20 +159,126 @@ protected:
|
|||
case Qt::Key_Up: chart()->scroll(0, 10); break;
|
||||
case Qt::Key_Down: chart()->scroll(0, -10); break;
|
||||
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);
|
||||
break;
|
||||
default: QGraphicsView::keyPressEvent(event); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
bool m_isTouching;
|
||||
int hRangeMin;
|
||||
int hRangeMax;
|
||||
int vRangeMin;
|
||||
int vRangeMax;
|
||||
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
|
|
@ -174,6 +174,7 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
|
|||
leSaveFilePath[iDigi] = new QLineEdit(this);
|
||||
leSaveFilePath[iDigi]->setReadOnly(true);
|
||||
buttonLayout->addWidget(leSaveFilePath[iDigi], rowID, 1, 1, 3);
|
||||
leSaveFilePath[iDigi]->setText(QString::fromStdString(digi[ID]->GetSettingFileName()));
|
||||
|
||||
rowID ++; //---------------------------
|
||||
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);
|
||||
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);
|
||||
buttonLayout->addWidget(bnLoadSettings, rowID, 3);
|
||||
|
@ -202,11 +203,11 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
|
|||
rowID ++; //---------------------------
|
||||
bnSendSoftwareTriggerSignal = new QPushButton("Send SW Trigger Signal", this);
|
||||
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);
|
||||
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);
|
||||
buttonLayout->addWidget(bnSaveSettings, rowID, 2);
|
||||
|
@ -395,6 +396,14 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
|
|||
});
|
||||
|
||||
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){
|
||||
if( !enableSignalSlot ) return;
|
||||
|
@ -457,7 +466,8 @@ DigiSettingsPanel::DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QStr
|
|||
uint32_t value = std::stoul(text.toStdString(), nullptr, 16);
|
||||
int index = cbDigi->currentIndex();
|
||||
int regID = cbChReg->currentIndex();
|
||||
digi[index]->WriteRegister(chRegList[regID], value);
|
||||
int ch = cbCh->currentIndex();
|
||||
digi[index]->WriteRegister(chRegList[regID], value, ch);
|
||||
leChRegSet->setStyleSheet("");
|
||||
|
||||
cbChReg->currentIndexChanged(regID);
|
||||
|
@ -645,6 +655,7 @@ void DigiSettingsPanel::SetUpCheckBox(QCheckBox * &chkBox, QString label, QGridL
|
|||
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);
|
||||
UpdatePanelFromMemory();
|
||||
emit UpdateOtherPanels();
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -673,6 +684,7 @@ void DigiSettingsPanel::SetUpComboBoxBit(RComboBox * &cb, QString label, QGridLa
|
|||
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);
|
||||
UpdatePanelFromMemory();
|
||||
emit UpdateOtherPanels();
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -701,6 +713,7 @@ void DigiSettingsPanel::SetUpComboBox(RComboBox * &cb, QString label, QGridLayou
|
|||
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);
|
||||
UpdatePanelFromMemory();
|
||||
emit UpdateOtherPanels();
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -752,18 +765,21 @@ void DigiSettingsPanel::SetUpSpinBox(RSpinBox * &sb, QString label, QGridLayout
|
|||
if( para == DPP::ChannelDCOffset ){
|
||||
digi[ID]->WriteRegister(para, 0xFFFF * (1.0 - sb->value() / 100. ), chID);
|
||||
UpdatePanelFromMemory();
|
||||
emit UpdateOtherPanels();
|
||||
return;
|
||||
}
|
||||
|
||||
if( para == DPP::PSD::CFDSetting ){
|
||||
digi[ID]->SetBits(para, DPP::PSD::Bit_CFDSetting::CFDDealy, sb->value()/digi[ID]->GetCh2ns(), chID);
|
||||
UpdatePanelFromMemory();
|
||||
emit UpdateOtherPanels();
|
||||
return;
|
||||
}
|
||||
|
||||
if( para == DPP::DPPAlgorithmControl ){
|
||||
digi[ID]->SetBits(para, {5,0}, sb->value(), chID);
|
||||
UpdatePanelFromMemory();
|
||||
emit UpdateOtherPanels();
|
||||
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);
|
||||
|
||||
UpdatePanelFromMemory();
|
||||
emit UpdateOtherPanels();
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -1201,6 +1218,11 @@ void DigiSettingsPanel::SetUpChannelMask(){
|
|||
bnChEnableMask[ID][i]->setStyleSheet("");
|
||||
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);
|
||||
}
|
||||
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);
|
||||
SetUpSpinBox(sbTriggerHoldOff[ID][ch], "", tabLayout, ch + 1, 6, DPP::PHA::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);
|
||||
SetUpSpinBox(sbTriggerHoldOff[ID][ch], "", tabLayout, ch + 1, 6, DPP::PSD::TriggerHoldOffWidth, 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 ){
|
||||
|
@ -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);
|
||||
}
|
||||
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(cbTrigCount[ID][ch], "", tabLayout, ch + 1, 5, DPP::PHA::Bit_DPPAlgorithmControl2::ListTrigCounter, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::TriggerCounterFlag, 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::PSD::Bit_DPPAlgorithmControl2::ListTrigCounter, DPP::PHA::DPPAlgorithmControl2_G, DPP::PHA::Bit_DPPAlgorithmControl2::TriggerCounterFlag, 1, ch);
|
||||
}
|
||||
|
||||
if( i == 2 ){
|
||||
|
@ -2214,7 +2235,7 @@ void DigiSettingsPanel::SetUpPSDChannel(){
|
|||
QTabWidget * othersTab = new QTabWidget(this);
|
||||
otherLayout->addWidget(othersTab);
|
||||
|
||||
QStringList tabName = {"Tab-1", "Test Pulse", "Veto", "Extra2"};
|
||||
QStringList tabName = {"Tab-1", "Test Pulse", "Veto", "Extra"};
|
||||
|
||||
const int nTab = tabName.count();
|
||||
|
||||
|
@ -2273,7 +2294,7 @@ void DigiSettingsPanel::SetUpPSDChannel(){
|
|||
|
||||
if( i == 3 ){
|
||||
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);
|
||||
}
|
||||
|
@ -2370,8 +2391,6 @@ void DigiSettingsPanel::UpdatePanelFromMemory(){
|
|||
chkTraceRecording[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::RecordTrace) );
|
||||
chkEnableExtra2[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::EnableExtra2) );
|
||||
|
||||
|
||||
|
||||
if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) {
|
||||
chkDecimateTrace[ID]->setChecked( Digitizer::ExtractBits(BdCfg, DPP::Bit_BoardConfig::DecimateTrace) );
|
||||
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_PSD_CODE ) UpdatePSDSetting();
|
||||
|
||||
|
@ -2632,6 +2649,8 @@ void DigiSettingsPanel::SyncSpinBox(RSpinBox *(&spb)[][MaxNChannels+1]){
|
|||
const int value = spb[ID][0]->value();
|
||||
for( int i = 1; i < nCh; i ++){
|
||||
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());
|
||||
|
@ -2663,6 +2682,7 @@ void DigiSettingsPanel::SyncComboBox(RComboBox *(&cb)[][MaxNChannels+1]){
|
|||
const QString text = cb[ID][0]->currentText();
|
||||
for( int i = 1; i < nCh; i ++){
|
||||
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());
|
||||
|
@ -2691,6 +2711,7 @@ void DigiSettingsPanel::SyncCheckBox(QCheckBox *(&chk)[][MaxNChannels+1]){
|
|||
const Qt::CheckState state = chk[ID][0]->checkState();
|
||||
for( int i = 1; i < nCh; i ++){
|
||||
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());
|
||||
|
@ -2753,7 +2774,7 @@ void DigiSettingsPanel::UpdatePHASetting(){
|
|||
|
||||
enableSignalSlot = false;
|
||||
|
||||
printf("------ %s \n", __func__);
|
||||
//printf("------ %s \n", __func__);
|
||||
|
||||
for( int ch = 0; ch < digi[ID]->GetNChannels(); 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);
|
||||
|
||||
UpdateComboBoxBit(cbVetoStep[ID][ch], vetoBit, DPP::Bit_VetoWidth::VetoStep);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enableSignalSlot = true;
|
||||
|
||||
|
@ -2870,13 +2891,12 @@ void DigiSettingsPanel::SyncAllChannelsTab_PSD(){
|
|||
SyncComboBox(cbVetoMode);
|
||||
SyncComboBox(cbVetoStep);
|
||||
|
||||
|
||||
}
|
||||
void DigiSettingsPanel::UpdatePSDSetting(){
|
||||
|
||||
enableSignalSlot = false;
|
||||
|
||||
printf("------ %s \n", __func__);
|
||||
//printf("------ %s \n", __func__);
|
||||
|
||||
for(int ch = 0; ch < digi[ID]->GetNChannels(); ch ++){
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
DigiSettingsPanel(Digitizer ** digi, unsigned int nDigi, QString rawDataPath, QMainWindow * parent = nullptr);
|
||||
~DigiSettingsPanel();
|
||||
|
||||
private slots:
|
||||
public slots:
|
||||
void UpdatePanelFromMemory();
|
||||
void ReadSettingsFromBoard();
|
||||
|
||||
|
@ -30,6 +30,7 @@ private slots:
|
|||
|
||||
signals:
|
||||
void SendLogMsg(const QString &msg);
|
||||
void UpdateOtherPanels();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -68,7 +69,6 @@ private:
|
|||
|
||||
void CheckRadioAndCheckedButtons();
|
||||
|
||||
|
||||
Digitizer ** digi;
|
||||
unsigned int nDigi;
|
||||
unsigned short ID;
|
||||
|
|
317
FSUDAQ.cpp
317
FSUDAQ.cpp
|
@ -12,10 +12,6 @@
|
|||
#include <QFileDialog>
|
||||
#include <QScrollArea>
|
||||
|
||||
#include <TH1.h>
|
||||
|
||||
#include "CustomWidgets.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
||||
|
||||
setWindowTitle("FSU DAQ");
|
||||
|
@ -27,6 +23,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
|||
scalar = nullptr;
|
||||
scope = nullptr;
|
||||
digiSettings = nullptr;
|
||||
canvas = nullptr;
|
||||
|
||||
QWidget * mainLayoutWidget = new QWidget(this);
|
||||
setCentralWidget(mainLayoutWidget);
|
||||
|
@ -43,16 +40,92 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
|||
connect(bnOpenDigitizers, &QPushButton::clicked, this, &MainWindow::OpenDigitizers);
|
||||
|
||||
bnCloseDigitizers = new QPushButton("Close Digitizers", this);
|
||||
layout->addWidget(bnCloseDigitizers, 0, 1);
|
||||
layout->addWidget(bnCloseDigitizers, 1, 0);
|
||||
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);
|
||||
layout->addWidget(bnOpenScope, 1, 0);
|
||||
layout->addWidget(bnOpenScope, 1, 1);
|
||||
connect(bnOpenScope, &QPushButton::clicked, this, &MainWindow::OpenScope);
|
||||
|
||||
bnDigiSettings = new QPushButton("Digitizers Settings", this);
|
||||
layout->addWidget(bnDigiSettings, 1, 1);
|
||||
connect(bnDigiSettings, &QPushButton::clicked, this, &MainWindow::OpenDigiSettings);
|
||||
bnCanvas = new QPushButton("Online 1D Histograms", this);
|
||||
layout->addWidget(bnCanvas, 1, 2);
|
||||
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);
|
||||
|
||||
chkSaveData = new QCheckBox("Save Data", this);
|
||||
cbAutoRun = new QComboBox(this);
|
||||
cbAutoRun = new RComboBox(this);
|
||||
cbAutoRun->addItem("Single Infinite", 0);
|
||||
cbAutoRun->addItem("Single 30 mins", 30);
|
||||
cbAutoRun->addItem("Single 60 mins", 60);
|
||||
|
@ -145,7 +218,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
|||
layoutMain->setStretchFactor(box3, 1);
|
||||
QVBoxLayout * layout3 = new QVBoxLayout(box3);
|
||||
logInfo = new QPlainTextEdit(this);
|
||||
logInfo->isReadOnly();
|
||||
logInfo->setReadOnly(true);
|
||||
QFont font;
|
||||
font.setFamily("Courier New");
|
||||
logInfo->setFont(font);
|
||||
|
@ -165,6 +238,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
|||
//=========== disable widget
|
||||
WaitForDigitizersOpen(true);
|
||||
|
||||
SetUpInflux();
|
||||
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow(){
|
||||
|
@ -176,6 +251,8 @@ MainWindow::~MainWindow(){
|
|||
|
||||
if( digiSettings ) delete digiSettings;
|
||||
|
||||
if( canvas ) delete canvas;
|
||||
|
||||
if( scalar ) {
|
||||
CleanUpScalar();
|
||||
scalarThread->Stop();
|
||||
|
@ -184,6 +261,8 @@ MainWindow::~MainWindow(){
|
|||
delete scalarThread;
|
||||
}
|
||||
|
||||
delete influx;
|
||||
|
||||
}
|
||||
|
||||
//***************************************************************
|
||||
|
@ -201,6 +280,8 @@ void MainWindow::OpenDataPath(){
|
|||
leDataPath->clear();
|
||||
}
|
||||
|
||||
SaveProgramSettings();
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::LoadProgramSettings(){
|
||||
|
@ -220,12 +301,19 @@ void MainWindow::LoadProgramSettings(){
|
|||
if( line.left(6) == "//----") break;
|
||||
|
||||
if( count == 0 ) rawDataPath = line;
|
||||
if( count == 1 ) influxIP = line;
|
||||
if( count == 2 ) dataBaseName = line;
|
||||
if( count == 3 ) elogIP = line;
|
||||
|
||||
count ++;
|
||||
line = in.readLine();
|
||||
}
|
||||
|
||||
//looking for the lastRun.sh for
|
||||
leDataPath->setText(rawDataPath);
|
||||
leInfluxIP->setText(influxIP);
|
||||
leDatabaseName->setText(dataBaseName);
|
||||
leElogIP->setText(elogIP);
|
||||
|
||||
//check is rawDataPath exist, if not, create one
|
||||
QDir rawDataDir;
|
||||
|
@ -252,7 +340,10 @@ void MainWindow::SaveProgramSettings(){
|
|||
file.open(QIODevice::Text | QIODevice::WriteOnly);
|
||||
|
||||
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();
|
||||
LogMsg("Saved program settings to <b>"+ programSettingsFilePath + "<b>.");
|
||||
|
@ -390,6 +481,14 @@ void MainWindow::OpenDigitizers(){
|
|||
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));
|
||||
|
||||
WaitForDigitizersOpen(false);
|
||||
|
@ -422,6 +521,13 @@ void MainWindow::CloseDigitizers(){
|
|||
for(unsigned int i = 0; i < nDigi; i ++){
|
||||
digi[i]->CloseDigitizer();
|
||||
delete digi[i];
|
||||
|
||||
if(readDataThread[i]->isRunning()){
|
||||
readDataThread[i]->Stop();
|
||||
readDataThread[i]->quit();
|
||||
readDataThread[i]->wait();
|
||||
}
|
||||
|
||||
delete readDataThread[i];
|
||||
}
|
||||
delete [] digi;
|
||||
|
@ -447,6 +553,7 @@ void MainWindow::WaitForDigitizersOpen(bool onOff){
|
|||
bnStartACQ->setEnabled(!onOff);
|
||||
bnStopACQ->setEnabled(!onOff);
|
||||
chkSaveData->setEnabled(!onOff);
|
||||
bnCanvas->setEnabled(!onOff);
|
||||
|
||||
}
|
||||
|
||||
|
@ -478,7 +585,7 @@ void MainWindow::SetupScalar(){
|
|||
scalarThread = new TimingThread();
|
||||
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 ){
|
||||
lbLastUpdateTime = new QLabel("Last update : NA", scalar);
|
||||
|
@ -515,6 +622,7 @@ void MainWindow::SetupScalar(){
|
|||
rowID = 2;
|
||||
leTrigger[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++){
|
||||
|
||||
if( ch == 0 ){
|
||||
|
@ -533,7 +641,6 @@ void MainWindow::SetupScalar(){
|
|||
}
|
||||
|
||||
rowID ++;
|
||||
|
||||
leTrigger[iDigi][ch] = new QLineEdit(scalar);
|
||||
leTrigger[iDigi][ch]->setReadOnly(true);
|
||||
leTrigger[iDigi][ch]->setAlignment(Qt::AlignRight);
|
||||
|
@ -543,6 +650,10 @@ void MainWindow::SetupScalar(){
|
|||
leAccept[iDigi][ch]->setReadOnly(true);
|
||||
leAccept[iDigi][ch]->setAlignment(Qt::AlignRight);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -584,17 +695,31 @@ void MainWindow::OpenScalar(){
|
|||
void MainWindow::UpdateScalar(){
|
||||
if( digi == 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"));
|
||||
|
||||
//printf("----------------------\n");
|
||||
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++){
|
||||
leTrigger[iDigi][i]->setText(QString::number(data->TriggerRate[i]));
|
||||
leAccept[iDigi][i]->setText(QString::number(data->NonPileUpRate[i]));
|
||||
if( digi[iDigi]->GetChannelOnOff(i) == true ) {
|
||||
//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( 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++){
|
||||
if( chkSaveData->isChecked() ) {
|
||||
|
@ -620,10 +749,13 @@ void MainWindow::StartACQ(){
|
|||
}
|
||||
readDataThread[i]->SetSaveData(chkSaveData->isChecked());
|
||||
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();
|
||||
readDataThread[i]->start();
|
||||
}
|
||||
if( chkSaveData->isChecked() ) SaveLastRunFile();
|
||||
|
||||
scalarThread->start();
|
||||
|
||||
if( !scalar->isVisible() ) {
|
||||
|
@ -633,6 +765,8 @@ void MainWindow::StartACQ(){
|
|||
}
|
||||
lbScalarACQStatus->setText("<font style=\"color: green;\"><b>ACQ On</b></font>");
|
||||
|
||||
if( canvas != nullptr ) histThread->start();
|
||||
|
||||
bnStartACQ->setEnabled(false);
|
||||
bnStopACQ->setEnabled(true);
|
||||
bnOpenScope->setEnabled(false);
|
||||
|
@ -641,21 +775,28 @@ void MainWindow::StartACQ(){
|
|||
void MainWindow::StopACQ(){
|
||||
if( digi == nullptr ) return;
|
||||
|
||||
LogMsg("===================== Stop Run-" + QString::number(runID));
|
||||
|
||||
bool commentResult = true;
|
||||
if( chkSaveData->isChecked() ) commentResult = CommentDialog(true);
|
||||
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++){
|
||||
LogMsg("Digi-" + QString::number(digi[i]->GetSerialNumber()) + " is stoping ACQ." );
|
||||
digi[i]->StopACQ();
|
||||
if( chkSaveData->isChecked() ) digi[i]->GetData()->CloseSaveFile();
|
||||
|
||||
if( readDataThread[i]->isRunning() ) {
|
||||
readDataThread[i]->Stop();
|
||||
readDataThread[i]->quit();
|
||||
readDataThread[i]->wait();
|
||||
}
|
||||
digiMTX[i].lock();
|
||||
digi[i]->StopACQ();
|
||||
digiMTX[i].unlock();
|
||||
if( chkSaveData->isChecked() ) digi[i]->GetData()->CloseSaveFile();
|
||||
}
|
||||
|
||||
if( scalarThread->isRunning()){
|
||||
|
@ -663,6 +804,12 @@ void MainWindow::StopACQ(){
|
|||
scalarThread->quit();
|
||||
scalarThread->wait();
|
||||
}
|
||||
|
||||
if( histThread->isRunning()){
|
||||
histThread->Stop();
|
||||
histThread->quit();
|
||||
histThread->wait();
|
||||
}
|
||||
|
||||
lbScalarACQStatus->setText("<font style=\"color: red;\"><b>ACQ Off</b></font>");
|
||||
|
||||
|
@ -671,7 +818,7 @@ void MainWindow::StopACQ(){
|
|||
bnOpenScope->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::AutoRun(){
|
||||
void MainWindow::AutoRun(){ //TODO
|
||||
|
||||
}
|
||||
|
||||
|
@ -783,15 +930,31 @@ void MainWindow::OpenScope(){
|
|||
bnStopACQ->setEnabled(false);
|
||||
});
|
||||
connect(scope, &Scope::TellACQOnOff, this, [=](bool onOff){
|
||||
if( scope == nullptr ) return;
|
||||
if( onOff ) {
|
||||
lbScalarACQStatus->setText("<font style=\"color: green;\"><b>ACQ On</b></font>");
|
||||
}else{
|
||||
lbScalarACQStatus->setText("<font style=\"color: red;\"><b>ACQ Off</b></font>");
|
||||
if( scope ) {
|
||||
if( onOff ) {
|
||||
lbScalarACQStatus->setText("<font style=\"color: green;\"><b>ACQ On</b></font>");
|
||||
}else{
|
||||
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::UpdateOtherPanels, this, [=](){ UpdateAllPanels(1); });
|
||||
|
||||
scope->show();
|
||||
}else{
|
||||
scope->show();
|
||||
|
@ -801,6 +964,8 @@ void MainWindow::OpenScope(){
|
|||
bnStartACQ->setEnabled(false);
|
||||
bnStopACQ->setEnabled(false);
|
||||
|
||||
chkSaveData->setChecked(false);
|
||||
|
||||
}
|
||||
|
||||
//***************************************************************
|
||||
|
@ -810,6 +975,8 @@ void MainWindow::OpenDigiSettings(){
|
|||
if( digiSettings == nullptr ) {
|
||||
digiSettings = new DigiSettingsPanel(digi, nDigi, rawDataPath);
|
||||
//connect(scope, &Scope::SendLogMsg, this, &MainWindow::LogMsg);
|
||||
connect(digiSettings, &DigiSettingsPanel::UpdateOtherPanels, this, [=](){ UpdateAllPanels(2); });
|
||||
|
||||
digiSettings->show();
|
||||
}else{
|
||||
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){
|
||||
|
@ -829,6 +1084,6 @@ void MainWindow::LogMsg(QString msg){
|
|||
}
|
||||
QScrollBar *v = logInfo->verticalScrollBar();
|
||||
v->setValue(v->maximum());
|
||||
//qDebug() << msg;
|
||||
qDebug() << outputStr;
|
||||
logInfo->repaint();
|
||||
}
|
||||
|
|
31
FSUDAQ.h
31
FSUDAQ.h
|
@ -13,8 +13,11 @@
|
|||
|
||||
#include "ClassDigitizer.h"
|
||||
#include "CustomThreads.h"
|
||||
#include "CustomWidgets.h"
|
||||
#include "Scope.h"
|
||||
#include "DigiSettingsPanel.h"
|
||||
#include "CanvasClass.h"
|
||||
#include "influxdb.h"
|
||||
|
||||
//^#===================================================== MainWindow
|
||||
class MainWindow : public QMainWindow{
|
||||
|
@ -26,6 +29,7 @@ public:
|
|||
void closeEvent(QCloseEvent * event){
|
||||
if( scope ) scope->close();
|
||||
if( digiSettings ) digiSettings->close();
|
||||
if( canvas ) canvas->close();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
|
@ -56,6 +60,12 @@ private slots:
|
|||
|
||||
void OpenDigiSettings();
|
||||
|
||||
void OpenCanvas();
|
||||
|
||||
void UpdateAllPanels(int panelID);
|
||||
|
||||
void SetUpInflux();
|
||||
|
||||
private:
|
||||
|
||||
Digitizer ** digi;
|
||||
|
@ -66,6 +76,9 @@ private:
|
|||
QString prefix;
|
||||
unsigned int runID;
|
||||
unsigned int elogID;
|
||||
QString influxIP;
|
||||
QString dataBaseName;
|
||||
QString elogIP;
|
||||
|
||||
QPushButton * bnOpenDigitizers;
|
||||
QPushButton * bnCloseDigitizers;
|
||||
|
@ -76,6 +89,18 @@ private:
|
|||
QPushButton * bnStartACQ;
|
||||
QPushButton * bnStopACQ;
|
||||
|
||||
QPushButton * bnCanvas;
|
||||
|
||||
//@----- influx
|
||||
InfluxDB * influx;
|
||||
|
||||
QLineEdit * leInfluxIP;
|
||||
QLineEdit * leDatabaseName;
|
||||
QPushButton * bnLock;
|
||||
|
||||
//@----- Elog
|
||||
QLineEdit * leElogIP;
|
||||
|
||||
//@----- log msg
|
||||
QPlainTextEdit * logInfo;
|
||||
void LogMsg(QString msg);
|
||||
|
@ -88,7 +113,7 @@ private:
|
|||
QLineEdit * leRunID;
|
||||
|
||||
QCheckBox * chkSaveData;
|
||||
QComboBox * cbAutoRun;
|
||||
RComboBox * cbAutoRun;
|
||||
|
||||
QString startComment;
|
||||
QString stopComment;
|
||||
|
@ -111,6 +136,10 @@ private:
|
|||
//@----- DigiSettings
|
||||
DigiSettingsPanel * digiSettings;
|
||||
|
||||
//@----- Canvas
|
||||
Canvas * canvas;
|
||||
TimingThread * histThread;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -8,8 +8,11 @@ INCLUDEPATH += .
|
|||
|
||||
QT += core widgets charts
|
||||
|
||||
QMAKE_CXXFLAGS += `root-config --cflags --glibs`
|
||||
LIBS += -lCAENDigitizer `root-config --cflags --glibs`
|
||||
#QMAKE_CXXFLAGS += `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.
|
||||
# In order to do so, uncomment the following line.
|
||||
|
@ -27,9 +30,13 @@ HEADERS += ClassData.h \
|
|||
FSUDAQ.h \
|
||||
macro.h \
|
||||
RegisterAddress.h \
|
||||
Scope.h
|
||||
influxdb.h\
|
||||
Scope.h \
|
||||
CanvasClass.h
|
||||
SOURCES += ClassDigitizer.cpp \
|
||||
DigiSettingsPanel.cpp \
|
||||
FSUDAQ.cpp \
|
||||
main.cpp \
|
||||
Scope.cpp
|
||||
influxdb.cpp\
|
||||
Scope.cpp \
|
||||
CanvasClass.cpp
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
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
|
||||
|
||||
|
|
31
README.md
Normal file
31
README.md
Normal 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`
|
56
Scope.cpp
56
Scope.cpp
|
@ -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_PSD_CODE ) SetUpPSDPanel();
|
||||
|
||||
//ReadSettingsFromBoard();
|
||||
ReadSettingsFromBoard();
|
||||
|
||||
});
|
||||
|
||||
connect(cbScopeCh, &RComboBox::currentIndexChanged, this, [=](){
|
||||
if( !enableSignalSlot ) return;
|
||||
ReadSettingsFromBoard();
|
||||
});
|
||||
|
||||
|
||||
bnReadSettingsFromBoard = new QPushButton("Refresh Settings", this);
|
||||
layout->addWidget(bnReadSettingsFromBoard, rowID, 2);
|
||||
connect(bnReadSettingsFromBoard, &QPushButton::clicked, this, &Scope::ReadSettingsFromBoard);
|
||||
|
||||
|
||||
QPushButton * bnClearMemory = new QPushButton("Clear Memory", this);
|
||||
layout->addWidget(bnClearMemory, rowID, 3);
|
||||
connect(bnClearMemory, &QPushButton::clicked, this, [=](){
|
||||
|
@ -150,7 +154,6 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
|
|||
//================ Plot view
|
||||
rowID ++;
|
||||
plotView = new TraceView(plot, this);
|
||||
plotView->setRenderHints(QPainter::Antialiasing);
|
||||
layout->addWidget(plotView, rowID, 0, 1, 6);
|
||||
|
||||
|
||||
|
@ -227,17 +230,25 @@ void Scope::StartScope(){
|
|||
|
||||
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]->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]->SetSaveData(false);
|
||||
|
||||
readDataThread[iDigi]->start();
|
||||
|
||||
}
|
||||
|
||||
emit UpdateOtherPanels();
|
||||
|
||||
updateTraceThread->start();
|
||||
|
||||
bnScopeStart->setEnabled(false);
|
||||
|
@ -252,20 +263,27 @@ void Scope::StartScope(){
|
|||
void Scope::StopScope(){
|
||||
if( !digi ) return;
|
||||
|
||||
// printf("------ Scope::%s \n", __func__);
|
||||
updateTraceThread->Stop();
|
||||
updateTraceThread->quit();
|
||||
updateTraceThread->exit();
|
||||
|
||||
|
||||
for( unsigned int iDigi = 0; iDigi < nDigi; iDigi ++){
|
||||
|
||||
if( readDataThread[iDigi]->isRunning() ){
|
||||
readDataThread[iDigi]->Stop();
|
||||
readDataThread[iDigi]->quit();
|
||||
readDataThread[iDigi]->wait();
|
||||
}
|
||||
digiMTX[iDigi].lock();
|
||||
digi[iDigi]->StopACQ();
|
||||
digiMTX[iDigi].unlock();
|
||||
|
||||
readDataThread[iDigi]->quit();
|
||||
readDataThread[iDigi]->wait();
|
||||
digi[iDigi]->SetBits(DPP::BoardConfiguration, DPP::Bit_BoardConfig::RecordTrace, traceOn[iDigi], -1);
|
||||
}
|
||||
|
||||
emit UpdateOtherPanels();
|
||||
|
||||
bnScopeStart->setEnabled(true);
|
||||
bnScopeStop->setEnabled(false);
|
||||
|
||||
|
@ -273,25 +291,28 @@ void Scope::StopScope(){
|
|||
|
||||
TellACQOnOff(false);
|
||||
|
||||
// printf("----- end of %s\n", __func__);
|
||||
|
||||
}
|
||||
|
||||
void Scope::UpdateScope(){
|
||||
|
||||
//printf("---- %s \n", __func__);
|
||||
|
||||
if( !digi ) return;
|
||||
|
||||
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();
|
||||
Data * data = digi[ID]->GetData();
|
||||
|
||||
//leTriggerRate->setText(QString::number(data->TriggerRate[ch]) + " [" + QString::number(data->NumEventsDecoded[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();
|
||||
|
||||
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 ){
|
||||
SendLogMsg(msg + " | OK.");
|
||||
cb->setStyleSheet("");
|
||||
emit UpdateOtherPanels();
|
||||
}else{
|
||||
SendLogMsg(msg + " | Fail.");
|
||||
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());
|
||||
|
||||
if( para == DPP::RecordLength_G){
|
||||
int factor = digi[ID]->IsDualTrace() ? 2 : 1;
|
||||
int factor = digi[ID]->IsDualTrace_PHA() ? 2 : 1;
|
||||
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 ){
|
||||
SendLogMsg(msg + " | OK.");
|
||||
sb->setStyleSheet("");
|
||||
emit UpdateOtherPanels();
|
||||
}else{
|
||||
SendLogMsg(msg + " | Fail.");
|
||||
sb->setStyleSheet("color:red;");
|
||||
|
@ -452,7 +475,6 @@ void Scope::CleanUpSettingsGroupBox(){
|
|||
|
||||
}
|
||||
|
||||
|
||||
void Scope::SetUpPHAPanel(){
|
||||
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_PSD_CODE ) UpdatePSDPanel();
|
||||
|
||||
settingGroup->setEnabled(digi[ID]->GetChannelOnOff(ch));
|
||||
|
||||
}
|
||||
|
||||
void Scope::UpdatePHAPanel(){
|
||||
|
|
6
Scope.h
6
Scope.h
|
@ -37,11 +37,12 @@ public:
|
|||
event->accept();
|
||||
}
|
||||
|
||||
private slots:
|
||||
public slots:
|
||||
void StartScope();
|
||||
void StopScope();
|
||||
void UpdateScope();
|
||||
void ReadSettingsFromBoard();
|
||||
void UpdatePanelFromMomeory();
|
||||
|
||||
signals:
|
||||
|
||||
|
@ -49,6 +50,7 @@ signals:
|
|||
void SendLogMsg(const QString &msg);
|
||||
void TellACQOnOff(const bool onOff);
|
||||
void UpdateScaler();
|
||||
void UpdateOtherPanels();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -63,7 +65,6 @@ private:
|
|||
|
||||
void UpdateComobox(RComboBox * &cb, const Reg para);
|
||||
void UpdateSpinBox(RSpinBox * &sb, const Reg para);
|
||||
void UpdatePanelFromMomeory();
|
||||
void UpdatePHAPanel();
|
||||
void UpdatePSDPanel();
|
||||
|
||||
|
@ -71,6 +72,7 @@ private:
|
|||
unsigned short nDigi;
|
||||
unsigned short ID; // the id of digi, index of cbScopeDigi
|
||||
int ch2ns;
|
||||
bool traceOn[MaxNDigitizer];
|
||||
|
||||
ReadDataThread ** readDataThread;
|
||||
TimingThread * updateTraceThread;
|
||||
|
|
157
influxdb.cpp
Normal file
157
influxdb.cpp
Normal 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
58
influxdb.h
Normal 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
|
Loading…
Reference in New Issue
Block a user