added all traces in Scope

This commit is contained in:
Ryan Tang 2023-02-07 18:58:00 -05:00
parent 898ddfa63c
commit ef666175b4
5 changed files with 140 additions and 48 deletions

View File

@ -1,5 +1,8 @@
#include "ClassDigitizer2Gen.h" #include "ClassDigitizer2Gen.h"
unsigned short Digitizer2Gen::TraceStep = 8; //? should be variable?
Digitizer2Gen::Digitizer2Gen(){ Digitizer2Gen::Digitizer2Gen(){
printf("======== %s \n",__func__); printf("======== %s \n",__func__);
Initialization(); Initialization();
@ -453,6 +456,8 @@ int Digitizer2Gen::ReadData(){
return CAEN_FELib_UNKNOWN; return CAEN_FELib_UNKNOWN;
} }
evt->traceZero = false;
if( ret != CAEN_FELib_Success) { if( ret != CAEN_FELib_Success) {
//ErrorMsg("ReadData()"); //ErrorMsg("ReadData()");
return ret; return ret;
@ -584,8 +589,8 @@ void Digitizer2Gen::ProgramPHA(bool testPulse){
//======== Self trigger for each channel //======== Self trigger for each channel
//WriteValue("/ch/0..63/par/EventTriggerSource", "ChSelfTrigger"); WriteValue("/ch/0..63/par/EventTriggerSource", "ChSelfTrigger");
//WriteValue("/ch/0..63/par/WaveTriggerSource" , "ChSelfTrigger"); WriteValue("/ch/0..63/par/WaveTriggerSource" , "ChSelfTrigger");
//======== One (or more) slef-trigger can trigger whole board, ??? depend on Channel Trigger mask //======== One (or more) slef-trigger can trigger whole board, ??? depend on Channel Trigger mask
//WriteValue("/ch/0..63/par/EventTriggerSource", "Ch64Trigger"); //WriteValue("/ch/0..63/par/EventTriggerSource", "Ch64Trigger");
@ -601,14 +606,14 @@ void Digitizer2Gen::ProgramPHA(bool testPulse){
//WriteValue("/ch/38/par/ChannelsTriggerMask", "0x000F"); // when channel has no input, it still record. //WriteValue("/ch/38/par/ChannelsTriggerMask", "0x000F"); // when channel has no input, it still record.
//----------- coincident trigger to ch-4n //----------- coincident trigger to ch-4n
WriteValue("/ch/0..63/par/EventTriggerSource", "ChSelfTrigger"); //WriteValue("/ch/0..63/par/EventTriggerSource", "ChSelfTrigger");
WriteValue("/ch/0..63/par/WaveTriggerSource" , "ChSelfTrigger"); //WriteValue("/ch/0..63/par/WaveTriggerSource" , "ChSelfTrigger");
for(int i = 0 ; i < 16; i++){ //for(int i = 0 ; i < 16; i++){
WriteValue(("/ch/"+ std::to_string(4*i+1) + ".." + std::to_string(4*i+3) + "/par/ChannelsTriggerMask").c_str(), "0x1"); // WriteValue(("/ch/"+ std::to_string(4*i+1) + ".." + std::to_string(4*i+3) + "/par/ChannelsTriggerMask").c_str(), "0x1");
WriteValue(("/ch/"+ std::to_string(4*i+1) + ".." + std::to_string(4*i+3) + "/par/CoincidenceMask").c_str(), "Ch64Trigger"); // WriteValue(("/ch/"+ std::to_string(4*i+1) + ".." + std::to_string(4*i+3) + "/par/CoincidenceMask").c_str(), "Ch64Trigger");
WriteValue(("/ch/"+ std::to_string(4*i+1) + ".." + std::to_string(4*i+3) + "/par/CoincidenceLengthT").c_str(), "100"); // ns // WriteValue(("/ch/"+ std::to_string(4*i+1) + ".." + std::to_string(4*i+3) + "/par/CoincidenceLengthT").c_str(), "100"); // ns
} //}
//======== ACQ trigger? //======== ACQ trigger?
//WriteValue("/ch/0..63/par/EventTriggerSource", "GlobalTriggerSource"); //WriteValue("/ch/0..63/par/EventTriggerSource", "GlobalTriggerSource");
//WriteValue("/ch/0..63/par/WaveTriggerSource" , "GlobalTriggerSource"); //WriteValue("/ch/0..63/par/WaveTriggerSource" , "GlobalTriggerSource");
@ -623,8 +628,8 @@ void Digitizer2Gen::ProgramPHA(bool testPulse){
WriteValue("/ch/0..63/par/DCOffset" , "10"); /// 10% WriteValue("/ch/0..63/par/DCOffset" , "10"); /// 10%
WriteValue("/ch/0..63/par/WaveSaving" , "Always"); WriteValue("/ch/0..63/par/WaveSaving" , "Always");
WriteValue("/ch/0..63/par/ChRecordLengthS" , "512"); /// 4096 ns WriteValue("/ch/0..63/par/ChRecordLengthT" , "4096"); /// 4096 ns, S and T are not Sync
WriteValue("/ch/0..63/par/ChPreTriggerS" , "125"); /// 1000 ns WriteValue("/ch/0..63/par/ChPreTriggerT" , "1000"); /// 1000 ns
WriteValue("/ch/0..63/par/WaveResolution" , "RES8"); /// 8 ns WriteValue("/ch/0..63/par/WaveResolution" , "RES8"); /// 8 ns
WriteValue("/ch/0..63/par/WaveAnalogProbe0" , "ADCInput"); WriteValue("/ch/0..63/par/WaveAnalogProbe0" , "ADCInput");

View File

@ -71,6 +71,8 @@ class Digitizer2Gen {
bool IsConnected() const {return isConnected;} bool IsConnected() const {return isConnected;}
int CloseDigitizer(); int CloseDigitizer();
int GetRet() const {return ret;};
std::string ReadValue(const char * parameter, bool verbose = false); std::string ReadValue(const char * parameter, bool verbose = false);
std::string ReadChValue(std::string ch, std::string shortPara, bool verbose = false); std::string ReadChValue(std::string ch, std::string shortPara, bool verbose = false);
void WriteValue(const char * parameter, std::string value); void WriteValue(const char * parameter, std::string value);
@ -110,6 +112,7 @@ class Digitizer2Gen {
void SaveDataToFile(); void SaveDataToFile();
unsigned int GetFileSize() {return outFileSize;} unsigned int GetFileSize() {return outFileSize;}
static unsigned short TraceStep;
}; };

22
Event.h
View File

@ -36,6 +36,8 @@ class Event {
size_t dataSize; /// number of byte of the data, size/8 = word [64 bits] size_t dataSize; /// number of byte of the data, size/8 = word [64 bits]
uint32_t n_events; uint32_t n_events;
bool traceZero;
Event(){ Event(){
Init(); Init();
} }
@ -71,6 +73,8 @@ class Event {
digital_probes_type[2] = 0xFF; digital_probes_type[2] = 0xFF;
digital_probes_type[3] = 0xFF; digital_probes_type[3] = 0xFF;
data = NULL; data = NULL;
traceZero = true; // indicate trace are all zero
} }
void ClearMemory(){ void ClearMemory(){
@ -83,6 +87,8 @@ class Event {
if( digital_probes[1] != NULL) delete digital_probes[1]; if( digital_probes[1] != NULL) delete digital_probes[1];
if( digital_probes[2] != NULL) delete digital_probes[2]; if( digital_probes[2] != NULL) delete digital_probes[2];
if( digital_probes[3] != NULL) delete digital_probes[3]; if( digital_probes[3] != NULL) delete digital_probes[3];
traceZero = true;
} }
void SetDataType(unsigned int type){ void SetDataType(unsigned int type){
@ -100,8 +106,24 @@ class Event {
digital_probes[2] = new uint8_t[MaxTraceLenght]; digital_probes[2] = new uint8_t[MaxTraceLenght];
digital_probes[3] = new uint8_t[MaxTraceLenght]; digital_probes[3] = new uint8_t[MaxTraceLenght];
traceZero = true;
}
} }
void ClearTrace(){
if( traceZero ) return; // no need to clear again
for( int i = 0; i < MaxTraceLenght; i++){
analog_probes[0][i] = 0;
analog_probes[1][i] = 0;
digital_probes[0][i] = 0;
digital_probes[1][i] = 0;
digital_probes[2][i] = 0;
digital_probes[3][i] = 0;
}
traceZero = true;
} }
void PrintEnergyTimeStamp(){ void PrintEnergyTimeStamp(){

View File

@ -182,12 +182,15 @@ MainWindow::~MainWindow(){
//delete bnNewExp; //delete bnNewExp;
//delete logInfo; //delete logInfo;
StopScope();
updateTraceThread->Stop(); updateTraceThread->Stop();
updateTraceThread->quit(); updateTraceThread->quit();
updateTraceThread->wait(); updateTraceThread->wait();
delete updateTraceThread; delete updateTraceThread;
delete dataTrace; /// dataTrace must be deleted before plot for( int i = 0; i < 6; i++) delete dataTrace[i];
//delete [] dataTrace; /// dataTrace must be deleted before plot
delete plot; delete plot;
//---- need manually delete //---- need manually delete
@ -353,7 +356,12 @@ void MainWindow::OpenScope(){
for( int i = 0 ; i < 2; i++){ for( int i = 0 ; i < 2; i++){
ans = digi[iDigi]->ReadChValue(std::to_string(ch), haha[i]); ans = digi[iDigi]->ReadChValue(std::to_string(ch), haha[i]);
index = cbAnaProbe[i]->findData(QString::fromStdString(ans)); index = cbAnaProbe[i]->findData(QString::fromStdString(ans));
if( index >= 0 ) {
cbAnaProbe[i]->setCurrentIndex(index); cbAnaProbe[i]->setCurrentIndex(index);
}else{
qDebug() << QString::fromStdString(ans);
}
} }
haha.clear(); haha.clear();
@ -362,7 +370,11 @@ void MainWindow::OpenScope(){
for( int i = 0 ; i < 4; i++){ for( int i = 0 ; i < 4; i++){
ans = digi[iDigi]->ReadChValue(std::to_string(ch), haha[i]); ans = digi[iDigi]->ReadChValue(std::to_string(ch), haha[i]);
index = cbDigProbe[i]->findData(QString::fromStdString(ans)); index = cbDigProbe[i]->findData(QString::fromStdString(ans));
if( index >= 0 ) {
cbDigProbe[i]->setCurrentIndex(index); cbDigProbe[i]->setCurrentIndex(index);
}else{
qDebug() << QString::fromStdString(ans);
}
} }
ans = digi[iDigi]->ReadChValue(std::to_string(ch), "ChRecordLengthT"); ans = digi[iDigi]->ReadChValue(std::to_string(ch), "ChRecordLengthT");
@ -384,7 +396,6 @@ void MainWindow::OpenScope(){
bnStartACQ->setEnabled(false); bnStartACQ->setEnabled(false);
bnStopACQ->setEnabled(false); bnStopACQ->setEnabled(false);
} }
scope->show(); scope->show();
@ -427,10 +438,12 @@ void MainWindow::StopScope(){
if( digi[i]->IsDummy() ) continue; if( digi[i]->IsDummy() ) continue;
digiMTX.lock(); digiMTX.lock();
digi[i]->StopACQ(); digi[i]->StopACQ();
digi[i]->WriteChValue("0..63", "ChEnable", "true");
digiMTX.unlock(); digiMTX.unlock();
readDataThread[i]->quit(); readDataThread[i]->quit();
readDataThread[i]->wait(); readDataThread[i]->wait();
} }
bnStartACQ->setEnabled(true); bnStartACQ->setEnabled(true);
bnStopACQ->setEnabled(true); bnStopACQ->setEnabled(true);
@ -453,29 +466,20 @@ void MainWindow::UpdateScope(){
if( digi ){ if( digi ){
digiMTX.lock(); digiMTX.lock();
unsigned int traceLength = digi[iDigi]->evt->traceLenght; unsigned int traceLength = digi[iDigi]->evt->traceLenght;
unsigned int dataLength = dataTrace->count(); unsigned int dataLength = dataTrace[0]->count();
if( traceLength < dataLength){ //---- remove all points
for( unsigned int i = 0; i < traceLength; i++) { for( int j = 0; j < 6; j++ ) dataTrace[j]->removePoints(0, dataLength);
dataTrace->replace(i, i, digi[iDigi]->evt->analog_probes[0][i]);
}
dataTrace->removePoints(traceLength, dataLength-traceLength);
}else{
for( unsigned int i = 0 ; i < traceLength; i++){ for( unsigned int i = 0 ; i < traceLength; i++){
if( i < dataLength ) { for( int j = 0; j < 2; j++) dataTrace[j]->append(Digitizer2Gen::TraceStep * i, digi[iDigi]->evt->analog_probes[j][i]);
dataTrace->replace(i, i, digi[iDigi]->evt->analog_probes[0][i]); for( int j = 2; j < 6; j++) dataTrace[j]->append(Digitizer2Gen::TraceStep * i, (j-1)*1000 + 4000 * digi[iDigi]->evt->digital_probes[j-2][i]);
}else{
dataTrace->append(i, digi[iDigi]->evt->analog_probes[0][i]);
} }
}
}
digiMTX.unlock(); digiMTX.unlock();
plot->axes(Qt::Vertical).first()->setRange(-1, 16000); /// this must be after createDefaultAxes(); //plot->axes(Qt::Vertical).first()->setRange(-1, 16000); /// this must be after createDefaultAxes();
plot->axes(Qt::Horizontal).first()->setRange(0, traceLength); //plot->axes(Qt::Horizontal).first()->setRange(-10, traceLength*1.1);
} }
} }
@ -502,12 +506,11 @@ void MainWindow::ProbeChange(QComboBox * cb[], const int size ){
digiMTX.lock(); digiMTX.lock();
if( size == 2) {// analog probes if( size == 2) {// analog probes
dataTrace->setName(cb[0]->currentText()); for( int j = 0; j < 2; j++ )dataTrace[j]->setName(cb[j]->currentText());
} }
if( size == 4){ // digitial probes if( size == 4){ // digitial probes
for( int j = 2; j < 6; j++ )dataTrace[j]->setName(cb[j-2]->currentText());
} }
digiMTX.unlock(); digiMTX.unlock();
@ -522,14 +525,24 @@ void MainWindow::SetUpPlot(){ //@--- this function run at start up
allowChange = false; allowChange = false;
plot = new QChart(); plot = new QChart();
dataTrace = new QLineSeries(); for( int i = 0; i < 6; i++) {
dataTrace->setName("Analog Trace 1"); dataTrace[i] = new QLineSeries();
for(int i = 0; i < 100; i ++) dataTrace->append(i, QRandomGenerator::global()->bounded(10)); dataTrace[i]->setName("Trace " + QString::number(i));
for(int j = 0; j < 100; j ++) dataTrace[i]->append(j, QRandomGenerator::global()->bounded(8000) + 8000);
plot->addSeries(dataTrace[i]);
}
dataTrace[0]->setPen(QPen(Qt::red, 2));
dataTrace[1]->setPen(QPen(Qt::blue, 2));
dataTrace[2]->setPen(QPen(Qt::darkRed, 1));
dataTrace[3]->setPen(QPen(Qt::darkYellow, 1));
dataTrace[4]->setPen(QPen(Qt::darkGreen, 1));
dataTrace[5]->setPen(QPen(Qt::darkBlue, 1));
plot->addSeries(dataTrace);
plot->createDefaultAxes(); /// this must be after addSeries(); plot->createDefaultAxes(); /// this must be after addSeries();
plot->axes(Qt::Vertical).first()->setRange(-1, 11); /// this must be after createDefaultAxes(); plot->axes(Qt::Vertical).first()->setRange(-2000, 16000); /// this must be after createDefaultAxes();
plot->axes(Qt::Horizontal).first()->setRange(-1, 101); plot->axes(Qt::Horizontal).first()->setRange(0, 5000);
plot->axes(Qt::Horizontal).first()->setTitleText("Time [ns]");
updateTraceThread = new UpdateTraceThread(); updateTraceThread = new UpdateTraceThread();
connect(updateTraceThread, &UpdateTraceThread::updateTrace, this, &MainWindow::UpdateScope); connect(updateTraceThread, &UpdateTraceThread::updateTrace, this, &MainWindow::UpdateScope);
@ -556,11 +569,21 @@ void MainWindow::SetUpPlot(){ //@--- this function run at start up
} }
}); });
connect(cbScopeCh, &QComboBox::currentIndexChanged, this, [=](){
if( !allowChange ) return;
int iDigi = cbScopeDigi->currentIndex();
int ch = cbScopeCh->currentIndex();
digiMTX.lock();
digi[iDigi]->WriteChValue("0..63", "ChEnable", "false");
digi[iDigi]->WriteChValue(std::to_string(ch), "ChEnable", "true");
digiMTX.unlock();
});
//------------ Probe selection //------------ Probe selection
rowID ++; rowID ++;
cbAnaProbe[0] = new QComboBox(scope); cbAnaProbe[0] = new QComboBox(scope);
cbAnaProbe[0]->addItem("ADC Input", "ADCInput"); cbAnaProbe[0]->addItem("ADC Input", "ADCInput");
cbAnaProbe[0]->addItem("Time Filter", "TimeFiler"); cbAnaProbe[0]->addItem("Time Filter", "TimeFilter");
cbAnaProbe[0]->addItem("Trapazoid", "EnergyFilter"); cbAnaProbe[0]->addItem("Trapazoid", "EnergyFilter");
cbAnaProbe[0]->addItem("Trap. Baseline", "EnergyFilterBaseline"); cbAnaProbe[0]->addItem("Trap. Baseline", "EnergyFilterBaseline");
cbAnaProbe[0]->addItem("Trap. - Baseline", "EnergyFilterMinusBaseline"); cbAnaProbe[0]->addItem("Trap. - Baseline", "EnergyFilterMinusBaseline");
@ -583,6 +606,13 @@ void MainWindow::SetUpPlot(){ //@--- this function run at start up
digiMTX.unlock(); digiMTX.unlock();
}); });
connect(cbAnaProbe[1], &QComboBox::currentIndexChanged, this, [=](){
int iDigi = cbScopeDigi->currentIndex();
int ch = cbScopeCh->currentIndex();
digiMTX.lock();
digi[iDigi]->WriteChValue(std::to_string(ch), "WaveAnalogProbe1", (cbAnaProbe[1]->currentData()).toString().toStdString());
digiMTX.unlock();
});
cbDigProbe[0] = new QComboBox(scope); cbDigProbe[0] = new QComboBox(scope);
cbDigProbe[0]->addItem("Trigger", "Trigger"); cbDigProbe[0]->addItem("Trigger", "Trigger");
@ -619,6 +649,36 @@ void MainWindow::SetUpPlot(){ //@--- this function run at start up
cbDigProbe[2]->setCurrentIndex(5); cbDigProbe[2]->setCurrentIndex(5);
cbDigProbe[3]->setCurrentIndex(6); cbDigProbe[3]->setCurrentIndex(6);
connect(cbDigProbe[0], &QComboBox::currentIndexChanged, this, [=](){
int iDigi = cbScopeDigi->currentIndex();
int ch = cbScopeCh->currentIndex();
digiMTX.lock();
digi[iDigi]->WriteChValue(std::to_string(ch), "WaveDigitalProbe0", (cbDigProbe[0]->currentData()).toString().toStdString());
digiMTX.unlock();
});
connect(cbDigProbe[1], &QComboBox::currentIndexChanged, this, [=](){
int iDigi = cbScopeDigi->currentIndex();
int ch = cbScopeCh->currentIndex();
digiMTX.lock();
digi[iDigi]->WriteChValue(std::to_string(ch), "WaveDigitalProbe1", (cbDigProbe[1]->currentData()).toString().toStdString());
digiMTX.unlock();
});
connect(cbDigProbe[2], &QComboBox::currentIndexChanged, this, [=](){
int iDigi = cbScopeDigi->currentIndex();
int ch = cbScopeCh->currentIndex();
digiMTX.lock();
digi[iDigi]->WriteChValue(std::to_string(ch), "WaveDigitalProbe2", (cbDigProbe[2]->currentData()).toString().toStdString());
digiMTX.unlock();
});
connect(cbDigProbe[3], &QComboBox::currentIndexChanged, this, [=](){
int iDigi = cbScopeDigi->currentIndex();
int ch = cbScopeCh->currentIndex();
digiMTX.lock();
digi[iDigi]->WriteChValue(std::to_string(ch), "WaveDigitalProbe3", (cbDigProbe[3]->currentData()).toString().toStdString());
digiMTX.unlock();
});
layout->addWidget(cbAnaProbe[0], rowID, 0); layout->addWidget(cbAnaProbe[0], rowID, 0);
layout->addWidget(cbAnaProbe[1], rowID, 1); layout->addWidget(cbAnaProbe[1], rowID, 1);
@ -640,6 +700,7 @@ void MainWindow::SetUpPlot(){ //@--- this function run at start up
connect(sbRL, &QSpinBox::valueChanged, this, [=](){ connect(sbRL, &QSpinBox::valueChanged, this, [=](){
if( !allowChange ) return; if( !allowChange ) return;
int iDigi = cbScopeDigi->currentIndex(); int iDigi = cbScopeDigi->currentIndex();
sbRL->setValue(8*((sbRL->value() + 7)/8));
digiMTX.lock(); digiMTX.lock();
//StopScope(); //StopScope();
digi[iDigi]->WriteChValue(std::to_string(cbScopeCh->currentIndex()), digi[iDigi]->WriteChValue(std::to_string(cbScopeCh->currentIndex()),
@ -648,7 +709,7 @@ void MainWindow::SetUpPlot(){ //@--- this function run at start up
//StartScope(); //StartScope();
digiMTX.unlock(); digiMTX.unlock();
plot->axes(Qt::Horizontal).first()->setRange(0, sbRL->value()/8); //plot->axes(Qt::Horizontal).first()->setRange(0, 600);
}); });

View File

@ -48,6 +48,7 @@ public:
break; break;
}else{ }else{
digi->ErrorMsg("ReadDataLoop()"); digi->ErrorMsg("ReadDataLoop()");
digi->evt->ClearTrace();
} }
if( !isScopeRun ){ if( !isScopeRun ){
@ -150,7 +151,7 @@ private:
QMainWindow * scope; QMainWindow * scope;
QPushButton * bnOpenScope; QPushButton * bnOpenScope;
QChart * plot; QChart * plot;
QLineSeries * dataTrace; QLineSeries * dataTrace[6];
UpdateTraceThread * updateTraceThread; UpdateTraceThread * updateTraceThread;
QComboBox * cbScopeDigi; QComboBox * cbScopeDigi;
QComboBox * cbScopeCh; QComboBox * cbScopeCh;