Compare commits

..

2 Commits

Author SHA1 Message Date
splitPoleDAQ 0000be1d44 scalar seems OK. 2023-04-19 16:21:14 -04:00
splitPoleDAQ f9128f6f92 pause building Scope, finsih the scalar first 2023-04-19 14:46:10 -04:00
6 changed files with 168 additions and 76 deletions

View File

@ -29,12 +29,14 @@ class Data{
uint32_t AllocatedSize; uint32_t AllocatedSize;
double TriggerRate[MaxNChannels]; /// Hz double TriggerRate[MaxNChannels]; /// Hz
double NonPileUpRate[MaxNChannels]; /// Hz
unsigned long TotNumEvents[MaxNChannels]; unsigned long TotNumEvents[MaxNChannels];
unsigned short NumEventsDecoded[MaxNChannels]; unsigned short NumEventsDecoded[MaxNChannels]; /// reset at every decode
unsigned short NumNonPileUpDecoded[MaxNChannels]; /// reset at every decode
/// store a single Raw event /// store data for event building
bool IsNotRollOverFakeAgg; bool IsNotRollOverFakeAgg;
unsigned short NumEvents[MaxNChannels]; unsigned short NumEvents[MaxNChannels]; /// max 65535, reset only clear Data
unsigned long long Timestamp[MaxNChannels][MaxNData]; /// 47 bit unsigned long long Timestamp[MaxNChannels][MaxNData]; /// 47 bit
unsigned short fineTime[MaxNChannels][MaxNData]; /// 10 bits, in unit of ch2ns / 1000 = ps unsigned short fineTime[MaxNChannels][MaxNData]; /// 10 bits, in unit of ch2ns / 1000 = ps
unsigned short Energy[MaxNChannels][MaxNData]; /// 15 bit unsigned short Energy[MaxNChannels][MaxNData]; /// 15 bit
@ -144,7 +146,9 @@ inline void Data::Allocate80MBMemory(){
inline void Data::ClearTriggerRate(){ inline void Data::ClearTriggerRate(){
for( int i = 0 ; i < MaxNChannels; i++) { for( int i = 0 ; i < MaxNChannels; i++) {
TriggerRate[i] = 0.0; TriggerRate[i] = 0.0;
NonPileUpRate[i] = 0.0;
NumEventsDecoded[i] = 0; NumEventsDecoded[i] = 0;
NumNonPileUpDecoded[i] = 0;
} }
} }
@ -340,6 +344,7 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){
double sec = dTime * ch2ns / 1e9; double sec = dTime * ch2ns / 1e9;
if( sec != 0 && NumEventsDecoded[ch] > 1 ){ if( sec != 0 && NumEventsDecoded[ch] > 1 ){
TriggerRate[ch] = NumEventsDecoded[ch]/sec; TriggerRate[ch] = NumEventsDecoded[ch]/sec;
NonPileUpRate[ch] = NumNonPileUpDecoded[ch]/sec;
} }
} }
@ -532,14 +537,21 @@ inline int Data::DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDe
printf(" trapezoid sat. : %d \n", ((extra >> 10) & 0x1) ); printf(" trapezoid sat. : %d \n", ((extra >> 10) & 0x1) );
} }
if( rollOver == 0 ) {
if( rollOver == 0 ) { // non-time roll over fake event
Energy[channel][NumEvents[channel]] = energy; Energy[channel][NumEvents[channel]] = energy;
Timestamp[channel][NumEvents[channel]] = timeStamp; Timestamp[channel][NumEvents[channel]] = timeStamp;
if(extra2Option == 0 || extra2Option == 2 ) fineTime[channel][NumEvents[channel]] = (extra2 & 0x07FF ); if(extra2Option == 0 || extra2Option == 2 ) fineTime[channel][NumEvents[channel]] = (extra2 & 0x07FF );
NumEvents[channel] ++; NumEvents[channel] ++;
NumEventsDecoded[channel] ++; NumEventsDecoded[channel] ++;
TotNumEvents[channel] ++; TotNumEvents[channel] ++;
if( !pileUp ) {
NumNonPileUpDecoded[channel] ++;
} }
}
if( NumEvents[channel] >= MaxNData ) ClearData();
if( verbose >= 1 ) printf("%4d | ch : %2d, PileUp : %d , energy : %5d, rollOver: %d, timestamp : %10llu, triggerAt : %d, nSample : %d, %f sec\n", if( verbose >= 1 ) printf("%4d | ch : %2d, PileUp : %d , energy : %5d, rollOver: %d, timestamp : %10llu, triggerAt : %d, nSample : %d, %f sec\n",
NumEvents[channel], channel, pileUp, energy, rollOver, timeStamp, triggerAtSample, nSample , timeStamp * 4. / 1e9); NumEvents[channel], channel, pileUp, energy, rollOver, timeStamp, triggerAtSample, nSample , timeStamp * 4. / 1e9);
@ -710,8 +722,11 @@ inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDe
NumEvents[channel] ++; NumEvents[channel] ++;
NumEventsDecoded[channel] ++; NumEventsDecoded[channel] ++;
TotNumEvents[channel] ++; TotNumEvents[channel] ++;
} }
if( NumEvents[channel] >= MaxNData ) ClearData();
if( verbose >= 2 ) printf("extra : 0x%08x, Qshort : %d, Qlong : %d \n", extra, Qshort, Qlong); if( verbose >= 2 ) printf("extra : 0x%08x, Qshort : %d, Qlong : %d \n", extra, Qshort, Qlong);
if( verbose >= 1 ) printf("ch : %2d, Qshort : %d, Qlong : %d, timestamp : %llu\n", if( verbose >= 1 ) printf("ch : %2d, Qshort : %d, Qlong : %d, timestamp : %llu\n",

View File

@ -17,8 +17,10 @@ public:
this->digi = dig; this->digi = dig;
this->ID = digiID; this->ID = digiID;
isSaveData = false; isSaveData = false;
isScope = false;
} }
void SetSaveData(bool onOff) {this->isSaveData = onOff;} void SetSaveData(bool onOff) {this->isSaveData = onOff;}
void SetScopeMode(bool onOff) {this->isScope = onOff;}
void run(){ void run(){
clock_gettime(CLOCK_REALTIME, &ta); clock_gettime(CLOCK_REALTIME, &ta);
while(true){ while(true){
@ -28,15 +30,12 @@ public:
if( ret == CAEN_DGTZ_Success ){ if( ret == CAEN_DGTZ_Success ){
digiMTX[ID].lock(); digiMTX[ID].lock();
if( isSaveData ) { digi->GetData()->DecodeBuffer(!isScope);
digi->GetData()->SaveData(); if( isSaveData ) digi->GetData()->SaveData();
}else{
digi->GetData()->DecodeBuffer(false);
}
digiMTX[ID].unlock(); digiMTX[ID].unlock();
}else{ }else{
printf("%s------------ ret : %d \n", __func__, ret); printf("ReadDataThread::%s------------ ret : %d \n", __func__, ret);
if( ret == CAEN_DGTZ_WrongAcqMode) break; if( ret == CAEN_DGTZ_WrongAcqMode) break;
} }
@ -72,47 +71,19 @@ private:
int ID; int ID;
timespec ta, tb; timespec ta, tb;
bool isSaveData; bool isSaveData;
bool isScope;
}; };
//^#===================================================== UpdateTrace Thread //^#======================================================= Timing Thread
class UpdateTraceThread : public QThread { class TimingThread : public QThread {
Q_OBJECT Q_OBJECT
public: public:
UpdateTraceThread(QObject * parent = 0) : QThread(parent){ TimingThread(QObject * parent = 0 ) : QThread(parent){
waitTime = 2;
stop = false;
}
unsigned int GetWaitTimeSec() const {return waitTime;}
void SetWaitTimeSec(unsigned sec) {waitTime = sec;}
void Stop() {this->stop = true;}
void run(){
unsigned int count = 0;
stop = false;
do{
usleep(100000);
count ++;
if( count % waitTime == 0){
emit updateTrace();
}
}while(!stop);
}
signals:
void updateTrace();
private:
bool stop;
unsigned int waitTime; //100 of milisec
};
//^#======================================================= Scalar Thread
class ScalarThread : public QThread {
Q_OBJECT
public:
ScalarThread(QObject * parent = 0 ) : QThread(parent){
waitTime = 20; // 10 x 100 milisec waitTime = 20; // 10 x 100 milisec
stop = false; stop = false;
} }
void Stop() { this->stop = true;} void Stop() { this->stop = true;}
void SetWaitTimeinSec(float sec) {waitTime = sec * 10 ;}
unsigned int GetWaitTimeinSec() const {return waitTime/10;} unsigned int GetWaitTimeinSec() const {return waitTime/10;}
void run(){ void run(){
unsigned int count = 0; unsigned int count = 0;

View File

@ -182,8 +182,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
lbLastUpdateTime = nullptr; lbLastUpdateTime = nullptr;
lbScalarACQStatus = nullptr; lbScalarACQStatus = nullptr;
scalarThread = new ScalarThread(); scalarThread = new TimingThread();
//connect(scalarThread, &ScalarThread::updataScalar, this, &MainWindow::UpdateScalar); connect(scalarThread, &TimingThread::updataScalar, this, &MainWindow::UpdateScalar);
} }
@ -199,6 +199,14 @@ MainWindow::~MainWindow(){
if( scope ) delete scope; if( scope ) delete scope;
if( scalar ) {
CleanUpScalar();
scalarThread->Stop();
scalarThread->quit();
scalarThread->exit();
delete scalarThread;
}
} }
@ -522,7 +530,18 @@ void MainWindow::OpenScalar(){
} }
void MainWindow::UpdateScalar(){ void MainWindow::UpdateScalar(){
if( digi == nullptr ) return;
lbLastUpdateTime->setText("Last update: " + QDateTime::currentDateTime().toString("MM.dd hh:mm:ss"));
for( unsigned int iDigi = 0; iDigi < nDigi; iDigi++){
Data * data = digi[iDigi]->GetData();
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]));
}
}
} }
@ -532,27 +551,38 @@ void MainWindow::UpdateScalar(){
void MainWindow::StartACQ(){ void MainWindow::StartACQ(){
if( digi == nullptr ) return; if( digi == nullptr ) return;
if( CommentDialog(true) == false) return; bool commentResult = true;
if( chkSaveData->isChecked() ) commentResult = CommentDialog(true);
if( commentResult == false) return;
for( unsigned int i = 0; i < nDigi ; i++){ for( unsigned int i = 0; i < nDigi ; i++){
digi[i]->GetData()->OpenSaveFile((rawDataPath + "/" + prefix).toStdString()); digi[i]->GetData()->OpenSaveFile((rawDataPath + "/" + prefix).toStdString());
digi[i]->StartACQ(); digi[i]->StartACQ();
readDataThread[i]->SetSaveData(true); readDataThread[i]->SetSaveData(chkSaveData->isChecked());
readDataThread[i]->start(); readDataThread[i]->start();
} }
if( chkSaveData->isChecked() ) SaveLastRunFile();
scalarThread->start();
SaveLastRunFile(); if( !scalar->isVisible() ) {
scalar->show();
}else{
scalar->activateWindow();
}
lbScalarACQStatus->setText("<font style=\"color: green;\"><b>ACQ On</b></font>");
} }
void MainWindow::StopACQ(){ void MainWindow::StopACQ(){
if( digi == nullptr ) return; if( digi == nullptr ) return;
if( CommentDialog(false) == false) return; bool commentResult = true;
if( chkSaveData->isChecked() ) commentResult = CommentDialog(true);
if( commentResult == false) return;
for( unsigned int i = 0; i < nDigi; i++){ for( unsigned int i = 0; i < nDigi; i++){
digi[i]->StopACQ(); digi[i]->StopACQ();
digi[i]->GetData()->CloseSaveFile(); if( chkSaveData->isChecked() ) digi[i]->GetData()->CloseSaveFile();
if( readDataThread[i]->isRunning() ) { if( readDataThread[i]->isRunning() ) {
readDataThread[i]->quit(); readDataThread[i]->quit();
@ -560,6 +590,13 @@ void MainWindow::StopACQ(){
} }
} }
if( scalarThread->isRunning()){
scalarThread->Stop();
scalarThread->quit();
scalarThread->wait();
}
lbScalarACQStatus->setText("<font style=\"color: red;\"><b>ACQ Off</b></font>");
} }
void MainWindow::AutoRun(){ void MainWindow::AutoRun(){

View File

@ -92,7 +92,7 @@ private:
//@----- Scalar //@----- Scalar
QMainWindow * scalar; QMainWindow * scalar;
QGridLayout * scalarLayout; QGridLayout * scalarLayout;
ScalarThread * scalarThread; TimingThread * scalarThread;
QLineEdit *** leTrigger; // need to delete manually QLineEdit *** leTrigger; // need to delete manually
QLineEdit *** leAccept; // need to delete manually QLineEdit *** leAccept; // need to delete manually
QLabel * lbLastUpdateTime; QLabel * lbLastUpdateTime;

View File

@ -48,7 +48,9 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
xaxis->setLabelFormat("%.0f"); xaxis->setLabelFormat("%.0f");
xaxis->setTitleText("Time [ns]"); xaxis->setTitleText("Time [ns]");
updateTraceThread = new UpdateTraceThread(); updateTraceThread = new TimingThread();
updateTraceThread->SetWaitTimeinSec(0.5);
//connect(updateTraceThread, &UpdateTraceThread::updateTrace, this, &Scope::UpdateScope); //connect(updateTraceThread, &UpdateTraceThread::updateTrace, this, &Scope::UpdateScope);
//*================================== UI //*================================== UI
@ -75,26 +77,33 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
for( int i = 0; i < digi[0]->GetNChannels(); i++) cbScopeCh->addItem("Ch-" + QString::number(i)); for( int i = 0; i < digi[0]->GetNChannels(); i++) cbScopeCh->addItem("Ch-" + QString::number(i));
ch2ns = digi[ID]->GetCh2ns(); ch2ns = digi[ID]->GetCh2ns();
connect(cbScopeCh, &RComboBox::currentIndexChanged, this, [=](int index){ connect(cbScopeDigi, &RComboBox::currentIndexChanged, this, [=](int index){
if( !enableSignalSlot ) return; if( !enableSignalSlot ) return;
ID = index; ID = index;
ch2ns = digi[ID]->GetCh2ns(); ch2ns = digi[ID]->GetCh2ns();
//---setup cbScopeCh //---setup cbScopeCh
cbScopeCh->clear(); cbScopeCh->clear();
for( int i = 0; i < digi[ID]->GetNChannels(); i++) cbScopeCh->addItem("Ch-" + QString::number(i)); for( int i = 0; i < digi[ID]->GetNChannels(); i++) cbScopeCh->addItem("Ch-" + QString::number(i));
//---Setup SettingGroup
if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) {
SetUpPHAPanel();
}else{
CleanUpSettingsGroupBox();
}
}); });
//================ Trace settings //================ Trace settings
rowID ++; rowID ++;
{ {
QGroupBox * settingGroup = new QGroupBox("Trace Settings",this); settingGroup = new QGroupBox("Trace Settings",this);
layout->addWidget(settingGroup, rowID, 0, 1, 6); layout->addWidget(settingGroup, rowID, 0, 1, 6);
QGridLayout * bLayout = new QGridLayout(settingGroup); settingLayout = new QGridLayout(settingGroup);
bLayout->setSpacing(0); settingLayout->setSpacing(0);
SetUpSpinBox(sbReordLength, "Record Length", bLayout, 0, 0, Register::DPP::RecordLength_G);
if( digi[ID]->GetDPPType() == V1730_DPP_PHA_CODE ) SetUpPHAPanel();
} }
//================ Plot view //================ Plot view
@ -108,7 +117,7 @@ Scope::Scope(Digitizer ** digi, unsigned int nDigi, ReadDataThread ** readDataTh
QLabel * lbhints = new QLabel("Type 'r' to restore view, '+/-' Zoom in/out, arrow key to pan.", this); QLabel * lbhints = new QLabel("Type 'r' to restore view, '+/-' Zoom in/out, arrow key to pan.", this);
layout->addWidget(lbhints, rowID, 0, 1, 4); layout->addWidget(lbhints, rowID, 0, 1, 4);
QLabel * lbinfo = new QLabel("Trace update every " + QString::number(updateTraceThread->GetWaitTimeSec()) + " sec.", this); QLabel * lbinfo = new QLabel("Trace update every " + QString::number(updateTraceThread->GetWaitTimeinSec()) + " sec.", this);
lbinfo->setAlignment(Qt::AlignRight); lbinfo->setAlignment(Qt::AlignRight);
layout->addWidget(lbinfo, rowID, 5); layout->addWidget(lbinfo, rowID, 5);
@ -178,28 +187,29 @@ void Scope::StopScope(){
//*======================================================= //*=======================================================
//*======================================================= //*=======================================================
void Scope::SetUpComboBox(RComboBox * &cb, QString str, QGridLayout * layout, int row, int col, const Register::Reg para){ void Scope::SetUpComboBox(RComboBox * &cb, QString str, int row, int col, const Register::Reg para){
QLabel * lb = new QLabel(str, this); QLabel * lb = new QLabel(str, settingGroup);
lb->setAlignment(Qt::AlignRight | Qt::AlignCenter); lb->setAlignment(Qt::AlignRight | Qt::AlignCenter);
layout->addWidget(lb, row, col); settingLayout->addWidget(lb, row, col);
cb = new RComboBox(this); cb = new RComboBox(settingGroup);
layout->addWidget(cb, row, col + 1); settingLayout->addWidget(cb, row, col + 1);
} }
void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, QGridLayout * layout, int row, int col, const Register::Reg para){ void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, int row, int col, const Register::Reg para){
QLabel * lb = new QLabel(str, this); QLabel * lb = new QLabel(str, settingGroup);
lb->setAlignment(Qt::AlignRight | Qt::AlignCenter); lb->setAlignment(Qt::AlignRight | Qt::AlignCenter);
layout->addWidget(lb, row, col); settingLayout->addWidget(lb, row, col);
sb = new RSpinBox(this); sb = new RSpinBox(settingGroup);
if( para.GetPartialStep() != 0 ){ if( para.GetPartialStep() != 0 ){
sb->setMinimum(0); sb->setMinimum(0);
sb->setMaximum(para.GetMax() * para.GetPartialStep() * ch2ns); sb->setMaximum(para.GetMax() * para.GetPartialStep() * ch2ns);
if( para.GetPartialStep() > 0 ) sb->setSingleStep(para.GetPartialStep() * ch2ns); if( para.GetPartialStep() > 0 ) sb->setSingleStep(para.GetPartialStep() * ch2ns);
if( para.GetPartialStep() == -1 ) sb->setSingleStep(1); if( para.GetPartialStep() == -1 ) sb->setSingleStep(1);
} }
layout->addWidget(sb, row, col + 1); settingLayout->addWidget(sb, row, col + 1);
connect(sb, &RSpinBox::valueChanged, this, [=](){ connect(sb, &RSpinBox::valueChanged, this, [=](){
if( !enableSignalSlot ) return; if( !enableSignalSlot ) return;
sb->setStyleSheet("color:blue"); sb->setStyleSheet("color:blue");
@ -229,5 +239,42 @@ void Scope::SetUpSpinBox(RSpinBox * &sb, QString str, QGridLayout * layout, int
// sb->setStyleSheet("color:red;"); // sb->setStyleSheet("color:red;");
// } // }
}); });
}
void Scope::CleanUpSettingsGroupBox(){
printf("-- %s\n", __func__);
QList<QLabel *> labelChildren1 = settingGroup->findChildren<QLabel *>();
for( int i = 0; i < labelChildren1.size(); i++) delete labelChildren1[i];
QList<RComboBox *> labelChildren2 = settingGroup->findChildren<RComboBox *>();
for( int i = 0; i < labelChildren2.size(); i++) delete labelChildren2[i];
QList<RSpinBox *> labelChildren3 = settingGroup->findChildren<RSpinBox *>();
for( int i = 0; i < labelChildren3.size(); i++) delete labelChildren3[i];
} }
void Scope::SetUpPHAPanel(){
CleanUpSettingsGroupBox();
printf("-- %s\n", __func__);
SetUpSpinBox(sbReordLength, "Record Length [ns]", 0, 0, Register::DPP::RecordLength_G);
SetUpSpinBox(sbPreTrigger, "Pre Trigger [ns]", 0, 2, Register::DPP::PreTrigger);
SetUpSpinBox(sbDCOffset, "DC offset", 0, 4, Register::DPP::ChannelDCOffset);
SetUpSpinBox(sbInputRiseTime, "Input Rise Time [ns]", 1, 0, Register::DPP::PHA::InputRiseTime);
SetUpSpinBox(sbThreshold, "Threshold [LSB]", 1, 2, Register::DPP::PHA::TriggerThreshold);
SetUpSpinBox(sbThreshold, "Trigger HoldOff [ns]", 1, 4, Register::DPP::PHA::TriggerHoldOffWidth);
SetUpSpinBox(sbTrapRiseTime, "Trap. Rise Time [ns]", 2, 0, Register::DPP::PHA::TrapezoidRiseTime);
SetUpSpinBox(sbTrapFlatTop, "Trap. FlatTop [ns]", 2, 2, Register::DPP::PHA::TrapezoidFlatTop);
SetUpSpinBox(sbDecayTime, "Decay Time [ns]", 2, 4, Register::DPP::PHA::DecayTime);
SetUpSpinBox(sbPeakingTime, "Peaking Time [ns]", 2, 6, Register::DPP::PHA::PeakingTime);
}

32
Scope.h
View File

@ -11,6 +11,7 @@
#include <QLineEdit> #include <QLineEdit>
#include <QComboBox> #include <QComboBox>
#include <QGridLayout> #include <QGridLayout>
#include <QGroupBox>
#include <QLineSeries> #include <QLineSeries>
#include <QRubberBand> #include <QRubberBand>
#include <QMouseEvent> #include <QMouseEvent>
@ -36,8 +37,11 @@ private slots:
void StartScope(); void StartScope();
void StopScope(); void StopScope();
void SetUpComboBox(RComboBox * &cb, QString str, QGridLayout * layout, int row, int col, const Register::Reg para); void SetUpComboBox(RComboBox * &cb, QString str, int row, int col, const Register::Reg para);
void SetUpSpinBox(RSpinBox * &sb, QString str, QGridLayout * layout, int row, int col, const Register::Reg para); void SetUpSpinBox(RSpinBox * &sb, QString str, int row, int col, const Register::Reg para);
void CleanUpSettingsGroupBox();
void SetUpPHAPanel();
signals: signals:
@ -49,7 +53,7 @@ private:
int ch2ns; int ch2ns;
ReadDataThread ** readDataThread; ReadDataThread ** readDataThread;
UpdateTraceThread * updateTraceThread; TimingThread * updateTraceThread;
bool enableSignalSlot; bool enableSignalSlot;
@ -64,11 +68,29 @@ private:
QLineEdit * leTriggerRate; QLineEdit * leTriggerRate;
RSpinBox * sbReordLength; QGroupBox * settingGroup;
//RSpinBox * sbPreTrigger; QGridLayout * settingLayout;
/// common to PSD and PHA
RSpinBox * sbReordLength;
RSpinBox * sbPreTrigger;
RSpinBox * sbDCOffset;
//RComboBox * cbDynamicRange; //RComboBox * cbDynamicRange;
/// PHA
RSpinBox * sbInputRiseTime;
RSpinBox * sbTriggerHoldOff;
RSpinBox * sbThreshold;
//RComboBox * cbSmoothingFactor;
RSpinBox * sbTrapRiseTime;
RSpinBox * sbTrapFlatTop;
RSpinBox * sbDecayTime;
RSpinBox * sbPeakingTime;
}; };