#include "scope.h" #include #include #include #include #include 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 Trace(); 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(40*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->setAnimationDuration(1); // msec plot->setAnimationOptions(QChart::NoAnimation); plot->createDefaultAxes(); /// this must be after addSeries(); /// this must be after createDefaultAxes(); QValueAxis * yaxis = qobject_cast (plot->axes(Qt::Vertical).first()); QValueAxis * xaxis = qobject_cast (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 ++; TraceView * plotView = new TraceView(plot); plotView->setRenderHints(QPainter::Antialiasing); layout->addWidget(plotView, rowID, 0, 1, 6); //------------- Ketbinding rowID ++; QLabel * lbhints = new QLabel("Type 'r' to restore view.", this); layout->addWidget(lbhints, rowID, 0, 1, 3); QLabel * lbinfo = new QLabel("Trace update every " + QString::number(updateTraceThread->GetWaitTimeSec()) + " sec.", this); lbinfo->setAlignment(Qt::AlignRight); layout->addWidget(lbinfo, rowID, 5); //------------ 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); QLabel * lbTriggerRate = new QLabel("Trigger Rate [Hz] : ", this); lbTriggerRate->setAlignment(Qt::AlignCenter | Qt::AlignRight); layout->addWidget(lbTriggerRate, rowID, 2); leTriggerRate = new QLineEdit(this); leTriggerRate->setAlignment(Qt::AlignRight); leTriggerRate->setReadOnly(true); layout->addWidget(leTriggerRate, rowID, 3); QPushButton * bnClose = new QPushButton("Close", this); layout->addWidget(bnClose, rowID, 5); 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]->SetSaveData(false); 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 ch = cbScopeCh->currentIndex(); int sample2ns = DIGIPARA::TraceStep * (1 << cbWaveRes->currentIndex()); emit UpdateScalar(); if( digi ){ //---- remove all points unsigned int dataLength = dataTrace[0]->count(); for( int j = 0; j < 6; j++ ) dataTrace[j]->removePoints(0, dataLength); digiMTX.lock(); std::string time = digi[iDigi]->ReadChValue(std::to_string(ch), DIGIPARA::CH::ChannelRealtime); // for refreashing SelfTrgRate and SavedCount std::string haha = digi[iDigi]->ReadChValue(std::to_string(ch), DIGIPARA::CH::SelfTrgRate); leTriggerRate->setText(QString::fromStdString(haha)); if( atoi(haha.c_str()) == 0 ) { digiMTX.unlock(); return; } unsigned int traceLength = digi[iDigi]->evt->traceLenght; 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(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(); }); }