#include #include #include #include #include #include #include #include #include #include #include "programSetting.h" #include "triggerSummary.h" extern unsigned short nDigi; extern Digitizer ** digi; //extern bool ProgramSetting::EnableDatabase; bool TriggerSummary::updateFlag = true; TGTextEntry * TriggerSummary::txtTrigger[MaxNBoards][MaxNChannels] = {NULL}; TGTextEntry * TriggerSummary::txtThresholdValue[MaxNBoards][MaxNChannels] = {NULL}; TGTextEntry * TriggerSummary::txtThreshold[MaxNBoards][MaxNChannels] = {NULL}; TGCheckButton * TriggerSummary::cbChannelEnable[MaxNBoards][MaxNChannels] = {NULL}; TGNumberEntry * TriggerSummary::numUpdateTime = NULL; unsigned short TriggerSummary::value[MaxNBoards][MaxNChannels] = {0}; bool TriggerSummary::onOff[MaxNBoards][MaxNChannels] = {true}; TriggerSummary::TriggerSummary(const TGWindow *p, const TGWindow *main){ fMain = new TGTransientFrame(p,main); fMain->SetWindowName("Scalar Panel"); fMain->Connect("CloseWindow()", "TriggerSummary", this, "CloseWindow()"); fMain->CenterOnParent(true, TGTransientFrame::EPlacement::kTopRight); fMain->SetMWMHints(1,4, 0); //tested many time to have no close button. TGHorizontalFrame *hframe = new TGHorizontalFrame(fMain); fMain->AddFrame(hframe); TGLayoutHints * kaka = new TGLayoutHints(kLHintsLeft, 0,0,0,0); /// left, right, top, bottom TGLayoutHints * lala = new TGLayoutHints(kLHintsLeft, 0,0,3,2); /// left, right, top, bottom TGGroupFrame * gBD[nDigi]; TGLabel * lbCh[nDigi][MaxNChannels]; for( int bd = 0; bd < nDigi; bd++){ gBD[bd] = new TGGroupFrame(hframe, Form("Board-%02d", bd), kHorizontalFrame); hframe->AddFrame(gBD[bd], new TGLayoutHints( kLHintsExpandY, 5, 0, 5, 5)); TGVerticalFrame * vframe0 = new TGVerticalFrame(gBD[bd]); gBD[bd]->AddFrame(vframe0, new TGLayoutHints(kLHintsCenterX, 0, 0, 0, 0)); TGVerticalFrame * vframe1 = new TGVerticalFrame(gBD[bd]); gBD[bd]->AddFrame(vframe1, new TGLayoutHints(kLHintsCenterX, 0, 0, 0, 0)); TGVerticalFrame * vframe2 = new TGVerticalFrame(gBD[bd]); gBD[bd]->AddFrame(vframe2, new TGLayoutHints(kLHintsCenterX, 0, 0, 0, 0)); TGVerticalFrame * vframe3 = new TGVerticalFrame(gBD[bd]); gBD[bd]->AddFrame(vframe3, new TGLayoutHints(kLHintsCenterX, 0, 0, 0, 0)); TGVerticalFrame * vframe4 = new TGVerticalFrame(gBD[bd]); gBD[bd]->AddFrame(vframe4, new TGLayoutHints(kLHintsCenterX, 0, 0, 0, 0)); TGLabel * lbCh0 = new TGLabel(vframe0, "ch"); vframe0->AddFrame(lbCh0, new TGLayoutHints(kLHintsCenterY, 0,5,3,2)); TGLabel * lbTrigger = new TGLabel(vframe1, "Trig.[Hz]"); vframe1->AddFrame(lbTrigger, new TGLayoutHints(kLHintsCenterY, 5,5,3,2)); TGLabel * lbThreshold = new TGLabel(vframe2, "Thres."); vframe2->AddFrame(lbThreshold, new TGLayoutHints(kLHintsCenterY, 5,5,3,2)); TGLabel * lbdummy = new TGLabel(vframe3, ""); vframe3->AddFrame(lbdummy, new TGLayoutHints(kLHintsCenterY, 5,5,3,2)); TGLabel * lbdummy2 = new TGLabel(vframe4, ""); vframe4->AddFrame(lbdummy2, new TGLayoutHints(kLHintsCenterY, 5,5,3,2)); uint32_t chMask = 0xFFFF; if( digi != NULL ) chMask = digi[bd]->ReadRegister(Register::DPP::ChannelEnableMask); for( int ch = 0; ch < (digi == NULL ? MaxNChannels: digi[bd]->GetNChannel()); ch++){ lbCh[bd][ch] = new TGLabel(vframe0, Form("%02d", ch)); vframe0->AddFrame(lbCh[bd][ch], new TGLayoutHints(kLHintsCenterY, 0,5,4,2)); txtTrigger[bd][ch] = new TGTextEntry(vframe1, ""); vframe1->AddFrame(txtTrigger[bd][ch], kaka); txtTrigger[bd][ch]->Resize(50,20); txtTrigger[bd][ch]->SetEnabled(false); txtTrigger[bd][ch]->SetAlignment(kTextRight); txtThresholdValue[bd][ch] = new TGTextEntry(vframe2, ""); vframe2->AddFrame(txtThresholdValue[bd][ch], kaka); txtThresholdValue[bd][ch]->Resize(50,20); txtThresholdValue[bd][ch]->SetEnabled(false); txtThresholdValue[bd][ch]->SetAlignment(kTextRight); value[bd][ch] = 0; if( digi != NULL ){ if( digi[bd]->GetDPPType() == V1730_DPP_PSD_CODE ) value[bd][ch] = digi[bd]->GetSettingFromMemory(Register::DPP::PSD::TriggerThreshold, ch); if( digi[bd]->GetDPPType() == V1730_DPP_PHA_CODE ) value[bd][ch] = digi[bd]->GetSettingFromMemory(Register::DPP::PHA::TriggerThreshold, ch); } txtThresholdValue[bd][ch]->SetText(Form("%d", value[bd][ch]), false); txtThreshold[bd][ch] = new TGTextEntry(vframe3, "", 100*bd + ch); vframe3->AddFrame(txtThreshold[bd][ch], kaka); txtThreshold[bd][ch]->Resize(50,20); txtThreshold[bd][ch]->SetAlignment(kTextRight); txtThreshold[bd][ch]->Connect("ReturnPressed()", "TriggerSummary", this, "SetThreshold()"); txtThreshold[bd][ch]->SetText(Form("%d", value[bd][ch]), false); cbChannelEnable[bd][ch] = new TGCheckButton(vframe4, ""); vframe4->AddFrame(cbChannelEnable[bd][ch], lala); cbChannelEnable[bd][ch]->Resize(50,20); cbChannelEnable[bd][ch]->SetState(kButtonDown); cbChannelEnable[bd][ch]->Connect("Clicked()", "TriggerSummary", this, "SetChannelEnable()"); if( ( chMask & ( 1 << ch ) ) == 0 ) { txtThreshold[bd][ch]->SetEnabled(false); cbChannelEnable[bd][ch]->SetState(kButtonUp); onOff[bd][ch] = false; }else{ onOff[bd][ch] = true; } } } TGHorizontalFrame * hframeSetting = new TGHorizontalFrame(fMain); fMain->AddFrame(hframeSetting, new TGLayoutHints(kLHintsExpandX)); TGLabel * lbUpDateTime = new TGLabel(hframeSetting, "Update Period [msec]:"); hframeSetting->AddFrame(lbUpDateTime, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5,5,3,3)); numUpdateTime = new TGNumberEntry(hframeSetting, 1000, 0, 0, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); hframeSetting->AddFrame(numUpdateTime, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5,5,3,3)); numUpdateTime->Resize(50, 20); fMain->MapSubwindows(); fMain->Resize(fMain->GetDefaultSize()); fMain->MapWindow(); updateFlag = true; if( digi != NULL ){ printf("-------- %s thread\n", __func__); thread = new TThread("hahaha", UpdateTriggerRate, (void *) 0); thread->Run(); } } TriggerSummary::~TriggerSummary(){ printf("Close %s \n", __func__); for(int i = 0; i < nDigi; i++){ for(int j = 0; j < MaxNChannels; j++){ delete txtTrigger[i][j]; delete txtThresholdValue[i][j]; delete txtThreshold[i][j]; delete cbChannelEnable[i][j]; } } delete numUpdateTime; updateFlag = false; thread->Join(); ///delete thread; /// Don;t delete the thread, otherwise, thread will not run after close and reopen. printf("%s ========== finial clena up\n", __func__); fMain->Cleanup(); delete fMain; } void * TriggerSummary::UpdateTriggerRate(void * ptr){ std::string tempDBPath = ProgramSetting::DataSavingPath + "/tempDB.txt"; std::string cmd = "curl -XPOST " + ProgramSetting::databaseIP + "/write?db=" + ProgramSetting::databaseName + " --data-binary @" + tempDBPath; std::ofstream myfile; unsigned int t1 = get_time(); unsigned int t2 = 0; while( updateFlag){ for( int bd = 0; bd < nDigi; bd++){ for( int ch = 0; ch < digi[bd]->GetNChannel(); ch++){ txtTrigger[bd][ch]->SetText(Form("%.2f", digi[bd]->GetData()->TriggerRate[ch])); value[bd][ch] = digi[bd]->GetSettingFromMemory(Register::DPP::PHA::TriggerThreshold, ch); txtThresholdValue[bd][ch]->SetText(Form("%d", value[bd][ch]), false); } } t2 = get_time(); if( ProgramSetting::EnableDatabase && (t2 - t1) > 5*1e6){ myfile.open(tempDBPath); for( int bd = 0; bd < nDigi; bd++){ for( int ch = 0; ch < digi[bd]->GetNChannel(); ch++){ myfile << "Rate,Bd=" << bd << ",Ch=" << ch << " value=" << digi[bd]->GetData()->TriggerRate[ch] << "\n"; } } myfile.close(); int temp = system(cmd.c_str()); t1 = t2; } usleep(numUpdateTime->GetNumber() * 1000); } return 0; } void TriggerSummary::SetThreshold(){ if( digi == NULL ) return; for( int bd = 0; bd < nDigi; bd++){ bool isACQRunning = digi[bd]->IsRunning(); for( int ch = 0; ch < digi[bd]->GetNChannel(); ch++){ unsigned int haha = atoi( txtThreshold[bd][ch]->GetText()); if( value[bd][ch] != haha ){ if( isACQRunning ) { digi[bd]->StopACQ(); usleep(500*1000); } if( digi[bd]->GetDPPType() == V1730_DPP_PSD_CODE ) { digi[bd]->WriteRegister(Register::DPP::PSD::TriggerThreshold, haha, ch); value[bd][ch] = digi[bd]->GetSettingFromMemory(Register::DPP::PSD::TriggerThreshold, ch); } if( digi[bd]->GetDPPType() == V1730_DPP_PHA_CODE ) { digi[bd]->WriteRegister(Register::DPP::PHA::TriggerThreshold, haha, ch); value[bd][ch] = digi[bd]->GetSettingFromMemory(Register::DPP::PHA::TriggerThreshold, ch); } txtThresholdValue[bd][ch]->SetText(Form("%d", value[bd][ch]), false); if( isACQRunning ) { usleep(500*1000); digi[bd]->StartACQ(); } } } } } void TriggerSummary::SetChannelEnable(){ if( digi == NULL ) return; for( int bd = 0; bd < nDigi; bd++){ bool isACQRunning = digi[bd]->IsRunning(); for( int ch = 0; ch < digi[bd]->GetNChannel(); ch++){ bool state = ( cbChannelEnable[bd][ch]->GetState() == kButtonDown ? true : false); if( onOff[bd][ch] != state ){ if( isACQRunning ) { digi[bd]->StopACQ(); usleep(500*1000); } digi[bd]->SetChannelOnOff(ch, state); onOff[bd][ch] = state; txtThreshold[bd][ch]->SetEnabled(state); if( isACQRunning ) { usleep(500*1000); digi[bd]->StartACQ(); } } } } }