move custom thread classes to a new file, move scope to a new class
This commit is contained in:
parent
882627c9f4
commit
15a8abd395
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -66,7 +66,8 @@
|
||||||
"thread": "cpp",
|
"thread": "cpp",
|
||||||
"cinttypes": "cpp",
|
"cinttypes": "cpp",
|
||||||
"typeinfo": "cpp",
|
"typeinfo": "cpp",
|
||||||
"variant": "cpp"
|
"variant": "cpp",
|
||||||
|
"qdatetime": "cpp"
|
||||||
},
|
},
|
||||||
|
|
||||||
"better-comments.multilineComments": true,
|
"better-comments.multilineComments": true,
|
||||||
|
|
|
@ -6,7 +6,7 @@ Digitizer2Gen::Digitizer2Gen(){
|
||||||
}
|
}
|
||||||
|
|
||||||
Digitizer2Gen::~Digitizer2Gen(){
|
Digitizer2Gen::~Digitizer2Gen(){
|
||||||
printf("======== %s \n",__func__);
|
printf("========Digitizer2Gen::%s \n",__func__);
|
||||||
if(isConnected ) CloseDigitizer();
|
if(isConnected ) CloseDigitizer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ int Digitizer2Gen::OpenDigitizer(const char * url){
|
||||||
}
|
}
|
||||||
|
|
||||||
int Digitizer2Gen::CloseDigitizer(){
|
int Digitizer2Gen::CloseDigitizer(){
|
||||||
printf("======== %s \n",__func__);
|
printf("========Digitizer2Gen::%s \n",__func__);
|
||||||
if( isConnected == true ){
|
if( isConnected == true ){
|
||||||
ret = CAEN_FELib_Close(handle);
|
ret = CAEN_FELib_Close(handle);
|
||||||
if (ret != CAEN_FELib_Success) {
|
if (ret != CAEN_FELib_Success) {
|
||||||
|
|
|
@ -18,5 +18,5 @@ LIBS += -lcurl -lCAEN_FELib
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
HEADERS += ClassDigitizer2Gen.h Event.h influxdb.h mainwindow.h digiSettings.h Digiparameters.h
|
HEADERS += ClassDigitizer2Gen.h Event.h influxdb.h mainwindow.h digiSettings.h Digiparameters.h scope.h manyThread.h
|
||||||
SOURCES += ClassDigitizer2Gen.cpp influxdb.cpp main.cpp mainwindow.cpp digiSettings.cpp
|
SOURCES += ClassDigitizer2Gen.cpp influxdb.cpp main.cpp mainwindow.cpp digiSettings.cpp scope.cpp
|
||||||
|
|
|
@ -660,5 +660,4 @@ DigiSettings::~DigiSettings(){
|
||||||
if( cbCh[iDig][i] != NULL) delete cbCh[iDig][i];
|
if( cbCh[iDig][i] != NULL) delete cbCh[iDig][i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
638
mainwindow.cpp
638
mainwindow.cpp
|
@ -13,6 +13,7 @@
|
||||||
#include <QChartView>
|
#include <QChartView>
|
||||||
#include <QValueAxis>
|
#include <QValueAxis>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -31,8 +32,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
||||||
digiSetting = NULL;
|
digiSetting = NULL;
|
||||||
readDataThread = NULL;
|
readDataThread = NULL;
|
||||||
|
|
||||||
SetUpPlot();
|
scope = NULL;
|
||||||
|
|
||||||
QWidget * mainLayoutWidget = new QWidget(this);
|
QWidget * mainLayoutWidget = new QWidget(this);
|
||||||
setCentralWidget(mainLayoutWidget);
|
setCentralWidget(mainLayoutWidget);
|
||||||
QVBoxLayout * layoutMain = new QVBoxLayout(mainLayoutWidget);
|
QVBoxLayout * layoutMain = new QVBoxLayout(mainLayoutWidget);
|
||||||
|
@ -60,7 +61,15 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
||||||
|
|
||||||
bnOpenScope = new QPushButton("Open scope", this);
|
bnOpenScope = new QPushButton("Open scope", this);
|
||||||
bnOpenScope->setEnabled(false);
|
bnOpenScope->setEnabled(false);
|
||||||
connect(bnOpenScope, &QPushButton::clicked, this, &MainWindow::OpenScope);
|
connect(bnOpenScope, &QPushButton::clicked, this, [=](){
|
||||||
|
if( digi ){
|
||||||
|
if( !scope ){
|
||||||
|
scope = new Scope(digi, nDigi, readDataThread, this);
|
||||||
|
}else{
|
||||||
|
scope->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
bnOpenDigitizers = new QPushButton("Open Digitizers", this);
|
bnOpenDigitizers = new QPushButton("Open Digitizers", this);
|
||||||
connect(bnOpenDigitizers, SIGNAL(clicked()), this, SLOT(OpenDigitizers()));
|
connect(bnOpenDigitizers, SIGNAL(clicked()), this, SLOT(OpenDigitizers()));
|
||||||
|
@ -76,6 +85,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
||||||
bnSOLSettings = new QPushButton("SOLARIS Settings", this);
|
bnSOLSettings = new QPushButton("SOLARIS Settings", this);
|
||||||
bnSOLSettings->setEnabled(false);
|
bnSOLSettings->setEnabled(false);
|
||||||
|
|
||||||
|
//QPushButton * newScope = new QPushButton("Scope2", this);
|
||||||
|
|
||||||
|
|
||||||
layout1->addWidget(bnProgramSettings, 0, 0);
|
layout1->addWidget(bnProgramSettings, 0, 0);
|
||||||
layout1->addWidget(bnNewExp, 0, 1);
|
layout1->addWidget(bnNewExp, 0, 1);
|
||||||
layout1->addWidget(lExpName, 0, 2);
|
layout1->addWidget(lExpName, 0, 2);
|
||||||
|
@ -85,6 +97,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
||||||
layout1->addWidget(bnOpenDigitizers, 1, 1);
|
layout1->addWidget(bnOpenDigitizers, 1, 1);
|
||||||
layout1->addWidget(bnCloseDigitizers, 1, 2, 1, 2);
|
layout1->addWidget(bnCloseDigitizers, 1, 2, 1, 2);
|
||||||
|
|
||||||
|
//layout1->addWidget(newScope, 2, 0);
|
||||||
layout1->addWidget(bnDigiSettings, 2, 1);
|
layout1->addWidget(bnDigiSettings, 2, 1);
|
||||||
layout1->addWidget(bnSOLSettings, 2, 2, 1, 2);
|
layout1->addWidget(bnSOLSettings, 2, 2, 1, 2);
|
||||||
|
|
||||||
|
@ -94,6 +107,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
|
||||||
layout1->setColumnStretch(2, 1);
|
layout1->setColumnStretch(2, 1);
|
||||||
layout1->setColumnStretch(3, 1);
|
layout1->setColumnStretch(3, 1);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,22 +195,13 @@ MainWindow::~MainWindow(){
|
||||||
//delete bnDigiSettings;
|
//delete bnDigiSettings;
|
||||||
//delete bnNewExp;
|
//delete bnNewExp;
|
||||||
//delete logInfo;
|
//delete logInfo;
|
||||||
|
printf("- %s\n", __func__);
|
||||||
StopScope();
|
|
||||||
|
|
||||||
updateTraceThread->Stop();
|
|
||||||
updateTraceThread->quit();
|
|
||||||
updateTraceThread->wait();
|
|
||||||
delete updateTraceThread;
|
|
||||||
|
|
||||||
for( int i = 0; i < 6; i++) delete dataTrace[i];
|
|
||||||
//delete [] dataTrace; /// dataTrace must be deleted before plot
|
|
||||||
delete plot;
|
|
||||||
|
|
||||||
//---- need manually delete
|
|
||||||
if( digiSetting != NULL ) delete digiSetting;
|
|
||||||
|
|
||||||
CloseDigitizers();
|
CloseDigitizers();
|
||||||
|
|
||||||
|
//---- need manually delete
|
||||||
|
if( scope != NULL ) delete scope;
|
||||||
|
if( digiSetting != NULL ) delete digiSetting;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,14 +299,14 @@ void MainWindow::OpenDigitizers(){
|
||||||
bnOpenDigitizers->setEnabled(false);
|
bnOpenDigitizers->setEnabled(false);
|
||||||
bnOpenDigitizers->setStyleSheet("");
|
bnOpenDigitizers->setStyleSheet("");
|
||||||
|
|
||||||
/// set scope digitizer
|
///// set scope digitizer
|
||||||
allowChange = false;
|
//allowChange = false;
|
||||||
cbScopeDigi->clear(); ///this will also trigger QComboBox::currentIndexChanged
|
//cbScopeDigi->clear(); ///this will also trigger QComboBox::currentIndexChanged
|
||||||
cbScopeCh->clear();
|
//cbScopeCh->clear();
|
||||||
for( int i = 0 ; i < nDigi; i++) {
|
//for( int i = 0 ; i < nDigi; i++) {
|
||||||
cbScopeDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i);
|
// cbScopeDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i);
|
||||||
}
|
//}
|
||||||
allowChange = true;
|
//allowChange = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,13 +314,13 @@ void MainWindow::CloseDigitizers(){
|
||||||
|
|
||||||
if( digi == NULL) return;
|
if( digi == NULL) return;
|
||||||
|
|
||||||
for( int i = 0; i < nDigi; i++){
|
for( int i = 0; i < nDigi; i++){
|
||||||
|
if( digi[i] == NULL) return;
|
||||||
digi[i]->CloseDigitizer();
|
digi[i]->CloseDigitizer();
|
||||||
|
|
||||||
delete digi[i];
|
delete digi[i];
|
||||||
|
|
||||||
LogMsg("Closed Digitizer : " + QString::number(digiSerialNum[0]));
|
LogMsg("Closed Digitizer : " + QString::number(digiSerialNum[0]));
|
||||||
|
|
||||||
digiSerialNum.clear();
|
digiSerialNum.clear();
|
||||||
|
|
||||||
bnOpenDigitizers->setEnabled(true);
|
bnOpenDigitizers->setEnabled(true);
|
||||||
|
@ -336,589 +341,12 @@ void MainWindow::CloseDigitizers(){
|
||||||
delete [] readDataThread;
|
delete [] readDataThread;
|
||||||
digi = NULL;
|
digi = NULL;
|
||||||
readDataThread = NULL;
|
readDataThread = NULL;
|
||||||
nDigi = 0;
|
|
||||||
|
|
||||||
bnOpenDigitizers->setFocus();
|
bnOpenDigitizers->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
//^###################################################################### Open Scope
|
//^###################################################################### Open Scope
|
||||||
|
|
||||||
//TODO ==== seperate Scope into a Scrop Panel class.
|
|
||||||
|
|
||||||
void MainWindow::OpenScope(){
|
|
||||||
|
|
||||||
if( digi ) {
|
|
||||||
//*---- get digi setting
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
if( digi[iDigi]->IsDummy() ) return;
|
|
||||||
|
|
||||||
//digi[iDigi]->Reset();
|
|
||||||
//digi[iDigi]->ProgramPHA(false);
|
|
||||||
|
|
||||||
StartScope(iDigi);
|
|
||||||
|
|
||||||
bnStartACQ->setEnabled(false);
|
|
||||||
bnStopACQ->setEnabled(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
scope->show();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::ReadScopeSettings(int iDigi, int ch){
|
|
||||||
if( !digi[iDigi] && digi[iDigi]->IsDummy() ) return;
|
|
||||||
|
|
||||||
printf("%s\n", __func__);
|
|
||||||
|
|
||||||
allowChange = false;
|
|
||||||
|
|
||||||
for( int i = 0 ; i < 2; i++){
|
|
||||||
ScopeReadComboBoxValue(iDigi, ch, cbAnaProbe[i], DIGIPARA::CH::AnalogProbe[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int i = 0 ; i < 4; i++){
|
|
||||||
ScopeReadComboBoxValue(iDigi, ch, cbDigProbe[i], DIGIPARA::CH::DigitalProbe[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopeReadComboBoxValue(iDigi, ch, cbPolarity, DIGIPARA::CH::Polarity);
|
|
||||||
ScopeReadComboBoxValue(iDigi, ch, cbWaveRes, DIGIPARA::CH::WaveResolution);
|
|
||||||
ScopeReadComboBoxValue(iDigi, ch, cbTrapPeakAvg, DIGIPARA::CH::EnergyFilterPeakingAvg);
|
|
||||||
ScopeReadComboBoxValue(iDigi, ch, cbBaselineAvg, DIGIPARA::CH::EnergyFilterBaselineAvg);
|
|
||||||
ScopeReadComboBoxValue(iDigi, ch, cbLowFreqFilter, DIGIPARA::CH::EnergyFilterLowFreqFilter);
|
|
||||||
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbRL, DIGIPARA::CH::RecordLength);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbPT, DIGIPARA::CH::PreTrigger);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbDCOffset, DIGIPARA::CH::DC_Offset);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbThreshold, DIGIPARA::CH::TriggerThreshold);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbTimeRiseTime, DIGIPARA::CH::TimeFilterRiseTime);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbTimeGuard, DIGIPARA::CH::TimeFilterRetriggerGuard);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbTrapRiseTime, DIGIPARA::CH::EnergyFilterRiseTime);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbTrapFlatTop, DIGIPARA::CH::EnergyFilterFlatTop);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbTrapPoleZero, DIGIPARA::CH::EnergyFilterPoleZero);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbEnergyFineGain, DIGIPARA::CH::EnergyFilterFineGain);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbTrapPeaking, DIGIPARA::CH::EnergyFilterPeakingPosition);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbBaselineGuard, DIGIPARA::CH::EnergyFilterBaselineGuard);
|
|
||||||
ScopeReadSpinBoxValue(iDigi, ch, sbPileUpGuard, DIGIPARA::CH::EnergyFilterPileUpGuard);
|
|
||||||
|
|
||||||
allowChange = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::StartScope(int iDigi){
|
|
||||||
|
|
||||||
if( !digi ) return;
|
|
||||||
if( digi[iDigi]->IsDummy() ) return;
|
|
||||||
|
|
||||||
printf("%s\n", __func__);
|
|
||||||
|
|
||||||
int ch = cbScopeCh->currentIndex();
|
|
||||||
|
|
||||||
//*---- set digitizer to take full trace; since in scope mode, no data saving, speed would be fast (How fast?)
|
|
||||||
//* when the input rate is faster than trigger rate, Digitizer will stop data taking.
|
|
||||||
|
|
||||||
ReadScopeSettings(iDigi, ch);
|
|
||||||
|
|
||||||
digi[iDigi]->WriteChValue("0..63", DIGIPARA::CH::ChannelEnable, "false");
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::ChannelEnable, "true");
|
|
||||||
digi[iDigi]->SetPHADataFormat(0);
|
|
||||||
|
|
||||||
digi[iDigi]->StartACQ();
|
|
||||||
|
|
||||||
readDataThread[iDigi]->SetScopeRun(true);
|
|
||||||
readDataThread[iDigi]->start();
|
|
||||||
|
|
||||||
updateTraceThread->start();
|
|
||||||
|
|
||||||
ScopeControlOnOff(false);
|
|
||||||
|
|
||||||
allowChange = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::StopScope(){
|
|
||||||
|
|
||||||
printf("%s\n", __func__);
|
|
||||||
|
|
||||||
updateTraceThread->Stop();
|
|
||||||
updateTraceThread->quit();
|
|
||||||
updateTraceThread->wait();
|
|
||||||
|
|
||||||
if(digi){
|
|
||||||
for(int i = 0; i < nDigi; i++){
|
|
||||||
if( digi[i]->IsDummy() ) continue;
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[i]->StopACQ();
|
|
||||||
digi[i]->WriteChValue("0..63", DIGIPARA::CH::ChannelEnable, "true");
|
|
||||||
digiMTX.unlock();
|
|
||||||
|
|
||||||
readDataThread[i]->quit();
|
|
||||||
readDataThread[i]->wait();
|
|
||||||
|
|
||||||
}
|
|
||||||
bnStartACQ->setEnabled(true);
|
|
||||||
bnStopACQ->setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopeControlOnOff(true);
|
|
||||||
allowChange = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::UpdateScope(){
|
|
||||||
|
|
||||||
if( scope->isVisible() == false) return;
|
|
||||||
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
int sample2ns = DIGIPARA::TraceStep * (1 << cbWaveRes->currentIndex());
|
|
||||||
|
|
||||||
if( digi ){
|
|
||||||
digiMTX.lock();
|
|
||||||
unsigned int traceLength = digi[iDigi]->evt->traceLenght;
|
|
||||||
unsigned int dataLength = dataTrace[0]->count();
|
|
||||||
|
|
||||||
//---- remove all points
|
|
||||||
for( int j = 0; j < 6; j++ ) dataTrace[j]->removePoints(0, dataLength);
|
|
||||||
|
|
||||||
for( unsigned int i = 0 ; i < traceLength; i++){
|
|
||||||
for( int j = 0; j < 2; j++) dataTrace[j]->append(sample2ns * i, digi[iDigi]->evt->analog_probes[j][i]);
|
|
||||||
for( int j = 2; j < 6; j++) dataTrace[j]->append(sample2ns * i, (j-1)*1000 + 4000 * digi[iDigi]->evt->digital_probes[j-2][i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
digiMTX.unlock();
|
|
||||||
|
|
||||||
plot->axes(Qt::Horizontal).first()->setRange(0, sample2ns * traceLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::ProbeChange(QComboBox * cb[], const int size ){
|
|
||||||
|
|
||||||
QStandardItemModel * model[size] = {NULL};
|
|
||||||
for( int i = 0; i < size; i++){
|
|
||||||
model[i] = qobject_cast<QStandardItemModel*>(cb[i]->model());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enable all items
|
|
||||||
for( int i = 0; i < cb[0]->count(); i++) {
|
|
||||||
for( int j = 0; j < size; j ++ ) model[j]->item(i)->setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int i = 0; i < size; i++){
|
|
||||||
int index = cb[i]->currentIndex();
|
|
||||||
for( int j = 0; j < size; j++){
|
|
||||||
if( i == j ) continue;
|
|
||||||
model[j]->item(index)->setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
digiMTX.lock();
|
|
||||||
if( size == 2) {// analog probes
|
|
||||||
for( int j = 0; j < 2; j++ )dataTrace[j]->setName(cb[j]->currentText());
|
|
||||||
}
|
|
||||||
if( size == 4){ // digitial probes
|
|
||||||
for( int j = 2; j < 6; j++ )dataTrace[j]->setName(cb[j-2]->currentText());
|
|
||||||
}
|
|
||||||
digiMTX.unlock();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::ScopeControlOnOff(bool on){
|
|
||||||
bnScopeStop->setEnabled(!on);
|
|
||||||
|
|
||||||
bnScopeStart->setEnabled(on);
|
|
||||||
bnScopeReset->setEnabled(on);
|
|
||||||
bnScopeReadSettings->setEnabled(on);
|
|
||||||
|
|
||||||
sbRL->setEnabled(on);
|
|
||||||
sbPT->setEnabled(on);
|
|
||||||
sbDCOffset->setEnabled(on);
|
|
||||||
sbThreshold->setEnabled(on);
|
|
||||||
sbTimeRiseTime->setEnabled(on);
|
|
||||||
sbTimeGuard->setEnabled(on);
|
|
||||||
sbTrapRiseTime->setEnabled(on);
|
|
||||||
sbTrapFlatTop->setEnabled(on);
|
|
||||||
sbTrapPoleZero->setEnabled(on);
|
|
||||||
sbEnergyFineGain->setEnabled(on);
|
|
||||||
sbTrapPeaking->setEnabled(on);
|
|
||||||
cbPolarity->setEnabled(on);
|
|
||||||
cbWaveRes->setEnabled(on);
|
|
||||||
cbTrapPeakAvg->setEnabled(on);
|
|
||||||
|
|
||||||
sbBaselineGuard->setEnabled(on);
|
|
||||||
sbPileUpGuard->setEnabled(on);
|
|
||||||
cbBaselineAvg->setEnabled(on);
|
|
||||||
cbLowFreqFilter->setEnabled(on);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::ScopeReadSpinBoxValue(int iDigi, int ch, QSpinBox *sb, std::string digPara){
|
|
||||||
std::string ans = digi[iDigi]->ReadChValue(std::to_string(ch), digPara);
|
|
||||||
sb->setValue(atoi(ans.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::ScopeReadComboBoxValue(int iDigi, int ch, QComboBox *cb, std::string digPara){
|
|
||||||
std::string ans = digi[iDigi]->ReadChValue(std::to_string(ch), digPara);
|
|
||||||
int index = cb->findData(QString::fromStdString(ans));
|
|
||||||
if( index >= 0 && index < cb->count()) {
|
|
||||||
cb->setCurrentIndex(index);
|
|
||||||
}else{
|
|
||||||
qDebug() << QString::fromStdString(ans);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::ScopeMakeSpinBox(QSpinBox *sb, QString str, QGridLayout *layout, int row, int col, int min, int max, int step, std::string digPara){
|
|
||||||
QLabel * lb = new QLabel(str, scope);
|
|
||||||
lb->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
|
||||||
layout->addWidget(lb, row, col);
|
|
||||||
sb->setMinimum(min);
|
|
||||||
sb->setMaximum(max);
|
|
||||||
sb->setSingleStep(abs(step));
|
|
||||||
layout->addWidget(sb, row, col+1);
|
|
||||||
connect(sb, &QSpinBox::valueChanged, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
if( step > 1 ) sb->setValue(step*((sb->value() + step - 1)/step));
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(cbScopeCh->currentIndex()), digPara, std::to_string(sb->value()));
|
|
||||||
digiMTX.unlock();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::ScopeMakeComoBox(QComboBox *cb, QString str, QGridLayout *layout, int row, int col, std::string digPara){
|
|
||||||
QLabel * lb = new QLabel(str, scope);
|
|
||||||
lb->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
|
||||||
layout->addWidget(lb, row, col);
|
|
||||||
layout->addWidget(cb, row, col+1);
|
|
||||||
connect(cb, &QComboBox::currentIndexChanged, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(cbScopeCh->currentIndex()), digPara, cb->currentData().toString().toStdString());
|
|
||||||
digiMTX.unlock();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::SetUpPlot(){ //@--- this function run at start up
|
|
||||||
scope = new QMainWindow(this);
|
|
||||||
scope->setWindowTitle("Scope");
|
|
||||||
scope->setGeometry(0, 0, 1000, 800);
|
|
||||||
scope->setWindowFlags( scope->windowFlags() & ~Qt::WindowCloseButtonHint );
|
|
||||||
|
|
||||||
allowChange = false;
|
|
||||||
|
|
||||||
plot = new QChart();
|
|
||||||
for( int i = 0; i < 6; i++) {
|
|
||||||
dataTrace[i] = new QLineSeries();
|
|
||||||
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->createDefaultAxes(); /// this must be after addSeries();
|
|
||||||
/// this must be after createDefaultAxes();
|
|
||||||
QValueAxis * yaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Vertical).first());
|
|
||||||
QValueAxis * xaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Horizontal).first());
|
|
||||||
yaxis->setTickCount(6);
|
|
||||||
yaxis->setTickInterval(16384);
|
|
||||||
yaxis->setRange(-16384, 65536);
|
|
||||||
yaxis->setLabelFormat("%.0f");
|
|
||||||
|
|
||||||
xaxis->setRange(0, 5000);
|
|
||||||
xaxis->setTickCount(11);
|
|
||||||
xaxis->setLabelFormat("%.0f");
|
|
||||||
xaxis->setTitleText("Time [ns]");
|
|
||||||
|
|
||||||
updateTraceThread = new UpdateTraceThread();
|
|
||||||
connect(updateTraceThread, &UpdateTraceThread::updateTrace, this, &MainWindow::UpdateScope);
|
|
||||||
|
|
||||||
//*================ add Widgets
|
|
||||||
int rowID = -1;
|
|
||||||
QWidget * layoutWidget = new QWidget(scope);
|
|
||||||
scope->setCentralWidget(layoutWidget);
|
|
||||||
QGridLayout * layout = new QGridLayout(layoutWidget);
|
|
||||||
layoutWidget->setLayout(layout);
|
|
||||||
|
|
||||||
//------------ Digitizer + channel selection
|
|
||||||
rowID ++;
|
|
||||||
cbScopeDigi = new QComboBox(scope);
|
|
||||||
cbScopeCh = new QComboBox(scope);
|
|
||||||
layout->addWidget(cbScopeDigi, rowID, 0);
|
|
||||||
layout->addWidget(cbScopeCh, rowID, 1);
|
|
||||||
|
|
||||||
connect(cbScopeDigi, &QComboBox::currentIndexChanged, this, [=](){
|
|
||||||
//if( allowChange ) StopScope();
|
|
||||||
int index = cbScopeDigi->currentIndex();
|
|
||||||
if( index == -1 ) return;
|
|
||||||
for( int i = 0; i < digi[index]->GetNChannels(); i++){
|
|
||||||
cbScopeCh->addItem("ch-" + QString::number(i), i);
|
|
||||||
}
|
|
||||||
//if( allowChange )StartScope(index);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(cbScopeCh, &QComboBox::currentIndexChanged, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
int ch = cbScopeCh->currentIndex();
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[iDigi]->WriteChValue("0..63", DIGIPARA::CH::ChannelEnable, "false");
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::ChannelEnable, "true");
|
|
||||||
ReadScopeSettings(iDigi, ch);
|
|
||||||
digiMTX.unlock();
|
|
||||||
});
|
|
||||||
|
|
||||||
bnScopeReset = new QPushButton("ReProgram Digitizer", scope);
|
|
||||||
layout->addWidget(bnScopeReset, rowID, 2);
|
|
||||||
connect(bnScopeReset, &QPushButton::clicked, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
digi[iDigi]->Reset();
|
|
||||||
digi[iDigi]->ProgramPHA(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
bnScopeReadSettings = new QPushButton("Read Ch. Settings", scope);
|
|
||||||
layout->addWidget(bnScopeReadSettings, rowID, 3);
|
|
||||||
connect(bnScopeReadSettings, &QPushButton::clicked, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
ReadScopeSettings(cbScopeDigi->currentIndex(), cbScopeCh->currentIndex());
|
|
||||||
});
|
|
||||||
|
|
||||||
//TODO----- add copy settings and paste settings
|
|
||||||
QCheckBox * chkSetAllChannel = new QCheckBox("apply to all channels", scope);
|
|
||||||
layout->addWidget(chkSetAllChannel, rowID, 4);
|
|
||||||
|
|
||||||
//------------ Probe selection
|
|
||||||
rowID ++;
|
|
||||||
//TODO --- add None
|
|
||||||
cbAnaProbe[0] = new QComboBox(scope);
|
|
||||||
cbAnaProbe[0]->addItem("ADC Input", "ADCInput");
|
|
||||||
cbAnaProbe[0]->addItem("Time Filter", "TimeFilter");
|
|
||||||
cbAnaProbe[0]->addItem("Trapazoid", "EnergyFilter");
|
|
||||||
cbAnaProbe[0]->addItem("Trap. Baseline", "EnergyFilterBaseline");
|
|
||||||
cbAnaProbe[0]->addItem("Trap. - Baseline", "EnergyFilterMinusBaseline");
|
|
||||||
|
|
||||||
cbAnaProbe[1] = new QComboBox(scope);
|
|
||||||
for( int i = 0; i < cbAnaProbe[0]->count() ; i++) cbAnaProbe[1]->addItem(cbAnaProbe[0]->itemText(i), cbAnaProbe[0]->itemData(i));
|
|
||||||
|
|
||||||
connect(cbAnaProbe[0], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbAnaProbe, 2);});
|
|
||||||
connect(cbAnaProbe[1], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbAnaProbe, 2);});
|
|
||||||
|
|
||||||
cbAnaProbe[0]->setCurrentIndex(1); ///trigger the AnaProbeChange
|
|
||||||
cbAnaProbe[0]->setCurrentIndex(0);
|
|
||||||
cbAnaProbe[1]->setCurrentIndex(4);
|
|
||||||
|
|
||||||
connect(cbAnaProbe[0], &QComboBox::currentIndexChanged, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
int ch = cbScopeCh->currentIndex();
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveAnalogProbe0, (cbAnaProbe[0]->currentData()).toString().toStdString());
|
|
||||||
digiMTX.unlock();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(cbAnaProbe[1], &QComboBox::currentIndexChanged, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
int ch = cbScopeCh->currentIndex();
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveAnalogProbe1, (cbAnaProbe[1]->currentData()).toString().toStdString());
|
|
||||||
digiMTX.unlock();
|
|
||||||
});
|
|
||||||
|
|
||||||
//TODO --- add None
|
|
||||||
cbDigProbe[0] = new QComboBox(scope);
|
|
||||||
cbDigProbe[0]->addItem("Trigger", "Trigger");
|
|
||||||
cbDigProbe[0]->addItem("Time Filter Armed", "TimeFilterArmed");
|
|
||||||
cbDigProbe[0]->addItem("ReTrigger Guard", "ReTriggerGuard");
|
|
||||||
cbDigProbe[0]->addItem("Trap. basline Freeze", "EnergyFilterBaselineFreeze");
|
|
||||||
cbDigProbe[0]->addItem("Peaking", "EnergyFilterPeaking");
|
|
||||||
cbDigProbe[0]->addItem("Peak Ready", "EnergyFilterPeakReady");
|
|
||||||
cbDigProbe[0]->addItem("Pile-up Guard", "EnergyFilterPileUpGuard");
|
|
||||||
cbDigProbe[0]->addItem("Event Pile Up", "EventPileUp");
|
|
||||||
cbDigProbe[0]->addItem("ADC Saturate", "ADCSaturation");
|
|
||||||
cbDigProbe[0]->addItem("ADC Sat. Protection", "ADCSaturationProtection");
|
|
||||||
cbDigProbe[0]->addItem("Post Sat. Event", "PostSaturationEvent");
|
|
||||||
cbDigProbe[0]->addItem("Trap. Saturate", "EnergylterSaturation");
|
|
||||||
cbDigProbe[0]->addItem("ACQ Inhibit", "AcquisitionInhibit");
|
|
||||||
|
|
||||||
cbDigProbe[1] = new QComboBox(scope);
|
|
||||||
cbDigProbe[2] = new QComboBox(scope);
|
|
||||||
cbDigProbe[3] = new QComboBox(scope);
|
|
||||||
for( int i = 0; i < cbDigProbe[0]->count() ; i++) {
|
|
||||||
cbDigProbe[1]->addItem(cbDigProbe[0]->itemText(i), cbDigProbe[0]->itemData(i));
|
|
||||||
cbDigProbe[2]->addItem(cbDigProbe[0]->itemText(i), cbDigProbe[0]->itemData(i));
|
|
||||||
cbDigProbe[3]->addItem(cbDigProbe[0]->itemText(i), cbDigProbe[0]->itemData(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(cbDigProbe[0], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbDigProbe, 4);});
|
|
||||||
connect(cbDigProbe[1], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbDigProbe, 4);});
|
|
||||||
connect(cbDigProbe[2], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbDigProbe, 4);});
|
|
||||||
connect(cbDigProbe[3], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbDigProbe, 4);});
|
|
||||||
|
|
||||||
cbDigProbe[0]->setCurrentIndex(1); ///trigger the DigProbeChange
|
|
||||||
cbDigProbe[0]->setCurrentIndex(0);
|
|
||||||
cbDigProbe[1]->setCurrentIndex(4);
|
|
||||||
cbDigProbe[2]->setCurrentIndex(5);
|
|
||||||
cbDigProbe[3]->setCurrentIndex(6);
|
|
||||||
|
|
||||||
connect(cbDigProbe[0], &QComboBox::currentIndexChanged, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
int ch = cbScopeCh->currentIndex();
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveDigitalProbe0, (cbDigProbe[0]->currentData()).toString().toStdString());
|
|
||||||
digiMTX.unlock();
|
|
||||||
});
|
|
||||||
connect(cbDigProbe[1], &QComboBox::currentIndexChanged, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
int ch = cbScopeCh->currentIndex();
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveDigitalProbe1, (cbDigProbe[1]->currentData()).toString().toStdString());
|
|
||||||
digiMTX.unlock();
|
|
||||||
});
|
|
||||||
connect(cbDigProbe[2], &QComboBox::currentIndexChanged, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
int ch = cbScopeCh->currentIndex();
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveDigitalProbe2, (cbDigProbe[2]->currentData()).toString().toStdString());
|
|
||||||
digiMTX.unlock();
|
|
||||||
});
|
|
||||||
connect(cbDigProbe[3], &QComboBox::currentIndexChanged, this, [=](){
|
|
||||||
if( !allowChange ) return;
|
|
||||||
int iDigi = cbScopeDigi->currentIndex();
|
|
||||||
int ch = cbScopeCh->currentIndex();
|
|
||||||
digiMTX.lock();
|
|
||||||
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveDigitalProbe3, (cbDigProbe[3]->currentData()).toString().toStdString());
|
|
||||||
digiMTX.unlock();
|
|
||||||
});
|
|
||||||
|
|
||||||
layout->addWidget(cbAnaProbe[0], rowID, 0);
|
|
||||||
layout->addWidget(cbAnaProbe[1], rowID, 1);
|
|
||||||
|
|
||||||
layout->addWidget(cbDigProbe[0], rowID, 2);
|
|
||||||
layout->addWidget(cbDigProbe[1], rowID, 3);
|
|
||||||
layout->addWidget(cbDigProbe[2], rowID, 4);
|
|
||||||
layout->addWidget(cbDigProbe[3], rowID, 5);
|
|
||||||
|
|
||||||
rowID ++;
|
|
||||||
{//------------ wave settings
|
|
||||||
QGroupBox * box = new QGroupBox("Channel Settings (need ACQ stop)", scope);
|
|
||||||
layout->addWidget(box, rowID, 0, 1, 6);
|
|
||||||
|
|
||||||
QGridLayout * bLayout = new QGridLayout(box);
|
|
||||||
bLayout->setSpacing(0);
|
|
||||||
|
|
||||||
sbRL = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbRL, "Record Lenght [ns] ", bLayout, 0, 0, 32, 648000, DIGIPARA::TraceStep, DIGIPARA::CH::RecordLength);
|
|
||||||
|
|
||||||
sbThreshold = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbThreshold, "Threshold [LSB] ", bLayout, 0, 2, 0, 8191, -20, DIGIPARA::CH::TriggerThreshold);
|
|
||||||
|
|
||||||
cbPolarity = new QComboBox(scope);
|
|
||||||
cbPolarity->addItem("Pos. +", "Positive");
|
|
||||||
cbPolarity->addItem("Neg. -", "Negative");
|
|
||||||
ScopeMakeComoBox(cbPolarity, "Polarity ", bLayout, 0, 4, DIGIPARA::CH::Polarity);
|
|
||||||
|
|
||||||
cbWaveRes = new QComboBox(scope);
|
|
||||||
cbWaveRes->addItem(" 8 ns", "RES8");
|
|
||||||
cbWaveRes->addItem("16 ns", "RES16");
|
|
||||||
cbWaveRes->addItem("32 ns", "RES32");
|
|
||||||
cbWaveRes->addItem("64 ns", "RES64");
|
|
||||||
ScopeMakeComoBox(cbWaveRes, "Wave Re. ", bLayout, 0, 6, DIGIPARA::CH::WaveResolution);
|
|
||||||
|
|
||||||
//------------------ next row
|
|
||||||
sbPT = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbPT, "Pre Trigger [ns] ", bLayout, 1, 0, 32, 32000, DIGIPARA::TraceStep, DIGIPARA::CH::PreTrigger);
|
|
||||||
|
|
||||||
sbDCOffset = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbDCOffset, "DC offset [%] ", bLayout, 1, 2, 0, 100, -10, DIGIPARA::CH::DC_Offset);
|
|
||||||
|
|
||||||
sbTimeRiseTime = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbTimeRiseTime, "Trigger Rise Time [ns] ", bLayout, 1, 4, 32, 2000, DIGIPARA::TraceStep, DIGIPARA::CH::TimeFilterRiseTime);
|
|
||||||
|
|
||||||
sbTimeGuard = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbTimeGuard, "Trigger Guard [ns] ", bLayout, 1, 6, 0, 8000, DIGIPARA::TraceStep, DIGIPARA::CH::TimeFilterRetriggerGuard);
|
|
||||||
|
|
||||||
//----------------- next row
|
|
||||||
sbTrapRiseTime = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbTrapRiseTime, "Trap. Rise Time [ns] ", bLayout, 2, 0, 32, 13000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterRiseTime);
|
|
||||||
|
|
||||||
sbTrapFlatTop = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbTrapFlatTop, "Trap. Flat Top [ns] ", bLayout, 2, 2, 32, 3000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterFlatTop);
|
|
||||||
|
|
||||||
sbTrapPoleZero = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbTrapPoleZero, "Trap. Pole Zero [ns] ", bLayout, 2, 4, 32, 524000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterPoleZero);
|
|
||||||
|
|
||||||
sbEnergyFineGain = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbEnergyFineGain, "Energy Fine Gain ", bLayout, 2, 6, 1, 10, -1, DIGIPARA::CH::EnergyFilterFineGain);
|
|
||||||
|
|
||||||
//----------------- next row
|
|
||||||
sbTrapPeaking = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbTrapPeaking, "Trap. Peaking [%] ", bLayout, 3, 0, 1, 100, -10, DIGIPARA::CH::EnergyFilterPeakingPosition);
|
|
||||||
|
|
||||||
cbTrapPeakAvg = new QComboBox(scope);
|
|
||||||
cbTrapPeakAvg->addItem(" 1 sample", "OneShot");
|
|
||||||
cbTrapPeakAvg->addItem(" 4 sample", "LowAVG");
|
|
||||||
cbTrapPeakAvg->addItem("16 sample", "MediumAVG");
|
|
||||||
cbTrapPeakAvg->addItem("64 sample", "HighAVG");
|
|
||||||
ScopeMakeComoBox(cbTrapPeakAvg, "Trap. Peaking ", bLayout, 3, 2, DIGIPARA::CH::EnergyFilterPeakingAvg);
|
|
||||||
|
|
||||||
sbBaselineGuard = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbBaselineGuard, "Baseline Guard [ns] ", bLayout, 3, 4, 0, 8000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterBaselineGuard);
|
|
||||||
|
|
||||||
cbBaselineAvg = new QComboBox(scope);
|
|
||||||
cbBaselineAvg->addItem(" 0 samp.", "Fixed");
|
|
||||||
cbBaselineAvg->addItem(" 16 samp.", "VeryLow");
|
|
||||||
cbBaselineAvg->addItem(" 64 samp.", "Low");
|
|
||||||
cbBaselineAvg->addItem(" 256 samp.", "MediumLow");
|
|
||||||
cbBaselineAvg->addItem(" 1024 samp.", "Medium");
|
|
||||||
cbBaselineAvg->addItem(" 4096 samp.", "MediumHigh");
|
|
||||||
cbBaselineAvg->addItem("16384 samp.", "High");
|
|
||||||
ScopeMakeComoBox(cbBaselineAvg, "Baseline Avg ", bLayout, 3, 6, DIGIPARA::CH::EnergyFilterBaselineAvg);
|
|
||||||
//----------------
|
|
||||||
|
|
||||||
sbPileUpGuard = new QSpinBox(scope);
|
|
||||||
ScopeMakeSpinBox(sbPileUpGuard, "Pile-up Guard [ns] ", bLayout, 4, 0, 0, 64000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterPileUpGuard);
|
|
||||||
|
|
||||||
cbLowFreqFilter = new QComboBox(scope);
|
|
||||||
cbLowFreqFilter->addItem("Disabled", "0");
|
|
||||||
cbLowFreqFilter->addItem("Enabled", "1");
|
|
||||||
ScopeMakeComoBox(cbLowFreqFilter, "Low Freq. Filter ", bLayout, 4, 2, DIGIPARA::CH::EnergyFilterLowFreqFilter);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------ plot view
|
|
||||||
rowID ++;
|
|
||||||
QChartView * plotView = new QChartView(plot);
|
|
||||||
plotView->setRenderHints(QPainter::Antialiasing);
|
|
||||||
layout->addWidget(plotView, rowID, 0, 1, 6);
|
|
||||||
|
|
||||||
//TODO zoom and pan, see Zoom Line example
|
|
||||||
|
|
||||||
//------------ close button
|
|
||||||
rowID ++;
|
|
||||||
bnScopeStart = new QPushButton("Start", scope);
|
|
||||||
layout->addWidget(bnScopeStart, rowID, 0);
|
|
||||||
bnScopeStart->setEnabled(false);
|
|
||||||
connect(bnScopeStart, &QPushButton::clicked, this, [=](){this->StartScope(cbScopeDigi->currentIndex());});
|
|
||||||
|
|
||||||
bnScopeStop = new QPushButton("Stop", scope);
|
|
||||||
layout->addWidget(bnScopeStop, rowID, 1);
|
|
||||||
connect(bnScopeStop, &QPushButton::clicked, this, &MainWindow::StopScope);
|
|
||||||
|
|
||||||
QPushButton * bnClose = new QPushButton("Close", scope);
|
|
||||||
layout->addWidget(bnClose, rowID, 5);
|
|
||||||
connect(bnClose, &QPushButton::clicked, this, &MainWindow::StopScope);
|
|
||||||
connect(bnClose, &QPushButton::clicked, scope, &QMainWindow::close);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//^###################################################################### Open digitizer setting panel
|
//^###################################################################### Open digitizer setting panel
|
||||||
void MainWindow::OpenDigitizersSettings(){
|
void MainWindow::OpenDigitizersSettings(){
|
||||||
LogMsg("Open digitizers Settings Panel");
|
LogMsg("Open digitizers Settings Panel");
|
||||||
|
|
142
mainwindow.h
142
mainwindow.h
|
@ -5,100 +5,25 @@
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QThread>
|
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QMutex>
|
|
||||||
#include <QChart>
|
#include <QChart>
|
||||||
#include <QLineSeries>
|
#include <QLineSeries>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <time.h> // time in nano-sec
|
#include <time.h> // time in nano-sec
|
||||||
|
|
||||||
#include "digiSettings.h"
|
|
||||||
|
|
||||||
#include "ClassDigitizer2Gen.h"
|
#include "ClassDigitizer2Gen.h"
|
||||||
#include "influxdb.h"
|
#include "influxdb.h"
|
||||||
|
|
||||||
static QMutex digiMTX;
|
#include "manyThread.h"
|
||||||
|
|
||||||
//^#===================================================== ReadData Thread
|
|
||||||
class ReadDataThread : public QThread {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
ReadDataThread(Digitizer2Gen * dig, QObject * parent = 0) : QThread(parent){
|
|
||||||
this->digi = dig;
|
|
||||||
isScopeRun = false;
|
|
||||||
}
|
|
||||||
void SetScopeRun(bool onOff) {this->isScopeRun = onOff;}
|
|
||||||
void run(){
|
|
||||||
clock_gettime(CLOCK_REALTIME, &ta);
|
|
||||||
while(true){
|
|
||||||
digiMTX.lock();
|
|
||||||
int ret = digi->ReadData();
|
|
||||||
digiMTX.unlock();
|
|
||||||
|
|
||||||
if( ret == CAEN_FELib_Success){
|
|
||||||
if( !isScopeRun) digi->SaveDataToFile();
|
|
||||||
}else if(ret == CAEN_FELib_Stop){
|
|
||||||
digi->ErrorMsg("No more data");
|
|
||||||
break;
|
|
||||||
}else{
|
|
||||||
digi->ErrorMsg("ReadDataLoop()");
|
|
||||||
digi->evt->ClearTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !isScopeRun ){
|
|
||||||
clock_gettime(CLOCK_REALTIME, &tb);
|
|
||||||
if( tb.tv_sec - ta.tv_sec > 2 ) {
|
|
||||||
emit sendMsg("FileSize : " + QString::number(digi->GetFileSize()/1024./1024.) + " MB");
|
|
||||||
|
|
||||||
//double duration = tb.tv_nsec-ta.tv_nsec + tb.tv_sec*1e+9 - ta.tv_sec*1e+9;
|
|
||||||
//printf("%4d, duration : %10.0f, %6.1f\n", readCount, duration, 1e9/duration);
|
|
||||||
ta = tb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
signals:
|
|
||||||
void sendMsg(const QString &msg);
|
|
||||||
private:
|
|
||||||
Digitizer2Gen * digi;
|
|
||||||
timespec ta, tb;
|
|
||||||
bool isScopeRun;
|
|
||||||
};
|
|
||||||
|
|
||||||
//^#===================================================== UpdateTrace Thread
|
|
||||||
class UpdateTraceThread : public QThread {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
UpdateTraceThread(QObject * parent = 0) : QThread(parent){
|
|
||||||
waitTime = 2;
|
|
||||||
stop = false;
|
|
||||||
}
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
|
#include "digiSettings.h"
|
||||||
|
#include "scope.h"
|
||||||
|
|
||||||
//^#===================================================== MainWindow
|
//^#===================================================== MainWindow
|
||||||
class MainWindow : public QMainWindow{
|
class MainWindow : public QMainWindow{
|
||||||
|
@ -114,18 +39,6 @@ private slots:
|
||||||
void OpenDigitizers();
|
void OpenDigitizers();
|
||||||
void CloseDigitizers();
|
void CloseDigitizers();
|
||||||
|
|
||||||
void OpenScope();
|
|
||||||
void ReadScopeSettings(int iDigi, int ch);
|
|
||||||
void StartScope(int iDigi);
|
|
||||||
void StopScope();
|
|
||||||
void UpdateScope();
|
|
||||||
void ScopeControlOnOff(bool on);
|
|
||||||
void ScopeReadSpinBoxValue(int iDigi, int ch, QSpinBox *sb, std::string digPara);
|
|
||||||
void ScopeReadComboBoxValue(int iDigi, int ch, QComboBox *cb, std::string digPara);
|
|
||||||
void ScopeMakeSpinBox(QSpinBox * sb, QString str, QGridLayout* layout, int row, int col, int min, int max, int step, std::string digPara);
|
|
||||||
void ScopeMakeComoBox(QComboBox * cb, QString str, QGridLayout* layout, int row, int col, std::string digPara);
|
|
||||||
void SetUpPlot();
|
|
||||||
|
|
||||||
void OpenDigitizersSettings();
|
void OpenDigitizersSettings();
|
||||||
|
|
||||||
void ProgramSettings();
|
void ProgramSettings();
|
||||||
|
@ -139,6 +52,13 @@ private slots:
|
||||||
void ChangeExperiment(const QString newExpName);
|
void ChangeExperiment(const QString newExpName);
|
||||||
void CreateRawDataFolderAndLink(const QString newExpName);
|
void CreateRawDataFolderAndLink(const QString newExpName);
|
||||||
|
|
||||||
|
void closeEvent(QCloseEvent * event){
|
||||||
|
if( digiSetting != NULL ) digiSetting->close();
|
||||||
|
if( scope != NULL ) scope->close();
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
signals :
|
signals :
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -153,45 +73,9 @@ private:
|
||||||
QPushButton * bnDigiSettings;
|
QPushButton * bnDigiSettings;
|
||||||
QPushButton * bnSOLSettings;
|
QPushButton * bnSOLSettings;
|
||||||
|
|
||||||
//@------ scope things
|
//@--- new scope
|
||||||
QMainWindow * scope;
|
Scope * scope;
|
||||||
QPushButton * bnOpenScope;
|
QPushButton * bnOpenScope;
|
||||||
QChart * plot;
|
|
||||||
QLineSeries * dataTrace[6];
|
|
||||||
UpdateTraceThread * updateTraceThread;
|
|
||||||
QComboBox * cbScopeDigi;
|
|
||||||
QComboBox * cbScopeCh;
|
|
||||||
QPushButton * bnScopeReset;
|
|
||||||
QPushButton * bnScopeReadSettings;
|
|
||||||
|
|
||||||
|
|
||||||
QPushButton * bnScopeStart;
|
|
||||||
QPushButton * bnScopeStop;
|
|
||||||
|
|
||||||
QComboBox * cbAnaProbe[2];
|
|
||||||
QComboBox * cbDigProbe[4];
|
|
||||||
QSpinBox * sbRL; // record length
|
|
||||||
QSpinBox * sbPT; // pre trigger
|
|
||||||
QSpinBox * sbDCOffset;
|
|
||||||
QSpinBox * sbThreshold;
|
|
||||||
QSpinBox * sbTimeRiseTime;
|
|
||||||
QSpinBox * sbTimeGuard;
|
|
||||||
QSpinBox * sbTrapRiseTime;
|
|
||||||
QSpinBox * sbTrapFlatTop;
|
|
||||||
QSpinBox * sbTrapPoleZero;
|
|
||||||
QSpinBox * sbEnergyFineGain;
|
|
||||||
QSpinBox * sbTrapPeaking;
|
|
||||||
QComboBox * cbPolarity;
|
|
||||||
QComboBox * cbWaveRes;
|
|
||||||
QComboBox * cbTrapPeakAvg;
|
|
||||||
|
|
||||||
QSpinBox * sbBaselineGuard;
|
|
||||||
QSpinBox * sbPileUpGuard;
|
|
||||||
QComboBox * cbBaselineAvg;
|
|
||||||
QComboBox * cbLowFreqFilter;
|
|
||||||
|
|
||||||
bool allowChange;
|
|
||||||
void ProbeChange(QComboBox * cb[], const int size);
|
|
||||||
|
|
||||||
//@------ ACQ things
|
//@------ ACQ things
|
||||||
QPushButton * bnStartACQ;
|
QPushButton * bnStartACQ;
|
||||||
|
|
86
manyThread.h
Normal file
86
manyThread.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
|
||||||
|
#ifndef MANYTHREADS_H
|
||||||
|
#define MANYTHREADS_H
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
#include "ClassDigitizer2Gen.h"
|
||||||
|
|
||||||
|
static QMutex digiMTX;
|
||||||
|
|
||||||
|
//^#===================================================== ReadData Thread
|
||||||
|
class ReadDataThread : public QThread {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ReadDataThread(Digitizer2Gen * dig, QObject * parent = 0) : QThread(parent){
|
||||||
|
this->digi = dig;
|
||||||
|
isScopeRun = false;
|
||||||
|
}
|
||||||
|
void SetScopeRun(bool onOff) {this->isScopeRun = onOff;}
|
||||||
|
void run(){
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ta);
|
||||||
|
while(true){
|
||||||
|
digiMTX.lock();
|
||||||
|
int ret = digi->ReadData();
|
||||||
|
digiMTX.unlock();
|
||||||
|
|
||||||
|
if( ret == CAEN_FELib_Success){
|
||||||
|
if( !isScopeRun) digi->SaveDataToFile();
|
||||||
|
}else if(ret == CAEN_FELib_Stop){
|
||||||
|
digi->ErrorMsg("No more data");
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
digi->ErrorMsg("ReadDataLoop()");
|
||||||
|
digi->evt->ClearTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !isScopeRun ){
|
||||||
|
clock_gettime(CLOCK_REALTIME, &tb);
|
||||||
|
if( tb.tv_sec - ta.tv_sec > 2 ) {
|
||||||
|
emit sendMsg("FileSize : " + QString::number(digi->GetFileSize()/1024./1024.) + " MB");
|
||||||
|
|
||||||
|
//double duration = tb.tv_nsec-ta.tv_nsec + tb.tv_sec*1e+9 - ta.tv_sec*1e+9;
|
||||||
|
//printf("%4d, duration : %10.0f, %6.1f\n", readCount, duration, 1e9/duration);
|
||||||
|
ta = tb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
signals:
|
||||||
|
void sendMsg(const QString &msg);
|
||||||
|
private:
|
||||||
|
Digitizer2Gen * digi;
|
||||||
|
timespec ta, tb;
|
||||||
|
bool isScopeRun;
|
||||||
|
};
|
||||||
|
|
||||||
|
//^#===================================================== UpdateTrace Thread
|
||||||
|
class UpdateTraceThread : public QThread {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
UpdateTraceThread(QObject * parent = 0) : QThread(parent){
|
||||||
|
waitTime = 2;
|
||||||
|
stop = false;
|
||||||
|
}
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
595
scope.cpp
Normal file
595
scope.cpp
Normal file
|
@ -0,0 +1,595 @@
|
||||||
|
#include "scope.h"
|
||||||
|
|
||||||
|
#include <QValueAxis>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QChartView>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
|
||||||
|
Scope::Scope(Digitizer2Gen **digi, unsigned int nDigi, ReadDataThread ** readDataThread, QMainWindow *parent) : QMainWindow(parent){
|
||||||
|
this->digi = digi;
|
||||||
|
this->nDigi = nDigi;
|
||||||
|
this->readDataThread = readDataThread;
|
||||||
|
|
||||||
|
setWindowTitle("Scope");
|
||||||
|
setGeometry(0, 0, 1000, 800);
|
||||||
|
setWindowFlags( this->windowFlags() & ~Qt::WindowCloseButtonHint );
|
||||||
|
|
||||||
|
allowChange = false;
|
||||||
|
|
||||||
|
plot = new QChart();
|
||||||
|
for( int i = 0; i < 6; i++) {
|
||||||
|
dataTrace[i] = new QLineSeries();
|
||||||
|
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->createDefaultAxes(); /// this must be after addSeries();
|
||||||
|
/// this must be after createDefaultAxes();
|
||||||
|
QValueAxis * yaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Vertical).first());
|
||||||
|
QValueAxis * xaxis = qobject_cast<QValueAxis*> (plot->axes(Qt::Horizontal).first());
|
||||||
|
yaxis->setTickCount(6);
|
||||||
|
yaxis->setTickInterval(16384);
|
||||||
|
yaxis->setRange(-16384, 65536);
|
||||||
|
yaxis->setLabelFormat("%.0f");
|
||||||
|
|
||||||
|
xaxis->setRange(0, 5000);
|
||||||
|
xaxis->setTickCount(11);
|
||||||
|
xaxis->setLabelFormat("%.0f");
|
||||||
|
xaxis->setTitleText("Time [ns]");
|
||||||
|
|
||||||
|
updateTraceThread = new UpdateTraceThread();
|
||||||
|
connect(updateTraceThread, &UpdateTraceThread::updateTrace, this, &Scope::UpdateScope);
|
||||||
|
|
||||||
|
//*================ add Widgets
|
||||||
|
int rowID = -1;
|
||||||
|
QWidget * layoutWidget = new QWidget(this);
|
||||||
|
setCentralWidget(layoutWidget);
|
||||||
|
QGridLayout * layout = new QGridLayout(layoutWidget);
|
||||||
|
layoutWidget->setLayout(layout);
|
||||||
|
|
||||||
|
//------------ Digitizer + channel selection
|
||||||
|
rowID ++;
|
||||||
|
cbScopeDigi = new QComboBox(this);
|
||||||
|
cbScopeCh = new QComboBox(this);
|
||||||
|
layout->addWidget(cbScopeDigi, rowID, 0);
|
||||||
|
layout->addWidget(cbScopeCh, rowID, 1);
|
||||||
|
|
||||||
|
connect(cbScopeDigi, &QComboBox::currentIndexChanged, this, [=](){
|
||||||
|
//if( allowChange ) StopScope();
|
||||||
|
int index = cbScopeDigi->currentIndex();
|
||||||
|
if( index == -1 ) return;
|
||||||
|
for( int i = 0; i < digi[index]->GetNChannels(); i++){
|
||||||
|
cbScopeCh->addItem("ch-" + QString::number(i), i);
|
||||||
|
}
|
||||||
|
//if( allowChange )StartScope(index);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(cbScopeCh, &QComboBox::currentIndexChanged, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
int ch = cbScopeCh->currentIndex();
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[iDigi]->WriteChValue("0..63", DIGIPARA::CH::ChannelEnable, "false");
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::ChannelEnable, "true");
|
||||||
|
ReadScopeSettings(iDigi, ch);
|
||||||
|
digiMTX.unlock();
|
||||||
|
});
|
||||||
|
|
||||||
|
allowChange = false;
|
||||||
|
cbScopeDigi->clear(); ///this will also trigger QComboBox::currentIndexChanged
|
||||||
|
cbScopeCh->clear();
|
||||||
|
for( unsigned int i = 0 ; i < nDigi; i++) {
|
||||||
|
cbScopeDigi->addItem("Digi-" + QString::number(digi[i]->GetSerialNumber()), i);
|
||||||
|
}
|
||||||
|
allowChange = true;
|
||||||
|
|
||||||
|
|
||||||
|
bnScopeReset = new QPushButton("ReProgram Digitizer", this);
|
||||||
|
layout->addWidget(bnScopeReset, rowID, 2);
|
||||||
|
connect(bnScopeReset, &QPushButton::clicked, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
digi[iDigi]->Reset();
|
||||||
|
digi[iDigi]->ProgramPHA(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
bnScopeReadSettings = new QPushButton("Read Ch. Settings", this);
|
||||||
|
layout->addWidget(bnScopeReadSettings, rowID, 3);
|
||||||
|
connect(bnScopeReadSettings, &QPushButton::clicked, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
ReadScopeSettings(cbScopeDigi->currentIndex(), cbScopeCh->currentIndex());
|
||||||
|
});
|
||||||
|
|
||||||
|
//TODO----- add copy settings and paste settings
|
||||||
|
QCheckBox * chkSetAllChannel = new QCheckBox("apply to all channels", this);
|
||||||
|
layout->addWidget(chkSetAllChannel, rowID, 4);
|
||||||
|
chkSetAllChannel->setEnabled(false);
|
||||||
|
|
||||||
|
//------------ Probe selection
|
||||||
|
rowID ++;
|
||||||
|
//TODO --- add None
|
||||||
|
cbAnaProbe[0] = new QComboBox(this);
|
||||||
|
cbAnaProbe[0]->addItem("ADC Input", "ADCInput");
|
||||||
|
cbAnaProbe[0]->addItem("Time Filter", "TimeFilter");
|
||||||
|
cbAnaProbe[0]->addItem("Trapazoid", "EnergyFilter");
|
||||||
|
cbAnaProbe[0]->addItem("Trap. Baseline", "EnergyFilterBaseline");
|
||||||
|
cbAnaProbe[0]->addItem("Trap. - Baseline", "EnergyFilterMinusBaseline");
|
||||||
|
|
||||||
|
cbAnaProbe[1] = new QComboBox(this);
|
||||||
|
for( int i = 0; i < cbAnaProbe[0]->count() ; i++) cbAnaProbe[1]->addItem(cbAnaProbe[0]->itemText(i), cbAnaProbe[0]->itemData(i));
|
||||||
|
|
||||||
|
connect(cbAnaProbe[0], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbAnaProbe, 2);});
|
||||||
|
connect(cbAnaProbe[1], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbAnaProbe, 2);});
|
||||||
|
|
||||||
|
cbAnaProbe[0]->setCurrentIndex(1); ///trigger the AnaProbeChange
|
||||||
|
cbAnaProbe[0]->setCurrentIndex(0);
|
||||||
|
cbAnaProbe[1]->setCurrentIndex(4);
|
||||||
|
|
||||||
|
connect(cbAnaProbe[0], &QComboBox::currentIndexChanged, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
int ch = cbScopeCh->currentIndex();
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveAnalogProbe0, (cbAnaProbe[0]->currentData()).toString().toStdString());
|
||||||
|
digiMTX.unlock();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(cbAnaProbe[1], &QComboBox::currentIndexChanged, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
int ch = cbScopeCh->currentIndex();
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveAnalogProbe1, (cbAnaProbe[1]->currentData()).toString().toStdString());
|
||||||
|
digiMTX.unlock();
|
||||||
|
});
|
||||||
|
|
||||||
|
//TODO --- add None
|
||||||
|
cbDigProbe[0] = new QComboBox(this);
|
||||||
|
cbDigProbe[0]->addItem("Trigger", "Trigger");
|
||||||
|
cbDigProbe[0]->addItem("Time Filter Armed", "TimeFilterArmed");
|
||||||
|
cbDigProbe[0]->addItem("ReTrigger Guard", "ReTriggerGuard");
|
||||||
|
cbDigProbe[0]->addItem("Trap. basline Freeze", "EnergyFilterBaselineFreeze");
|
||||||
|
cbDigProbe[0]->addItem("Peaking", "EnergyFilterPeaking");
|
||||||
|
cbDigProbe[0]->addItem("Peak Ready", "EnergyFilterPeakReady");
|
||||||
|
cbDigProbe[0]->addItem("Pile-up Guard", "EnergyFilterPileUpGuard");
|
||||||
|
cbDigProbe[0]->addItem("Event Pile Up", "EventPileUp");
|
||||||
|
cbDigProbe[0]->addItem("ADC Saturate", "ADCSaturation");
|
||||||
|
cbDigProbe[0]->addItem("ADC Sat. Protection", "ADCSaturationProtection");
|
||||||
|
cbDigProbe[0]->addItem("Post Sat. Event", "PostSaturationEvent");
|
||||||
|
cbDigProbe[0]->addItem("Trap. Saturate", "EnergylterSaturation");
|
||||||
|
cbDigProbe[0]->addItem("ACQ Inhibit", "AcquisitionInhibit");
|
||||||
|
|
||||||
|
cbDigProbe[1] = new QComboBox(this);
|
||||||
|
cbDigProbe[2] = new QComboBox(this);
|
||||||
|
cbDigProbe[3] = new QComboBox(this);
|
||||||
|
for( int i = 0; i < cbDigProbe[0]->count() ; i++) {
|
||||||
|
cbDigProbe[1]->addItem(cbDigProbe[0]->itemText(i), cbDigProbe[0]->itemData(i));
|
||||||
|
cbDigProbe[2]->addItem(cbDigProbe[0]->itemText(i), cbDigProbe[0]->itemData(i));
|
||||||
|
cbDigProbe[3]->addItem(cbDigProbe[0]->itemText(i), cbDigProbe[0]->itemData(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(cbDigProbe[0], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbDigProbe, 4);});
|
||||||
|
connect(cbDigProbe[1], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbDigProbe, 4);});
|
||||||
|
connect(cbDigProbe[2], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbDigProbe, 4);});
|
||||||
|
connect(cbDigProbe[3], &QComboBox::currentIndexChanged, this, [=](){ this->ProbeChange(cbDigProbe, 4);});
|
||||||
|
|
||||||
|
cbDigProbe[0]->setCurrentIndex(1); ///trigger the DigProbeChange
|
||||||
|
cbDigProbe[0]->setCurrentIndex(0);
|
||||||
|
cbDigProbe[1]->setCurrentIndex(4);
|
||||||
|
cbDigProbe[2]->setCurrentIndex(5);
|
||||||
|
cbDigProbe[3]->setCurrentIndex(6);
|
||||||
|
|
||||||
|
connect(cbDigProbe[0], &QComboBox::currentIndexChanged, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
int ch = cbScopeCh->currentIndex();
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveDigitalProbe0, (cbDigProbe[0]->currentData()).toString().toStdString());
|
||||||
|
digiMTX.unlock();
|
||||||
|
});
|
||||||
|
connect(cbDigProbe[1], &QComboBox::currentIndexChanged, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
int ch = cbScopeCh->currentIndex();
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveDigitalProbe1, (cbDigProbe[1]->currentData()).toString().toStdString());
|
||||||
|
digiMTX.unlock();
|
||||||
|
});
|
||||||
|
connect(cbDigProbe[2], &QComboBox::currentIndexChanged, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
int ch = cbScopeCh->currentIndex();
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveDigitalProbe2, (cbDigProbe[2]->currentData()).toString().toStdString());
|
||||||
|
digiMTX.unlock();
|
||||||
|
});
|
||||||
|
connect(cbDigProbe[3], &QComboBox::currentIndexChanged, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
int ch = cbScopeCh->currentIndex();
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::WaveDigitalProbe3, (cbDigProbe[3]->currentData()).toString().toStdString());
|
||||||
|
digiMTX.unlock();
|
||||||
|
});
|
||||||
|
|
||||||
|
layout->addWidget(cbAnaProbe[0], rowID, 0);
|
||||||
|
layout->addWidget(cbAnaProbe[1], rowID, 1);
|
||||||
|
|
||||||
|
layout->addWidget(cbDigProbe[0], rowID, 2);
|
||||||
|
layout->addWidget(cbDigProbe[1], rowID, 3);
|
||||||
|
layout->addWidget(cbDigProbe[2], rowID, 4);
|
||||||
|
layout->addWidget(cbDigProbe[3], rowID, 5);
|
||||||
|
|
||||||
|
rowID ++;
|
||||||
|
{//------------ wave settings
|
||||||
|
QGroupBox * box = new QGroupBox("Channel Settings (need ACQ stop)", this);
|
||||||
|
layout->addWidget(box, rowID, 0, 1, 6);
|
||||||
|
|
||||||
|
QGridLayout * bLayout = new QGridLayout(box);
|
||||||
|
bLayout->setSpacing(0);
|
||||||
|
|
||||||
|
sbRL = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbRL, "Record Lenght [ns] ", bLayout, 0, 0, 32, 648000, DIGIPARA::TraceStep, DIGIPARA::CH::RecordLength);
|
||||||
|
|
||||||
|
sbThreshold = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbThreshold, "Threshold [LSB] ", bLayout, 0, 2, 0, 8191, -20, DIGIPARA::CH::TriggerThreshold);
|
||||||
|
|
||||||
|
cbPolarity = new QComboBox(this);
|
||||||
|
cbPolarity->addItem("Pos. +", "Positive");
|
||||||
|
cbPolarity->addItem("Neg. -", "Negative");
|
||||||
|
ScopeMakeComoBox(cbPolarity, "Polarity ", bLayout, 0, 4, DIGIPARA::CH::Polarity);
|
||||||
|
|
||||||
|
cbWaveRes = new QComboBox(this);
|
||||||
|
cbWaveRes->addItem(" 8 ns", "RES8");
|
||||||
|
cbWaveRes->addItem("16 ns", "RES16");
|
||||||
|
cbWaveRes->addItem("32 ns", "RES32");
|
||||||
|
cbWaveRes->addItem("64 ns", "RES64");
|
||||||
|
ScopeMakeComoBox(cbWaveRes, "Wave Re. ", bLayout, 0, 6, DIGIPARA::CH::WaveResolution);
|
||||||
|
|
||||||
|
//------------------ next row
|
||||||
|
sbPT = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbPT, "Pre Trigger [ns] ", bLayout, 1, 0, 32, 32000, DIGIPARA::TraceStep, DIGIPARA::CH::PreTrigger);
|
||||||
|
|
||||||
|
sbDCOffset = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbDCOffset, "DC offset [%] ", bLayout, 1, 2, 0, 100, -10, DIGIPARA::CH::DC_Offset);
|
||||||
|
|
||||||
|
sbTimeRiseTime = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbTimeRiseTime, "Trigger Rise Time [ns] ", bLayout, 1, 4, 32, 2000, DIGIPARA::TraceStep, DIGIPARA::CH::TimeFilterRiseTime);
|
||||||
|
|
||||||
|
sbTimeGuard = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbTimeGuard, "Trigger Guard [ns] ", bLayout, 1, 6, 0, 8000, DIGIPARA::TraceStep, DIGIPARA::CH::TimeFilterRetriggerGuard);
|
||||||
|
|
||||||
|
//----------------- next row
|
||||||
|
sbTrapRiseTime = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbTrapRiseTime, "Trap. Rise Time [ns] ", bLayout, 2, 0, 32, 13000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterRiseTime);
|
||||||
|
|
||||||
|
sbTrapFlatTop = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbTrapFlatTop, "Trap. Flat Top [ns] ", bLayout, 2, 2, 32, 3000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterFlatTop);
|
||||||
|
|
||||||
|
sbTrapPoleZero = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbTrapPoleZero, "Trap. Pole Zero [ns] ", bLayout, 2, 4, 32, 524000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterPoleZero);
|
||||||
|
|
||||||
|
sbEnergyFineGain = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbEnergyFineGain, "Energy Fine Gain ", bLayout, 2, 6, 1, 10, -1, DIGIPARA::CH::EnergyFilterFineGain);
|
||||||
|
|
||||||
|
//----------------- next row
|
||||||
|
sbTrapPeaking = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbTrapPeaking, "Trap. Peaking [%] ", bLayout, 3, 0, 1, 100, -10, DIGIPARA::CH::EnergyFilterPeakingPosition);
|
||||||
|
|
||||||
|
cbTrapPeakAvg = new QComboBox(this);
|
||||||
|
cbTrapPeakAvg->addItem(" 1 sample", "OneShot");
|
||||||
|
cbTrapPeakAvg->addItem(" 4 sample", "LowAVG");
|
||||||
|
cbTrapPeakAvg->addItem("16 sample", "MediumAVG");
|
||||||
|
cbTrapPeakAvg->addItem("64 sample", "HighAVG");
|
||||||
|
ScopeMakeComoBox(cbTrapPeakAvg, "Trap. Peaking ", bLayout, 3, 2, DIGIPARA::CH::EnergyFilterPeakingAvg);
|
||||||
|
|
||||||
|
sbBaselineGuard = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbBaselineGuard, "Baseline Guard [ns] ", bLayout, 3, 4, 0, 8000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterBaselineGuard);
|
||||||
|
|
||||||
|
cbBaselineAvg = new QComboBox(this);
|
||||||
|
cbBaselineAvg->addItem(" 0 samp.", "Fixed");
|
||||||
|
cbBaselineAvg->addItem(" 16 samp.", "VeryLow");
|
||||||
|
cbBaselineAvg->addItem(" 64 samp.", "Low");
|
||||||
|
cbBaselineAvg->addItem(" 256 samp.", "MediumLow");
|
||||||
|
cbBaselineAvg->addItem(" 1024 samp.", "Medium");
|
||||||
|
cbBaselineAvg->addItem(" 4096 samp.", "MediumHigh");
|
||||||
|
cbBaselineAvg->addItem("16384 samp.", "High");
|
||||||
|
ScopeMakeComoBox(cbBaselineAvg, "Baseline Avg ", bLayout, 3, 6, DIGIPARA::CH::EnergyFilterBaselineAvg);
|
||||||
|
//----------------
|
||||||
|
|
||||||
|
sbPileUpGuard = new QSpinBox(this);
|
||||||
|
ScopeMakeSpinBox(sbPileUpGuard, "Pile-up Guard [ns] ", bLayout, 4, 0, 0, 64000, DIGIPARA::TraceStep, DIGIPARA::CH::EnergyFilterPileUpGuard);
|
||||||
|
|
||||||
|
cbLowFreqFilter = new QComboBox(this);
|
||||||
|
cbLowFreqFilter->addItem("Disabled", "Off");
|
||||||
|
cbLowFreqFilter->addItem("Enabled", "On");
|
||||||
|
ScopeMakeComoBox(cbLowFreqFilter, "Low Freq. Filter ", bLayout, 4, 2, DIGIPARA::CH::EnergyFilterLowFreqFilter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------ plot view
|
||||||
|
rowID ++;
|
||||||
|
QChartView * plotView = new QChartView(plot);
|
||||||
|
plotView->setRenderHints(QPainter::Antialiasing);
|
||||||
|
layout->addWidget(plotView, rowID, 0, 1, 6);
|
||||||
|
|
||||||
|
//TODO zoom and pan, see Zoom Line example
|
||||||
|
|
||||||
|
//------------ close button
|
||||||
|
rowID ++;
|
||||||
|
bnScopeStart = new QPushButton("Start", this);
|
||||||
|
layout->addWidget(bnScopeStart, rowID, 0);
|
||||||
|
bnScopeStart->setEnabled(false);
|
||||||
|
connect(bnScopeStart, &QPushButton::clicked, this, [=](){this->StartScope();});
|
||||||
|
|
||||||
|
bnScopeStop = new QPushButton("Stop", this);
|
||||||
|
layout->addWidget(bnScopeStop, rowID, 1);
|
||||||
|
connect(bnScopeStop, &QPushButton::clicked, this, &Scope::StopScope);
|
||||||
|
|
||||||
|
QPushButton * bnClose = new QPushButton("Close", this);
|
||||||
|
layout->addWidget(bnClose, rowID, 5);
|
||||||
|
connect(bnClose, &QPushButton::clicked, this, &Scope::StopScope);
|
||||||
|
connect(bnClose, &QPushButton::clicked, this, &Scope::close);
|
||||||
|
|
||||||
|
|
||||||
|
show();
|
||||||
|
|
||||||
|
StartScope();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Scope::~Scope(){
|
||||||
|
|
||||||
|
updateTraceThread->Stop();
|
||||||
|
updateTraceThread->quit();
|
||||||
|
updateTraceThread->wait();
|
||||||
|
delete updateTraceThread;
|
||||||
|
|
||||||
|
|
||||||
|
for( int i = 0; i < 6; i++) delete dataTrace[i];
|
||||||
|
|
||||||
|
delete plot;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::ReadScopeSettings(int iDigi, int ch){
|
||||||
|
if( !digi[iDigi] && digi[iDigi]->IsDummy() ) return;
|
||||||
|
|
||||||
|
printf("%s\n", __func__);
|
||||||
|
|
||||||
|
allowChange = false;
|
||||||
|
|
||||||
|
for( int i = 0 ; i < 2; i++){
|
||||||
|
ScopeReadComboBoxValue(iDigi, ch, cbAnaProbe[i], DIGIPARA::CH::AnalogProbe[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = 0 ; i < 4; i++){
|
||||||
|
ScopeReadComboBoxValue(iDigi, ch, cbDigProbe[i], DIGIPARA::CH::DigitalProbe[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopeReadComboBoxValue(iDigi, ch, cbPolarity, DIGIPARA::CH::Polarity);
|
||||||
|
ScopeReadComboBoxValue(iDigi, ch, cbWaveRes, DIGIPARA::CH::WaveResolution);
|
||||||
|
ScopeReadComboBoxValue(iDigi, ch, cbTrapPeakAvg, DIGIPARA::CH::EnergyFilterPeakingAvg);
|
||||||
|
ScopeReadComboBoxValue(iDigi, ch, cbBaselineAvg, DIGIPARA::CH::EnergyFilterBaselineAvg);
|
||||||
|
ScopeReadComboBoxValue(iDigi, ch, cbLowFreqFilter, DIGIPARA::CH::EnergyFilterLowFreqFilter);
|
||||||
|
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbRL, DIGIPARA::CH::RecordLength);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbPT, DIGIPARA::CH::PreTrigger);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbDCOffset, DIGIPARA::CH::DC_Offset);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbThreshold, DIGIPARA::CH::TriggerThreshold);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbTimeRiseTime, DIGIPARA::CH::TimeFilterRiseTime);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbTimeGuard, DIGIPARA::CH::TimeFilterRetriggerGuard);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbTrapRiseTime, DIGIPARA::CH::EnergyFilterRiseTime);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbTrapFlatTop, DIGIPARA::CH::EnergyFilterFlatTop);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbTrapPoleZero, DIGIPARA::CH::EnergyFilterPoleZero);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbEnergyFineGain, DIGIPARA::CH::EnergyFilterFineGain);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbTrapPeaking, DIGIPARA::CH::EnergyFilterPeakingPosition);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbBaselineGuard, DIGIPARA::CH::EnergyFilterBaselineGuard);
|
||||||
|
ScopeReadSpinBoxValue(iDigi, ch, sbPileUpGuard, DIGIPARA::CH::EnergyFilterPileUpGuard);
|
||||||
|
|
||||||
|
allowChange = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::StartScope(){
|
||||||
|
|
||||||
|
if( !digi ) return;
|
||||||
|
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
|
||||||
|
if( digi[iDigi]->IsDummy() ) return;
|
||||||
|
|
||||||
|
printf("%s\n", __func__);
|
||||||
|
|
||||||
|
int ch = cbScopeCh->currentIndex();
|
||||||
|
|
||||||
|
//*---- set digitizer to take full trace; since in scope mode, no data saving, speed would be fast (How fast?)
|
||||||
|
//* when the input rate is faster than trigger rate, Digitizer will stop data taking.
|
||||||
|
|
||||||
|
ReadScopeSettings(iDigi, ch);
|
||||||
|
|
||||||
|
digi[iDigi]->WriteChValue("0..63", DIGIPARA::CH::ChannelEnable, "false");
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(ch), DIGIPARA::CH::ChannelEnable, "true");
|
||||||
|
digi[iDigi]->SetPHADataFormat(0);
|
||||||
|
|
||||||
|
digi[iDigi]->StartACQ();
|
||||||
|
|
||||||
|
readDataThread[iDigi]->SetScopeRun(true);
|
||||||
|
readDataThread[iDigi]->start();
|
||||||
|
|
||||||
|
updateTraceThread->start();
|
||||||
|
|
||||||
|
ScopeControlOnOff(false);
|
||||||
|
|
||||||
|
allowChange = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::StopScope(){
|
||||||
|
|
||||||
|
printf("%s\n", __func__);
|
||||||
|
|
||||||
|
updateTraceThread->Stop();
|
||||||
|
updateTraceThread->quit();
|
||||||
|
updateTraceThread->wait();
|
||||||
|
|
||||||
|
if(digi){
|
||||||
|
for(int i = 0; i < nDigi; i++){
|
||||||
|
if( digi[i]->IsDummy() ) continue;
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[i]->StopACQ();
|
||||||
|
digi[i]->WriteChValue("0..63", DIGIPARA::CH::ChannelEnable, "true");
|
||||||
|
digiMTX.unlock();
|
||||||
|
|
||||||
|
readDataThread[i]->quit();
|
||||||
|
readDataThread[i]->wait();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopeControlOnOff(true);
|
||||||
|
allowChange = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::UpdateScope(){
|
||||||
|
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
int sample2ns = DIGIPARA::TraceStep * (1 << cbWaveRes->currentIndex());
|
||||||
|
|
||||||
|
if( digi ){
|
||||||
|
digiMTX.lock();
|
||||||
|
unsigned int traceLength = digi[iDigi]->evt->traceLenght;
|
||||||
|
unsigned int dataLength = dataTrace[0]->count();
|
||||||
|
|
||||||
|
//---- remove all points
|
||||||
|
for( int j = 0; j < 6; j++ ) dataTrace[j]->removePoints(0, dataLength);
|
||||||
|
|
||||||
|
for( unsigned int i = 0 ; i < traceLength; i++){
|
||||||
|
for( int j = 0; j < 2; j++) dataTrace[j]->append(sample2ns * i, digi[iDigi]->evt->analog_probes[j][i]);
|
||||||
|
for( int j = 2; j < 6; j++) dataTrace[j]->append(sample2ns * i, (j-1)*1000 + 4000 * digi[iDigi]->evt->digital_probes[j-2][i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
digiMTX.unlock();
|
||||||
|
|
||||||
|
plot->axes(Qt::Horizontal).first()->setRange(0, sample2ns * traceLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::ProbeChange(QComboBox * cb[], const int size ){
|
||||||
|
|
||||||
|
QStandardItemModel * model[size] = {NULL};
|
||||||
|
for( int i = 0; i < size; i++){
|
||||||
|
model[i] = qobject_cast<QStandardItemModel*>(cb[i]->model());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable all items
|
||||||
|
for( int i = 0; i < cb[0]->count(); i++) {
|
||||||
|
for( int j = 0; j < size; j ++ ) model[j]->item(i)->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = 0; i < size; i++){
|
||||||
|
int index = cb[i]->currentIndex();
|
||||||
|
for( int j = 0; j < size; j++){
|
||||||
|
if( i == j ) continue;
|
||||||
|
model[j]->item(index)->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
digiMTX.lock();
|
||||||
|
if( size == 2) {// analog probes
|
||||||
|
for( int j = 0; j < 2; j++ )dataTrace[j]->setName(cb[j]->currentText());
|
||||||
|
}
|
||||||
|
if( size == 4){ // digitial probes
|
||||||
|
for( int j = 2; j < 6; j++ )dataTrace[j]->setName(cb[j-2]->currentText());
|
||||||
|
}
|
||||||
|
digiMTX.unlock();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::ScopeControlOnOff(bool on){
|
||||||
|
bnScopeStop->setEnabled(!on);
|
||||||
|
|
||||||
|
bnScopeStart->setEnabled(on);
|
||||||
|
bnScopeReset->setEnabled(on);
|
||||||
|
bnScopeReadSettings->setEnabled(on);
|
||||||
|
|
||||||
|
sbRL->setEnabled(on);
|
||||||
|
sbPT->setEnabled(on);
|
||||||
|
sbDCOffset->setEnabled(on);
|
||||||
|
sbThreshold->setEnabled(on);
|
||||||
|
sbTimeRiseTime->setEnabled(on);
|
||||||
|
sbTimeGuard->setEnabled(on);
|
||||||
|
sbTrapRiseTime->setEnabled(on);
|
||||||
|
sbTrapFlatTop->setEnabled(on);
|
||||||
|
sbTrapPoleZero->setEnabled(on);
|
||||||
|
sbEnergyFineGain->setEnabled(on);
|
||||||
|
sbTrapPeaking->setEnabled(on);
|
||||||
|
cbPolarity->setEnabled(on);
|
||||||
|
cbWaveRes->setEnabled(on);
|
||||||
|
cbTrapPeakAvg->setEnabled(on);
|
||||||
|
|
||||||
|
sbBaselineGuard->setEnabled(on);
|
||||||
|
sbPileUpGuard->setEnabled(on);
|
||||||
|
cbBaselineAvg->setEnabled(on);
|
||||||
|
cbLowFreqFilter->setEnabled(on);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::ScopeReadSpinBoxValue(int iDigi, int ch, QSpinBox *sb, std::string digPara){
|
||||||
|
std::string ans = digi[iDigi]->ReadChValue(std::to_string(ch), digPara);
|
||||||
|
sb->setValue(atoi(ans.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::ScopeReadComboBoxValue(int iDigi, int ch, QComboBox *cb, std::string digPara){
|
||||||
|
std::string ans = digi[iDigi]->ReadChValue(std::to_string(ch), digPara);
|
||||||
|
int index = cb->findData(QString::fromStdString(ans));
|
||||||
|
if( index >= 0 && index < cb->count()) {
|
||||||
|
cb->setCurrentIndex(index);
|
||||||
|
}else{
|
||||||
|
qDebug() << QString::fromStdString(ans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::ScopeMakeSpinBox(QSpinBox *sb, QString str, QGridLayout *layout, int row, int col, int min, int max, int step, std::string digPara){
|
||||||
|
QLabel * lb = new QLabel(str, this);
|
||||||
|
lb->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
|
layout->addWidget(lb, row, col);
|
||||||
|
sb->setMinimum(min);
|
||||||
|
sb->setMaximum(max);
|
||||||
|
sb->setSingleStep(abs(step));
|
||||||
|
layout->addWidget(sb, row, col+1);
|
||||||
|
connect(sb, &QSpinBox::valueChanged, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
if( step > 1 ) sb->setValue(step*((sb->value() + step - 1)/step));
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(cbScopeCh->currentIndex()), digPara, std::to_string(sb->value()));
|
||||||
|
digiMTX.unlock();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scope::ScopeMakeComoBox(QComboBox *cb, QString str, QGridLayout *layout, int row, int col, std::string digPara){
|
||||||
|
QLabel * lb = new QLabel(str, this);
|
||||||
|
lb->setAlignment(Qt::AlignRight | Qt::AlignCenter);
|
||||||
|
layout->addWidget(lb, row, col);
|
||||||
|
layout->addWidget(cb, row, col+1);
|
||||||
|
connect(cb, &QComboBox::currentIndexChanged, this, [=](){
|
||||||
|
if( !allowChange ) return;
|
||||||
|
int iDigi = cbScopeDigi->currentIndex();
|
||||||
|
digiMTX.lock();
|
||||||
|
digi[iDigi]->WriteChValue(std::to_string(cbScopeCh->currentIndex()), digPara, cb->currentData().toString().toStdString());
|
||||||
|
digiMTX.unlock();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
90
scope.h
Normal file
90
scope.h
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#ifndef Scope_H
|
||||||
|
#define Scope_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QChart>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QLineSeries>
|
||||||
|
|
||||||
|
#include "ClassDigitizer2Gen.h"
|
||||||
|
#include "manyThread.h"
|
||||||
|
|
||||||
|
class Scope : public QMainWindow{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Scope(Digitizer2Gen ** digi, unsigned int nDigi, ReadDataThread ** readDataThread, QMainWindow * parent = nullptr);
|
||||||
|
~Scope();
|
||||||
|
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void ReadScopeSettings(int iDigi, int ch);
|
||||||
|
void StartScope();
|
||||||
|
void StopScope();
|
||||||
|
void UpdateScope();
|
||||||
|
void ScopeControlOnOff(bool on);
|
||||||
|
void ScopeReadSpinBoxValue(int iDigi, int ch, QSpinBox *sb, std::string digPara);
|
||||||
|
void ScopeReadComboBoxValue(int iDigi, int ch, QComboBox *cb, std::string digPara);
|
||||||
|
void ScopeMakeSpinBox(QSpinBox * sb, QString str, QGridLayout* layout, int row, int col, int min, int max, int step, std::string digPara);
|
||||||
|
void ScopeMakeComoBox(QComboBox * cb, QString str, QGridLayout* layout, int row, int col, std::string digPara);
|
||||||
|
void ProbeChange(QComboBox * cb[], const int size);
|
||||||
|
|
||||||
|
void closeEvent(QCloseEvent * event){
|
||||||
|
StopScope();
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Digitizer2Gen ** digi;
|
||||||
|
unsigned short nDigi;
|
||||||
|
|
||||||
|
ReadDataThread ** readDataThread;
|
||||||
|
UpdateTraceThread * updateTraceThread;
|
||||||
|
|
||||||
|
QChart * plot;
|
||||||
|
QLineSeries * dataTrace[6];
|
||||||
|
QComboBox * cbScopeDigi;
|
||||||
|
QComboBox * cbScopeCh;
|
||||||
|
QPushButton * bnScopeReset;
|
||||||
|
QPushButton * bnScopeReadSettings;
|
||||||
|
|
||||||
|
|
||||||
|
QPushButton * bnScopeStart;
|
||||||
|
QPushButton * bnScopeStop;
|
||||||
|
|
||||||
|
QComboBox * cbAnaProbe[2];
|
||||||
|
QComboBox * cbDigProbe[4];
|
||||||
|
QSpinBox * sbRL; // record length
|
||||||
|
QSpinBox * sbPT; // pre trigger
|
||||||
|
QSpinBox * sbDCOffset;
|
||||||
|
QSpinBox * sbThreshold;
|
||||||
|
QSpinBox * sbTimeRiseTime;
|
||||||
|
QSpinBox * sbTimeGuard;
|
||||||
|
QSpinBox * sbTrapRiseTime;
|
||||||
|
QSpinBox * sbTrapFlatTop;
|
||||||
|
QSpinBox * sbTrapPoleZero;
|
||||||
|
QSpinBox * sbEnergyFineGain;
|
||||||
|
QSpinBox * sbTrapPeaking;
|
||||||
|
QComboBox * cbPolarity;
|
||||||
|
QComboBox * cbWaveRes;
|
||||||
|
QComboBox * cbTrapPeakAvg;
|
||||||
|
|
||||||
|
QSpinBox * sbBaselineGuard;
|
||||||
|
QSpinBox * sbPileUpGuard;
|
||||||
|
QComboBox * cbBaselineAvg;
|
||||||
|
QComboBox * cbLowFreqFilter;
|
||||||
|
|
||||||
|
bool allowChange;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user