#include "SOLARISpanel.h" #include #include #include #include #include #include #define NCOL 10 // number of column #define ChStartIndex 2 // the index of detIDList for channel std::vector SettingItems = {PHA::CH::TriggerThreshold, PHA::CH::DC_Offset}; SOLARISpanel::SOLARISpanel(Digitizer2Gen **digi, unsigned short nDigi, QString analysisPath, std::vector> mapping, QStringList detType, QStringList detGroupName, std::vector detGroupID, std::vector detMaxID, QWidget *parent) : QWidget(parent){ setWindowTitle("SOLARIS Settings"); setGeometry(0, 0, 1350, 800); this->digi = digi; this->nDigi = nDigi; if( this->nDigi > MaxNumberOfDigitizer ) { this->nDigi = MaxNumberOfChannel; qDebug() << "Please increase the MaxNumberOfChannel"; } this->mapping = mapping; this->detTypeNameList = detType; this->detMaxID = detMaxID; this->detGroupID = detGroupID; this->detGroupNameList = detGroupName; this->digiSettingPath = analysisPath + "/working/Settings/"; //Check number of detector type; Array 0-199, Recoil 200-299, other 300- int nDetType = detTypeNameList.size(); for( int k = 0 ; k < nDetType; k++) nDetinType.push_back(0); std::vector condenGroupID = detGroupID; std::sort(condenGroupID.begin(), condenGroupID.end()); // sort the detGroupID auto last = std::unique(condenGroupID.begin(), condenGroupID.end()); condenGroupID.erase(last, condenGroupID.end()); int nDetGroup = condenGroupID.size(); for( int k = 0 ; k < nDetGroup; k++) nDetinGroup.push_back(0); QList> detIDListTemp; // store { detGroup, detID, (Digi << 8 ) + ch}, making mapping into 1-D array to be consolidated printf("################################# \n"); for( int i = 0; i < (int) mapping.size() ; i++){ for( int j = 0; j < (int) mapping[i].size(); j++ ){ printf("%4d,", mapping[i][j]); if( mapping[i][j] >= 0 ) { int groupID = FindDetGroup(mapping[i][j]); int typeID = FindDetTypeID(mapping[i][j]); QList haha ; haha << groupID << mapping[i][j] << ((i << 8 ) + j); detIDListTemp << haha; nDetinType[typeID] ++; nDetinGroup[groupID] ++; } if( j % 16 == 15 ) printf("\n"); } printf("------------------ \n"); } //consolidate detIDListTemp --> 2D array of (detID, (Digi << 8) + ch, +.... ) //for example, {2, 0, 0}, {2, 100, 1}, {2, 200, 2}--> {2, 0, 0, 1, 2}; //for example, {2, 1, 3}, {2, 101, 4}, {2, 201, 5}--> {2, 0, 3, 4, 5}; detIDArrayList.clear(); bool repeated = false; for( int i = 0; i < detIDListTemp.size(); i++ ){ repeated = false; if( detIDArrayList.size() == 0 ){ detIDArrayList << detIDListTemp[i]; continue; } for( int j = 0; j < detIDArrayList.size() ; j++){ if( detIDArrayList[j][0] == detIDListTemp[i][0] ) { // same group int type1 = FindDetTypeID(detIDArrayList[j][1]); int type2 = FindDetTypeID(detIDListTemp[i][1]); int low1 = (type1 == 0 ? 0 : detMaxID[type1-1]); int low2 = (type2 == 0 ? 0 : detMaxID[type2-1]); int detID1 = detIDArrayList[j][1] - low1; int detID2 = detIDListTemp[i][1] - low2; if( detID1 == detID2) { repeated = true; detIDArrayList[j] << detIDListTemp[i][2]; break; } } } if( !repeated ) { detIDArrayList << detIDListTemp[i]; } } //---- sort detIDList; std::sort(detIDArrayList.begin(), detIDArrayList.end(), [](const QList& a, const QList& b) { return a.at(1) < b.at(1); }); //------------- display detector summary //qDebug() << detIDList; printf("---------- num. of det. Type : %d\n", nDetType); for( int i =0; i < nDetType; i ++ ) { detType[i].remove(' '); printf(" Type-%d (%6s) : %3d det. (%3d - %3d)\n", i, detType[i].toStdString().c_str(), nDetinType[i], (i==0 ? 0 : detMaxID[i-1]), detMaxID[i]-1); } printf("---------- num. of det. Group : %d\n", nDetGroup); for( int i =0; i < nDetGroup; i++){ printf(" Group-%d (%10s) : %3d det.\n", i, detGroupName[i].toStdString().c_str(), nDetinGroup[i]); } //---------- Set Panel QGridLayout * mainLayout = new QGridLayout(this); this->setLayout(mainLayout); ///================================= int rowIndex = 0 ; QPushButton * bnRefresh = new QPushButton("Refresh Settings", this); connect(bnRefresh, &QPushButton::clicked, this, &SOLARISpanel::RefreshSettings ); mainLayout->addWidget(bnRefresh, rowIndex, 0, 1, 2); QPushButton * bnSaveSetting = new QPushButton("Save Settings", this); connect(bnSaveSetting, &QPushButton::clicked, this, &SOLARISpanel::SaveSettings); mainLayout->addWidget(bnSaveSetting, rowIndex, 2, 1, 2); QPushButton * bnLoadSetting = new QPushButton("Load Settings", this); connect(bnLoadSetting, &QPushButton::clicked, this, &SOLARISpanel::LoadSettings); mainLayout->addWidget(bnLoadSetting, rowIndex, 4, 1, 2); QLabel * lbCoinTime = new QLabel("Coin. Time (all ch.) [ns]", this); lbCoinTime->setAlignment(Qt::AlignRight | Qt::AlignCenter); mainLayout->addWidget(lbCoinTime, rowIndex, 6, 1, 2); sbCoinTime = new RSpinBox(this); sbCoinTime->setMinimum(-1); sbCoinTime->setMaximum(atof(PHA::CH::CoincidenceLength.GetAnswers()[1].first.c_str())); sbCoinTime->setSingleStep(atof(PHA::CH::CoincidenceLength.GetAnswers()[2].first.c_str())); sbCoinTime->setDecimals(0); sbCoinTime->SetToolTip(atof(PHA::CH::CoincidenceLength.GetAnswers()[1].first.c_str())); mainLayout->addWidget(sbCoinTime, rowIndex, 8, 1, 2); connect(sbCoinTime, &RSpinBox::valueChanged, this, [=](){ if( !enableSignalSlot ) return; sbCoinTime->setStyleSheet("color:blue;"); }); connect(sbCoinTime, &RSpinBox::returnPressed, this, [=](){ if( !enableSignalSlot ) return; //printf("%s %d %d \n", para.GetPara().c_str(), index, spb->value()); if( sbCoinTime->decimals() == 0 && sbCoinTime->singleStep() != 1) { double step = sbCoinTime->singleStep(); double value = sbCoinTime->value(); sbCoinTime->setValue( (std::round(value/step) * step) ); } for(int i = 0; i < (int) mapping.size(); i ++){ if( i >= nDigi || digi[i]->IsDummy() || !digi[i]->IsConnected() ) return; QString msg; msg = QString::fromStdString(PHA::CH::CoincidenceLength.GetPara()) + "|DIG:"+ QString::number(digi[i]->GetSerialNumber()); msg += ",CH:All = " + QString::number(sbCoinTime->value()); if( digi[i]->WriteValue(PHA::CH::CoincidenceLength, std::to_string(sbCoinTime->value()))){ SendLogMsg(msg + "|OK."); sbCoinTime->setStyleSheet(""); }else{ SendLogMsg(msg + "|Fail."); sbCoinTime->setStyleSheet("color:red;"); } } UpdatePanelFromMemory(); }); ///================================= rowIndex ++; QLabel * info = new QLabel("Only simple trigger is avalible. For complex trigger scheme, please use the setting panel.", this); mainLayout->addWidget(info, rowIndex, 0, 1, 4); rowIndex ++; QLabel * info2 = new QLabel("The panel is defined by " + analysisPath + "/working/Mapping.h", this); mainLayout->addWidget(info2, rowIndex, 0, 1, 4); ///================================= rowIndex ++; QTabWidget * tabWidget = new QTabWidget(this); mainLayout->addWidget(tabWidget, rowIndex, 0, 1, 10); for( int detGroup = 0; detGroup < nDetGroup; detGroup ++ ){ QTabWidget * tabSetting = new QTabWidget(tabWidget); tabWidget->addTab(tabSetting, detGroupName[detGroup]); for( int SettingID = 0; SettingID < (int) SettingItems.size(); SettingID ++){ QScrollArea * scrollArea = new QScrollArea(this); scrollArea->setWidgetResizable(true); scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); tabSetting->addTab(scrollArea, QString::fromStdString(SettingItems[SettingID])); QWidget * tab = new QWidget(tabSetting); scrollArea->setWidget(tab); QGridLayout * layout = new QGridLayout(tab); layout->setAlignment(Qt::AlignLeft|Qt::AlignTop); layout->setSpacing(0); chkAll[detGroup][SettingID] = new QCheckBox("Set for all", tab); layout->addWidget(chkAll[detGroup][SettingID], 0, 0); connect(chkAll[detGroup][SettingID], &QCheckBox::stateChanged, this, [=](bool state){ bool found = false; for(int i = 0; i < detIDArrayList.size(); i++){ if( detIDArrayList[i][0] != detGroup ) continue; if( found == false ){ found = true; continue; }else{ groupBox[detGroup][SettingID][detIDArrayList[i][1]]->setEnabled(!state); } } }); QFrame *line = new QFrame(tab); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); line->setFixedHeight(10); layout->addWidget(line, 1, 0, 1, NCOL); for(int i = 0; i < detIDArrayList.size(); i++){ if( detIDArrayList[i][0] != detGroup ) continue; CreateDetGroup(SettingID, detIDArrayList[i], layout, i/NCOL + 2, i%NCOL); } } } enableSignalSlot = true; } SOLARISpanel::~SOLARISpanel(){ } //^###################################################################### int SOLARISpanel::FindDetTypeID(int detID){ for( int i = 0; i < (int) detTypeNameList.size(); i++){ int lowID = (i == 0) ? 0 : detMaxID[i-1]; if( lowID <= detID && detID < detMaxID[i]) { return i; } } return -1; } int SOLARISpanel::FindDetGroup(int detID){ int typeID = FindDetTypeID(detID); if( typeID == -1) return -999; return detGroupID[typeID]; } void SOLARISpanel::CreateDetGroup(int SettingID, QList detIDArray, QGridLayout * &layout, int row, int col){ int detGroup = detIDArray[0]; int detID = detIDArray[1]; groupBox[detGroup][SettingID][detID] = new QGroupBox("Det-" + QString::number(detID), this); groupBox[detGroup][SettingID][detID]->setFixedWidth(130); groupBox[detGroup][SettingID][detID]->setAlignment(Qt::AlignCenter); QGridLayout * layout0 = new QGridLayout(groupBox[detGroup][SettingID][detID]); layout0->setSpacing(0); layout0->setAlignment(Qt::AlignLeft); //@======================================== SpinBox and Display bool isDisableDetector = false; int nChInGroupBox = 0; for( int ppp = ChStartIndex; ppp < detIDArray.size(); ppp ++){ int chIndex = ppp - ChStartIndex; isDisableDetector = false; nChInGroupBox ++; int digiID = (detIDArray[ppp] >> 8 ); int chID = (detIDArray[ppp] & 0xFF); int typeID = FindDetTypeID(mapping[digiID][chID]); QLabel * lb = new QLabel(detTypeNameList[typeID].remove(' '), this); layout0->addWidget(lb, 2*chIndex, 0, 2, 1); chkOnOff[SettingID][digiID][chID] = new QCheckBox(this); layout0->addWidget(chkOnOff[SettingID][digiID][chID], 2*chIndex, 1, 2, 1); leDisplay[SettingID][digiID][chID] = new QLineEdit(this); leDisplay[SettingID][digiID][chID]->setFixedWidth(70); layout0->addWidget(leDisplay[SettingID][digiID][chID], 2*chIndex, 2); sbSetting[SettingID][digiID][chID] = new RSpinBox(this); if( digiID < nDigi ) sbSetting[SettingID][digiID][chID]->setToolTip( "Digi-" + QString::number(digi[digiID]->GetSerialNumber()) + ", Ch-" + QString::number(chID)); sbSetting[SettingID][digiID][chID]->setToolTipDuration(-1); sbSetting[SettingID][digiID][chID]->setFixedWidth(70); sbSetting[SettingID][digiID][chID]->setMinimum(atoi(SettingItems[SettingID].GetAnswers()[0].first.c_str())); sbSetting[SettingID][digiID][chID]->setMaximum(atoi(SettingItems[SettingID].GetAnswers()[1].first.c_str())); sbSetting[SettingID][digiID][chID]->setSingleStep(atoi(SettingItems[SettingID].GetAnswers()[2].first.c_str())); layout0->addWidget(sbSetting[SettingID][digiID][chID], 2*chIndex+1, 2); if( digiID >= nDigi || chID >= digi[digiID]->GetNChannels() ) { leDisplay[SettingID][digiID][chID]->setEnabled(false); sbSetting[SettingID][digiID][chID]->setEnabled(false); chkOnOff[SettingID][digiID][chID]->setEnabled(false); isDisableDetector = true; } ///========================= for SpinBox RSpinBox * spb = sbSetting[SettingID][digiID][chID]; const Reg para = SettingItems[SettingID]; connect(spb, &RSpinBox::valueChanged, this, [=](){ if( !enableSignalSlot ) return; spb->setStyleSheet("color:blue;"); }); connect(spb, &RSpinBox::returnPressed, this, [=](){ if( !enableSignalSlot ) return; //printf("%s %d %d \n", para.GetPara().c_str(), index, spb->value()); if( spb->decimals() == 0 && spb->singleStep() != 1) { double step = spb->singleStep(); double value = spb->value(); spb->setValue( (std::round(value/step) * step) ); } if( chkAll[detGroup][SettingID]->isChecked() ){ for(int k = 0; k < detIDArrayList.size() ; k++){ if( detGroup == detIDArrayList[k][0] ){ for( int h = ChStartIndex; h < detIDArrayList[k].size() ; h++){ if( h != chIndex + ChStartIndex) continue; int digiK = (detIDArrayList[k][h] >> 8); if( digiK >= nDigi ) continue; int index = (detIDArrayList[k][h] & 0xFF); QString msg; msg = QString::fromStdString(para.GetPara()) + "|DIG:"+ QString::number(digi[digiK]->GetSerialNumber()); msg += ",CH:" + QString::number(index) + "(" + detTypeNameList[typeID] + ")"; msg += " = " + QString::number(spb->value()); if( digi[digiK]->WriteValue(para, std::to_string(spb->value()), index)){ SendLogMsg(msg + "|OK."); spb->setStyleSheet(""); }else{ SendLogMsg(msg + "|Fail."); spb->setStyleSheet("color:red;"); } } } } }else{ QString msg; msg = QString::fromStdString(para.GetPara()) + "|DIG:"+ QString::number(digi[digiID]->GetSerialNumber()); msg += ",CH:" + QString::number(chID) + "(" + detTypeNameList[typeID] + ")"; msg += " = " + QString::number(spb->value()); if( digi[digiID]->WriteValue(para, std::to_string(spb->value()), chID)){ SendLogMsg(msg + "|OK."); spb->setStyleSheet(""); }else{ SendLogMsg(msg + "|Fail."); spb->setStyleSheet("color:red;"); } } UpdatePanelFromMemory(); UpdateOtherPanels(); }); ///===================== for the OnOff CheckBox connect(chkOnOff[SettingID][digiID][chID], &QCheckBox::stateChanged, this, [=](int state){ if( !enableSignalSlot ) return; if( chkAll[detGroup][SettingID]->isChecked() ){ for(int k = 0; k < detIDArrayList.size() ; k++){ if( detGroup == detIDArrayList[k][0] ){ for( int h = ChStartIndex; h < detIDArrayList[k].size() ; h++){ if( h != chIndex + ChStartIndex) continue; int digiK = (detIDArrayList[k][h] >> 8); if( digiK >= nDigi ) continue; int index = (detIDArrayList[k][h] & 0xFF); QString msg; msg = QString::fromStdString(PHA::CH::ChannelEnable.GetPara()) + "|DIG:"+ QString::number(digi[digiK]->GetSerialNumber()); msg += ",CH:" + QString::number(index) + "(" + detTypeNameList[typeID] + ")"; msg += ( state ? " = True" : " = False"); if( digi[digiK]->WriteValue(PHA::CH::ChannelEnable, state ? "True" : "False", index)){ SendLogMsg(msg + "|OK."); enableSignalSlot = false; leDisplay[detGroup][digiK][index]->setEnabled(state); sbSetting[detGroup][digiK][index]->setEnabled(state); chkOnOff [detGroup][digiK][index]->setChecked(state); enableSignalSlot = true; }else{ SendLogMsg(msg + "|Fail."); } } } } }else{ QString msg; msg = QString::fromStdString(PHA::CH::ChannelEnable.GetPara()) + "|DIG:"+ QString::number(digi[digiID]->GetSerialNumber()); msg += ",CH:" + QString::number(chID) + "(" + detTypeNameList[typeID] + ")"; msg += ( state ? " = True" : " = False"); qDebug() << msg; if( digi[digiID]->WriteValue(PHA::CH::ChannelEnable, state ? "True" : "False", chID)){ SendLogMsg(msg + "|OK."); enableSignalSlot = false; leDisplay[detGroup][digiID][chID]->setEnabled(state); sbSetting[detGroup][digiID][chID]->setEnabled(state); chkOnOff [detGroup][digiID][chID]->setChecked(state); enableSignalSlot = true; }else{ SendLogMsg(msg + "|Fail."); } } UpdatePanelFromMemory(); UpdateOtherPanels(); }); layout0->setColumnStretch(0, 1); layout0->setColumnStretch(1, 1); layout0->setColumnStretch(2, 5); } //@======================================== Trigger Combox //=================== The Trigger depnds on 5 settings (at least) // EventTriggerSource, WaveTriggerSource, CoincidentMask, AntiCoincidentMask // 1, EventTriggerSource has 8 settings, ITLA, ITLB, GlobalTriggerSource, TRGIN, SWTrigger, ChSelfTrigger, Ch64Trigger, Disabled // 2, WaveTriggerSource has 8 settings, always set to be equal EventTriggerSource // 3, CoincidentMak has 6 Settings, Disabled, Ch64Trigger, TRGIN, GloableTriggerSource, ITLA, ITLB // 4, AntiCoincidentMask has 6 Settings, always disabled // 5, ChannelTriggerMask is a 64-bit // 6, CoincidenceLengthT in ns, set to be 100 ns. if( SettingItems[SettingID].GetPara() == PHA::CH::TriggerThreshold.GetPara()){ cbTrigger[detGroup][detID] = new RComboBox(this); cbTrigger[detGroup][detID]->addItem("Self Trigger", "ChSelfTrigger"); /// no coincident cbTrigger[detGroup][detID]->addItem("Trigger e", 0x1); // Self-trigger and coincient Ch64Trigger cbTrigger[detGroup][detID]->addItem("Ext. Trigger", "TRGIN"); // with coincident with TRGIN. cbTrigger[detGroup][detID]->addItem("Disabled", "Disabled"); // no Trigger, no coincident, basically channel still alive, but no recording cbTrigger[detGroup][detID]->addItem("Others", -999); // other settings layout0->addWidget(cbTrigger[detGroup][detID], 2*nChInGroupBox, 0, 1, 3); if( isDisableDetector ) cbTrigger[detGroup][detID]->setEnabled(false); //*========== connection connect(cbTrigger[detGroup][detID], &RComboBox::currentIndexChanged, this , [=](int index){ if( !enableSignalSlot) return; if( chkAll[detGroup][SettingID]->isChecked() ){ for( int k = 0; k < detIDArrayList.size(); k++){ if( detIDArrayList[k][0] != detGroup ) continue; int haha = detIDArrayList[k][1]; if( haha == detID )continue; cbTrigger[detGroup][haha]->setCurrentIndex(index); } } ///----------- single for( int i = ChStartIndex ; i < detIDArray.size(); i++){ int digiID = (detIDArray[i] >> 8 ); if( digiID >= nDigi) continue; int chID = (detIDArray[i] & 0xFF); if( digi[digiID]->IsDummy() || !digi[digiID]->IsConnected() ) continue; digi[digiID]->WriteValue(PHA::CH::AntiCoincidenceMask, "Disabled", chID); switch(index){ case 0 : { /// Self Trigger digi[digiID]->WriteValue(PHA::CH::EventTriggerSource, "ChSelfTrigger", chID); digi[digiID]->WriteValue(PHA::CH::WaveTriggerSource, "ChSelfTrigger", chID); digi[digiID]->WriteValue(PHA::CH::CoincidenceMask, "Disabled", chID); }; break; case 1 : { /// trigger by energy digi[digiID]->WriteValue(PHA::CH::EventTriggerSource, "ChSelfTrigger", chID); digi[digiID]->WriteValue(PHA::CH::WaveTriggerSource, "ChSelfTrigger", chID); if( i == ChStartIndex ){ digi[digiID]->WriteValue(PHA::CH::CoincidenceMask, "Disabled", chID); }else { digi[digiID]->WriteValue(PHA::CH::CoincidenceMask, "Ch64Trigger", chID); digi[digiID]->WriteValue(PHA::CH::CoincidenceLength, "100"); //Form the trigger bit unsigned long mask = 1ULL << (detIDArray[ChStartIndex] & 0xFF ); // trigger by energy QString maskStr = QString::number(mask); digi[digiID]->WriteValue(PHA::CH::ChannelsTriggerMask, maskStr.toStdString() , chID); } }; break; case 2 : { /// TRGIN, when the whole board is trigger by TRG-IN digi[digiID]->WriteValue(PHA::CH::EventTriggerSource, "TRGIN", chID); digi[digiID]->WriteValue(PHA::CH::WaveTriggerSource, "TRGIN", chID); digi[digiID]->WriteValue(PHA::CH::CoincidenceMask, "TRGIN", chID); digi[digiID]->WriteValue(PHA::CH::CoincidenceLength, "100"); }; break; case 3 : { /// disbaled digi[digiID]->WriteValue(PHA::CH::EventTriggerSource, "Disabled", chID); digi[digiID]->WriteValue(PHA::CH::WaveTriggerSource, "Disabled", chID); digi[digiID]->WriteValue(PHA::CH::CoincidenceMask, "Disabled", chID); }; break; } SendLogMsg("SOLARIS panel : Set Trigger = " + cbTrigger[detGroup][detID]->itemText(index) + "|Digi:" + QString::number(digi[digiID]->GetSerialNumber()) + ",Det:" + QString::number(detID)); } UpdatePanelFromMemory(); UpdateOtherPanels(); }); } layout->addWidget(groupBox[detGroup][SettingID][detID], row, col); } //^############################################################## void SOLARISpanel::RefreshSettings(){ for( int i = 0 ; i < nDigi; i++){ if( digi[i]->IsDummy() || !digi[i]->IsConnected()){ digi[i]->ReadAllSettings(); } } UpdatePanelFromMemory(); } void SOLARISpanel::UpdatePanelFromMemory(){ if( !isVisible() ) return; enableSignalSlot = false; printf("SOLARISpanel::%s\n", __func__); //@===================== LineEdit and SpinBox for( int SettingID = 0; SettingID < (int) SettingItems.size() ; SettingID ++){ for( int DigiID = 0; DigiID < (int) mapping.size(); DigiID ++){ if( DigiID >= nDigi ) continue;; for( int chID = 0; chID < (int) mapping[DigiID].size(); chID++){ if( mapping[DigiID][chID] < 0 ) continue; std::string haha = digi[DigiID]->GetSettingValue(SettingItems[SettingID], chID); sbSetting[SettingID][DigiID][chID]->setValue( atof(haha.c_str())); if( SettingItems[SettingID].GetPara() == PHA::CH::TriggerThreshold.GetPara() ){ std::string haha = digi[DigiID]->GetSettingValue(PHA::CH::SelfTrgRate, chID); leDisplay[SettingID][DigiID][chID]->setText(QString::number(atof(haha.c_str()), 'f', 2) ); }else{ leDisplay[SettingID][DigiID][chID]->setText(QString::number(atof(haha.c_str()), 'f', 2) ); } haha = digi[DigiID]->GetSettingValue(PHA::CH::ChannelEnable, chID); chkOnOff[SettingID][DigiID][chID]->setChecked( haha == "True" ? true : false); leDisplay[SettingID][DigiID][chID]->setEnabled(haha == "True" ? true : false); sbSetting[SettingID][DigiID][chID]->setEnabled(haha == "True" ? true : false); //printf("====== %d %d %d |%s|\n", SettingID, DigiID, chID, haha.c_str()); } } } //@===================== Trigger for( int k = 0; k < detIDArrayList.size() ; k++){ if( detIDArrayList[k][1] >= detMaxID[0] || 0 > detIDArrayList[k][1]) continue; //! only for array if( detIDArrayList[k][0] != 0 ) continue; //if( detIDList[k].size() <= 2) continue; bool skipFlag = false; std::vector triggerMap; std::vector coincidentMask; std::vector antiCoincidentMask; std::vector eventTriggerSource; std::vector waveTriggerSource; for( int h = ChStartIndex; h < detIDArrayList[k].size(); h++){ int digiID = detIDArrayList[k][h] >> 8; if( digiID >= nDigi) { skipFlag = true; continue; } int chID = (detIDArrayList[k][h] & 0xFF); triggerMap.push_back(Utility::TenBase(digi[digiID]->GetSettingValue(PHA::CH::ChannelsTriggerMask, chID))); coincidentMask.push_back(digi[digiID]->GetSettingValue(PHA::CH::CoincidenceMask, chID)); antiCoincidentMask.push_back(digi[digiID]->GetSettingValue(PHA::CH::AntiCoincidenceMask, chID)); eventTriggerSource.push_back(digi[digiID]->GetSettingValue(PHA::CH::EventTriggerSource, chID)); waveTriggerSource.push_back(digi[digiID]->GetSettingValue(PHA::CH::WaveTriggerSource, chID)); } if(skipFlag) continue; //====== only acceptable condition is eventTriggerSource are all ChSelfTrigger // and coincidentMask for e, xf, xn, are at least one for Ch64Trigger // and waveTriggerSource are all ChSelfTrigger //====== a stupid way // triggerSource : Other = 0x0, Disabled = 0x1, ChSelfTrigger = 0x2, TRGIN = 0x3 // CoinMask : Other = 0x0, Disbaled = 0x1, Ch64Trigger = 0x2, TRGIN = 0x3 // for example, SelfTrigger should be, 0x2211, triggerMask does not matter. // |||+-- anti-coin // ||+-- coin // |+-- wave // +-- event // comboxIndex 0) SelfTrigger 0x2211, any trigger mask // comboxIndex 2) TRGIN 0x3331, any trigger mask // comboxIndex 3) Disable 0x1111, any trigger mask // comboxIndex 1) Trigger E {0x2211 - e , 0x2221 - xf, 0x2221 - xn }, // triggerMask { 0, 0x1, 0x1} // comboxIndex 4) Other settings std::vector stupidIndex; for( int i = 0 ; i < (int) triggerMap.size(); i++){ unsigned int index = 0; if(antiCoincidentMask[i] == "Disabled") index += 0x1; if(antiCoincidentMask[i] == "Ch64Trigger") index += 0x2; if(antiCoincidentMask[i] == "TRGIN") index += 0x3; if(coincidentMask[i] == "Disabled") index += 0x10; if(coincidentMask[i] == "Ch64Trigger") index += 0x20; if(coincidentMask[i] == "TRGIN") index += 0x30; if(waveTriggerSource[i] == "Disabled") index += 0x100; if(waveTriggerSource[i] == "ChSelfTrigger") index += 0x200; if(waveTriggerSource[i] == "TRGIN") index += 0x300; if(eventTriggerSource[i] == "Disabled") index += 0x1000; if(eventTriggerSource[i] == "ChSelfTrigger") index += 0x2000; if(eventTriggerSource[i] == "TRGIN") index += 0x3000; stupidIndex.push_back(index); } //printf("===================== detIDList : %d %d \n", detIDList[k][0], detIDList[k][1]); int jaja[5] = {0}; // this store the count for each comboxIndex; for( int i = 0; i < (int) stupidIndex.size(); i++){ //printf(" %d | 0x%s \n", i, QString::number(stupidIndex[i], 16).toUpper().toStdString().c_str()); if( stupidIndex[i] == 0x2211 ) jaja[0] ++; if( stupidIndex[i] == 0x3331 ) jaja[2] ++; if( stupidIndex[i] == 0x1111 ) jaja[3] ++; if( i == 0 && stupidIndex[i] == 0x2211 ) jaja[1] ++; if( i > 0 && stupidIndex[i] == 0x2221 ) jaja[1] ++; } //Search for jaja, see is there any one equal to total number of ch; int comboxIndex = 4; for( int i = 0; i < 5; i++){ //printf("%d | %d \n", i, jaja[i]); if( jaja[i] == (int) stupidIndex.size() )comboxIndex = i; } //printf("comboxIndex : %d \n", comboxIndex); // if Trigger e, need to check the trigger mask; if( comboxIndex == 3){ unsigned long ShouldBeMask = 1ULL << (detIDArrayList[k][ChStartIndex] & 0xFF); for( int i = 1; i < (int) triggerMap.size(); i ++){ //printf(" %d | %lu =? %lu \n", i, triggerMap[i], ShouldBeMask); if( triggerMap[i] != ShouldBeMask) comboxIndex = 4; } } int detGroup = FindDetGroup(detIDArrayList[k][1]); cbTrigger[detGroup][detIDArrayList[k][1]]->setCurrentIndex(comboxIndex); } //@===================== Coin. time std::vector coinTime; for( int i = 0; i < detIDArrayList.size(); i++){ for( int j = ChStartIndex; j < detIDArrayList[i].size(); j++){ int digiID = detIDArrayList[i][j] >> 8; int chID = (detIDArrayList[i][j] & 0xFF); if( digiID >= nDigi ) continue; if( digi[digiID]->IsDummy() || !digi[digiID]->IsConnected() ) continue; coinTime.push_back( atoi(digi[digiID]->GetSettingValue(PHA::CH::CoincidenceLength, chID).c_str())); } } bool isSameCoinTime = true; for( int i = 1; i < (int) coinTime.size(); i++){ if( coinTime[i] != coinTime[0]) { isSameCoinTime = false; break; } } if( isSameCoinTime ){ sbCoinTime->setValue(coinTime[0]); }else{ sbCoinTime->setValue(-1); } enableSignalSlot = true; } void SOLARISpanel::UpdateThreshold(){ for( int SettingID = 0; SettingID < (int) SettingItems.size() ; SettingID ++){ if( SettingItems[SettingID].GetPara() != PHA::CH::TriggerThreshold.GetPara() ) continue; for( int DigiID = 0; DigiID < (int) mapping.size(); DigiID ++){ if( DigiID >= nDigi ) continue;; for( int chID = 0; chID < (int) mapping[DigiID].size(); chID++){ if( mapping[DigiID][chID] < 0 ) continue; std::string haha = digi[DigiID]->GetSettingValue(PHA::CH::SelfTrgRate, chID); leDisplay[SettingID][DigiID][chID]->setText(QString::fromStdString(haha)); ///printf("====== %d %d %d |%s|\n", SettingID, DigiID, chID, haha.c_str()); } } } } //^######################################### void SOLARISpanel::SaveSettings(){ for(int i = 0; i < nDigi; i++){ //*------ search for settings_XXXX.dat //Check path exist QDir dir(digiSettingPath); if( !dir.exists() ) dir.mkpath("."); QString settingFile = digiSettingPath + "/setting_" + QString::number(digi[i]->GetSerialNumber()) + "_" + QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss") + ".dat"; int flag = digi[i]->SaveSettingsToFile(settingFile.toStdString().c_str()); switch (flag) { case 1 : { SendLogMsg("Saved setting file " + settingFile + "."); }; break; case 0 : { SendLogMsg(" Fail to write setting file. " + settingFile + " "); }; break; case -1 : { SendLogMsg(" Fail to save setting file " + settingFile + " , same settings are empty."); }; break; }; } } void SOLARISpanel::LoadSettings(){ for(int i = 0; i < nDigi; i++){ //*------ search for settings_XXXX.dat QString settingFile = digiSettingPath + "/settings_" + QString::number(digi[i]->GetSerialNumber()) + ".dat"; if( digi[i]->LoadSettingsFromFile( settingFile.toStdString().c_str() ) ){ SendLogMsg("Found setting file " + settingFile + " and loading. please wait."); digi[i]->SetSettingFileName(settingFile.toStdString()); SendLogMsg("done settings."); }else{ SendLogMsg("Unable to found setting file " + settingFile + ". "); digi[i]->SetSettingFileName(""); } } }