#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "DigitizerPHA.h" #include "DigitizerPSD.h" #include "FSUDAQ.h" enum MenuIdentifiers{ M_DIGITIZER_OPEN, M_FILE_OPEN, M_EXIT, M_LOAD_SETTINGS, M_VIEW_SETTINGS, // TODO M_TRIGGER_SUMMARY, M_CH_SETTING_PHA, M_CH_SETTING_PSD, M_BOARD_SETTINGS, M_PROGRAM_SETTINGS, M_FINDPEAKS, M_SHOW_CHANNELS_RATE }; ///make static members Digitizer ** MainWindow::digi = NULL; TGTextEdit * MainWindow::teLog = NULL; TRootEmbeddedCanvas * MainWindow::fEcanvas = NULL; MainWindow::MainWindow(const TGWindow *p,UInt_t w,UInt_t h) { nDigi = 0; /// Create a main frame fMain = new TGMainFrame(p,w,h); ///fMain->SetWMPosition(500, 500); //does not work fMain->Connect("CloseWindow()", "MainWindow", this, "GoodBye()"); {///======================= menu fMenuBar = new TGMenuBar(fMain, 1, 1, kHorizontalFrame); fMain->AddFrame(fMenuBar, new TGLayoutHints(kLHintsTop | kLHintsExpandX)); fMenuFile = new TGPopupMenu(gClient->GetRoot()); fMenuFile->AddEntry("&Open File", M_FILE_OPEN); fMenuFile->AddSeparator(); fMenuFile->AddEntry("E&xit", M_EXIT); fMenuFile->Connect("Activated(Int_t)", "MainWindow", this, "HandleMenu(Int_t)"); fMenuBar->AddPopup("&File", fMenuFile, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0)); fMenuDigitizers = new TGPopupMenu(gClient->GetRoot()); fMenuDigitizers->AddEntry("&Open Digitizers", M_DIGITIZER_OPEN); fMenuDigitizers->AddEntry("&Load Settings", M_LOAD_SETTINGS); fMenuDigitizers->AddEntry("&Trigger Summary", M_TRIGGER_SUMMARY); fMenuDigitizers->AddSeparator(); fMenuDigitizers->AddEntry("Digitizer &Settings", M_BOARD_SETTINGS); fMenuDigitizers->AddEntry("&Channel Settings (PHA)", M_CH_SETTING_PHA); fMenuDigitizers->AddEntry("&Channel Settings (PSD)", M_CH_SETTING_PSD); fMenuDigitizers->AddSeparator(); fMenuDigitizers->AddEntry("&Program Settings", M_PROGRAM_SETTINGS); fMenuDigitizers->Connect("Activated(Int_t)", "MainWindow", this, "HandleMenu(Int_t)"); fMenuBar->AddPopup("&Digitizers", fMenuDigitizers, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0)); fMenuDigitizers->DisableEntry( M_TRIGGER_SUMMARY); fMenuDigitizers->DisableEntry( M_LOAD_SETTINGS); //fMenuDigitizers->DisableEntry( M_BOARD_SETTINGS); //fMenuDigitizers->DisableEntry( M_CH_SETTING); fMenuUtility = new TGPopupMenu(gClient->GetRoot()); fMenuUtility->AddEntry("Plot Channels Rate", M_SHOW_CHANNELS_RATE); fMenuDigitizers->AddSeparator(); fMenuUtility->AddEntry("Find &Peaks", M_FINDPEAKS); fMenuUtility->Connect("Activated(Int_t)", "MainWindow", this, "HandleMenu(Int_t)"); fMenuBar->AddPopup("&Utility", fMenuUtility, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0)); } TGHorizontalFrame *hframe = new TGHorizontalFrame(fMain); fMain->AddFrame(hframe, new TGLayoutHints(kLHintsCenterX,2,2,2,2)); {///================= Create a horizontal frame widget with buttons TGGroupFrame * group0 = new TGGroupFrame(hframe, "Hahaha", kHorizontalFrame); hframe->AddFrame(group0 ); TGHorizontalFrame *hfg0 = new TGHorizontalFrame(group0,200,30); group0->AddFrame(hfg0 ,new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0)); TGLayoutHints * uniLayoutHints = new TGLayoutHints(kLHintsNormal, 2,2,10,0); ///left, right, top, bottom bOpenDigitizers = new TGTextButton(hfg0,"Open Digitizers"); hfg0->AddFrame(bOpenDigitizers, uniLayoutHints); bOpenDigitizers->Connect("Clicked()","MainWindow",this,"OpenDigitizers()"); TGTextButton *bStartRun = new TGTextButton(hfg0,"Start Run"); hfg0->AddFrame(bStartRun, uniLayoutHints); bStartRun->Connect("Clicked()", "MainWindow", this, "StartRun()"); TGTextButton *bStopRun = new TGTextButton(hfg0,"Stop Run"); hfg0->AddFrame(bStopRun, uniLayoutHints); bStopRun->Connect("Clicked()", "MainWindow", this, "StopRun()"); TGCheckButton* bSaveData = new TGCheckButton(hfg0, "ACQ Start/Arm", 1); hfg0->AddFrame(bSaveData, uniLayoutHints); bSaveData->SetState(kButtonDown); } {///================= sigle Channel group TGGroupFrame * group1 = new TGGroupFrame(hframe, "Single Channel", kHorizontalFrame); hframe->AddFrame(group1 ); TGHorizontalFrame *hfg1 = new TGHorizontalFrame(group1,200,30); group1->AddFrame(hfg1 ,new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0)); TGLayoutHints * haha = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 10, 0); ///left, right, top, bottom TGLabel * lb0 = new TGLabel(hfg1, "Board"); hfg1->AddFrame(lb0, haha); TGNumberEntry * boardIDEntry = new TGNumberEntry(hfg1, 0, 0, 0, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); hfg1->AddFrame(boardIDEntry, haha); boardIDEntry->SetWidth(50); //boardIDEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, nBoard-1); TGLabel * lb1 = new TGLabel(hfg1, "Channel"); hfg1->AddFrame(lb1, haha); TGNumberEntry* chIDEntry = new TGNumberEntry(hfg1, 0, 0, 0, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber); hfg1->AddFrame(chIDEntry, haha); chIDEntry->SetWidth(50); TGLabel * lbMode = new TGLabel(hfg1, "Mode"); hfg1->AddFrame(lbMode, haha); TGComboBox* cbMode = new TGComboBox(hfg1); hfg1->AddFrame(cbMode, haha); cbMode->AddEntry("Energy Hist", 0); cbMode->AddEntry("Ocs.", 1); cbMode->Select(1, false); cbMode->Resize(80, 20); } ///================= canvas widget fEcanvas = new TRootEmbeddedCanvas("Ecanvas",fMain,900,400); fMain->AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 10,10,10,10)); ///================= Log massage TGGroupFrame * groupLog = new TGGroupFrame(fMain, "Log Message", kHorizontalFrame); fMain->AddFrame(groupLog, new TGLayoutHints(kLHintsExpandX, 10,10,10,10) ); teLog = new TGTextEdit(groupLog, w, 100); groupLog->AddFrame(teLog, new TGLayoutHints(kLHintsExpandX, 2,2,10,0) ); /// Set a name to the main frame fMain->SetWindowName("FSU DAQ"); /// Map all subwindows of main frame fMain->MapSubwindows(); /// Initialize the layout algorithm fMain->Resize(fMain->GetDefaultSize()); fMain->SetWMPosition(200, 200); //does not work?? /// Map main frame fMain->MapWindow(); /// setup thread //saveDataThread = new TThread("hahaha", SaveData, (void *) 1); //fillHistThread = new TThread("kakaka", FillHistogram, (void *) 1); ///settingsSummary = NULL; boardSetting = NULL; channelSettingPHA = NULL; ///scalarPanel = NULL; LogMsg("Please \"Open Digitizers\" to start."); //HandleMenu(M_DIGITIZER_OPEN); //HandleMenu(M_BOARD_SETTINGS); //HandleMenu(M_CH_SETTING_PHA); //HandleMenu(M_CH_SETTING_PSD); gAnaTrace1 = NULL; gAnaTrace2 = NULL; gDigiTrace1 = NULL; gDigiTrace2 = NULL; } MainWindow::~MainWindow() { delete fMenuBar; delete fMenuFile; delete fMenuDigitizers; delete fMenuUtility; //delete boardIDEntry; //delete chEntry; //delete tePath; delete teLog; if( digi != NULL ) delete [] digi; delete boardSetting; delete channelSettingPHA; //delete settingsSummary; //delete scalarPanel; // //delete saveDataThread; //delete fillHistThread; delete gAnaTrace1; delete gAnaTrace2; delete gDigiTrace1; delete gDigiTrace2; /// Clean up used widgets: frames, buttons, layout hints fMain->Cleanup(); delete fMain; } void MainWindow::HandleMenu(Int_t id){ switch(id){ ///========================= Scan digitizers case M_DIGITIZER_OPEN:{ OpenDigitizers(); //fMenuDigitizers->EnableEntry( M_TRIGGER_SUMMARY); //fMenuDigitizers->EnableEntry( M_BOARD_SETTINGS); //fMenuDigitizers->EnableEntry( M_CH_SETTING); }break; ///========================= File Open case M_FILE_OPEN:{ }break; ///========================= Exit case M_EXIT: GoodBye(); break; ///========================= Channel setting summary case M_TRIGGER_SUMMARY: { }break; ///========================= Channel setting case M_CH_SETTING_PHA: channelSettingPHA = new ChannelSettingPHA(gClient->GetRoot(), 600, 600, digi, nDigi, 0); channelSettingPHA->Connect("LogMsg(char*)", "MainWindow", this, "LogMsg(char*)"); break; case M_CH_SETTING_PSD: channelSettingPSD = new ChannelSettingPSD(gClient->GetRoot(), 600, 600, digi, nDigi, 0); channelSettingPSD->Connect("LogMsg(char*)", "MainWindow", this, "LogMsg(char*)"); break; ///========================= Board setting case M_BOARD_SETTINGS:{ boardSetting = new BoardSetting(gClient->GetRoot(), 600, 600, digi, nDigi); boardSetting->Connect("LogMsg(char*)", "MainWindow", this, "LogMsg(char*)"); boardSetting->Connect("Haha(Int_t)", "MainWindow", this, "OpenChannelSetting(Int_t)"); }break; ///========================= Program setting case M_PROGRAM_SETTINGS:{ LogMsg("[Program settings] Not impelmented"); }break; ///====================== Show channel rate; case M_SHOW_CHANNELS_RATE:{ }break; ///====================== Fit Gaussian case M_FINDPEAKS:{ LogMsg("[Find Peaks] Not impelmented"); }break; } } void MainWindow::OpenDigitizers(){ LogMsg("============= detect digitizers"); vector DPPType; DPPType.clear(); portID.clear(); boardID.clear(); nDigi = 0; Digitizer * dig = new Digitizer(); LogMsg("Finding Digitizer for 4 ports and 3 boards for each port..."); for( int port = 0; port < 4 ; port ++){ for( int board = 0; board < 3 ; board ++){ dig->OpenDigitizer(board, port); if ( dig->GetConnectionStatus() ) { nDigi++; DPPType.push_back(dig->GetDPPType()); portID.push_back(port); boardID.push_back(board); serialNum.push_back(dig->GetSerialNumber()); dig->CloseDigitizer(); } } } LogMsg(Form("========== found %d digitizer(s)", nDigi)); for( int i = 0 ; i < nDigi ; i++){ LogMsg(Form("port: %d, board: %d, DPP Type : %d", portID[i], boardID[i], DPPType[i])); } if( nDigi > 0 ) { LogMsg(Form("============= Connect %d digitizer(s)...", nDigi)); digi = new Digitizer * [nDigi]; for( int i = 0; i < nDigi; i++){ printf("------------ %d \n", i); digi[i] = new Digitizer(boardID[i], portID[i], false, false); // TODO basic board program LogMsg(Form("%2d, Serial number : %3d opened (%s, %s)", i, digi[i]->GetSerialNumber(), digi[i]->GetDPPTypeString().c_str(), digi[i]->GetModelName().c_str())); digi[i]->OpenSettingBinary("setting_" + to_string(digi[i]->GetSerialNumber()) + ".bin"); } fMenuDigitizers->DisableEntry( M_DIGITIZER_OPEN); fMenuDigitizers->EnableEntry( M_LOAD_SETTINGS); fMenuDigitizers->EnableEntry( M_TRIGGER_SUMMARY); bOpenDigitizers->SetEnabled(false); } } Double_t standardPulse(Double_t *x, Double_t * par){ /// par[0] = start time /// par[1] = rise time /// par[2] = decay time /// par[3] = amplitude /// par[4] = baseline Double_t z = x[0] - par[0]; if( z <= 0 ) { return par[4]; }else{ return par[3]*(1-TMath::Exp(-1*z/par[1]))*TMath::Exp(-1*z/par[2]) + par[4]; } } void MainWindow::GoodBye(){ printf("----- bye bye ---- \n"); gApplication->Terminate(0); } void MainWindow::StartRun(){ LogMsg(Form("%s",__func__)); if( digi == NULL) return; digi[0]->StartACQ(); } void MainWindow::StopRun(){ LogMsg(Form("%s",__func__)); if( digi == NULL) return; } void MainWindow::OpenChannelSetting(Int_t boardID){ printf("#### %s \n", __func__); if( digi[boardID]->GetDPPType() == V1730_DPP_PHA_CODE ){ channelSettingPHA = new ChannelSettingPHA(gClient->GetRoot(), 600, 600, digi, nDigi, boardID); channelSettingPHA->Connect("LogMsg(char*)", "MainWindow", this, "LogMsg(char*)"); channelSettingPHA->Connect("SendPlotTraceCmd()", "MainWindow", this, "PlotTrace()"); } if( digi[boardID]->GetDPPType() == V1730_DPP_PSD_CODE ){ channelSettingPSD = new ChannelSettingPSD(gClient->GetRoot(), 600, 600, digi, nDigi, boardID); channelSettingPSD->Connect("LogMsg(char*)", "MainWindow", this, "LogMsg(char*)"); } } void MainWindow::LogMsg(char * msg){ time_t now = time(0); tm * ltm = localtime(&now); int year = 1900 + ltm->tm_year; int month = 1 + ltm->tm_mon; int day = ltm->tm_mday; int hour = ltm->tm_hour; int minute = ltm->tm_min; int secound = ltm->tm_sec; TString outMsg = Form("[%4d-%02d-%02d %02d:%02d:%02d] %s", year, month, day, hour, minute, secound, msg); teLog->AddLine(outMsg); printf("%s\n", outMsg.Data()); teLog->LineDown(); teLog->ShowBottom(); } void MainWindow::PlotTrace(){ printf("=== %s\n", __func__); Data * data = digi[0]->GetData(); data->AllocateMemory(); data->DPPType = digi[0]->GetDPPType(); int ch2ns = (int) digi[0]->GetCh2ns(); digi[0]->StartACQ(); int count = 0; while(count < 10){ //sleep(1); usleep(500*1000); /// wait half sec digi[0]->ReadData(); if( data->nByte > 0 ){ data->DecodeBuffer(1); data->PrintStat(); delete gAnaTrace1; gAnaTrace1 = new TGraph(); delete gDigiTrace1; gDigiTrace1 = new TGraph(); int traceLength = (data->Waveform1[0][0]).size(); printf("0----------%d \n", traceLength); if( traceLength == 0 ) { LogMsg((char *)"no trace"); }else{ for( int i = 0; i < traceLength ; i++) { //printf("%d, ", (data->Waveform1[0][0])[i]); gAnaTrace1->SetPoint(i, i*ch2ns, (data->Waveform1[0][0])[i]); gDigiTrace1->SetPoint(i, i*ch2ns, 2000*(data->DigiWaveform1[0][0])[i] + 2000); } } data->ClearData(); fEcanvas->GetCanvas()->cd(); gAnaTrace1->Draw("APL"); gDigiTrace1->Draw("L"); fEcanvas->GetCanvas()->Update(); break; } count++; }; digi[0]->StopACQ(); if( count == 10 ) LogMsg("Plot Trace TimeOut, please check setting"); } //############################################ int main(int argc, char **argv) { printf(" Welcome to FSU DQ \n"); TApplication theApp("App",&argc,argv); new MainWindow(gClient->GetRoot(),800,800); theApp.Run(); return 0; }