#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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_REGISTER_SETTING, M_BOARD_SETTINGS, M_PROGRAM_SETTINGS, M_FINDPEAKS, M_SHOW_CHANNELS_RATE }; enum ModeIdentifiers{ Mode_EnergyHist, Mode_CountHist, Mode_Oscilloscope, Mode_DataRun }; long get_time(){ long time_ms; struct timeval t1; struct timezone tz; gettimeofday(&t1, &tz); time_ms = (t1.tv_sec) * 1000 + t1.tv_usec / 1000; return time_ms; } ///make static members Digitizer ** MainWindow::digi = NULL; TGTextEdit * MainWindow::teLog = NULL; TRootEmbeddedCanvas * MainWindow::fEcanvas = NULL; TGNumberEntry * MainWindow::boardIDEntry = NULL; TGNumberEntry * MainWindow::chIDEntry = NULL; TGComboBox* MainWindow::cbMode = NULL; TGTextEntry * MainWindow::dataPrefix = NULL; TGNumberEntry * MainWindow::runIDEntry = NULL; BoardSetting * MainWindow::boardSetting = NULL; TH1F * MainWindow::hEnergy[MaxNBoards][MaxNChannels] = {NULL}; TH1F * MainWindow::hChannel[MaxNBoards] = {NULL}; TGraph * MainWindow::gAnaTrace1 = NULL ; TGraph * MainWindow::gAnaTrace2 = NULL ; TGraph * MainWindow::gDigiTrace1 = NULL ; TGraph * MainWindow::gDigiTrace2 = 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->AddEntry("&Register Setting", M_REGISTER_SETTING); //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_REGISTER_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, "Run Control", kHorizontalFrame); hframe->AddFrame(group0 ); TGVerticalFrame * vframe = new TGVerticalFrame(group0); group0->AddFrame(vframe); TGHorizontalFrame *hfg0 = new TGHorizontalFrame(vframe); vframe->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()"); bStartRun = new TGTextButton(hfg0,"Start Run"); hfg0->AddFrame(bStartRun, uniLayoutHints); bStartRun->Connect("Clicked()", "MainWindow", this, "StartRun()"); bStartRun->SetEnabled(false); bStopRun = new TGTextButton(hfg0,"Stop Run"); hfg0->AddFrame(bStopRun, uniLayoutHints); bStopRun->Connect("Clicked()", "MainWindow", this, "StopRun()"); bStopRun->SetEnabled(false); TGLabel * lbMode = new TGLabel(hfg0, "Mode"); hfg0->AddFrame(lbMode, uniLayoutHints); cbMode = new TGComboBox(hfg0); hfg0->AddFrame(cbMode, uniLayoutHints); cbMode->AddEntry("Energy Hist.", Mode_EnergyHist); cbMode->AddEntry("Count Hist.", Mode_CountHist); cbMode->AddEntry("Ocsilloscope.", Mode_Oscilloscope); cbMode->AddEntry("Data Run", Mode_DataRun); cbMode->Select(1, false); cbMode->Resize(80, 20); TGHorizontalFrame *hfg1 = new TGHorizontalFrame(vframe); vframe->AddFrame(hfg1 ,new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0)); TGLabel * lbDataPath = new TGLabel(hfg1, "Save Data Prefix"); hfg1->AddFrame(lbDataPath, uniLayoutHints); dataPrefix = new TGTextEntry(hfg1, "ExpName"); hfg1->AddFrame(dataPrefix,uniLayoutHints); dataPrefix->Resize(100, 20); TGLabel * lbRunNum = new TGLabel(hfg1, "Run"); hfg1->AddFrame(lbRunNum, uniLayoutHints); runIDEntry = new TGNumberEntry(hfg1, 0, 0, 0, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); hfg1->AddFrame(runIDEntry, uniLayoutHints); runIDEntry->SetWidth(50); } {///================= single Channel group TGGroupFrame * group1 = new TGGroupFrame(hframe, "Single Channel", kHorizontalFrame); hframe->AddFrame(group1, new TGLayoutHints(kLHintsExpandY)); 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); boardIDEntry = new TGNumberEntry(hfg1, 0, 0, 0, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); hfg1->AddFrame(boardIDEntry, haha); boardIDEntry->SetWidth(50); boardIDEntry->SetState(false); boardIDEntry->Connect("Modified()", "MainWindow", this, "ChangeBoard()"); TGLabel * lb1 = new TGLabel(hfg1, "Channel"); hfg1->AddFrame(lb1, haha); chIDEntry = new TGNumberEntry(hfg1, 0, 0, 0, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber); hfg1->AddFrame(chIDEntry, haha); chIDEntry->SetWidth(50); chIDEntry->SetState(false); bPlotSingleTrace = new TGTextButton(hfg1,"Plot Trace"); hfg1->AddFrame(bPlotSingleTrace, haha); bPlotSingleTrace->Connect("Clicked()", "MainWindow", this, "PlotSingleTrace()"); bPlotSingleTrace->SetEnabled(false); bFitTrace = new TGTextButton(hfg1,"Fit Trace"); hfg1->AddFrame(bFitTrace, haha); bFitTrace->Connect("Clicked()", "MainWindow", this, "FitTrace()"); bFitTrace->SetEnabled(false); } {///================= 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); boardSetting = NULL; channelSettingPHA = NULL; registerSetting = NULL; ///scalarPanel = NULL; LogMsg((char*)"Please \"Open Digitizers\" to start."); HandleMenu(M_DIGITIZER_OPEN); HandleMenu(M_BOARD_SETTINGS); //HandleMenu(M_CH_SETTING_PHA); //HandleMenu(M_CH_SETTING_PSD); //HandleMenu(M_REGISTER_SETTING); //HandleMenu(M_TRIGGER_SUMMARY); gAnaTrace1 = new TGraph(); gAnaTrace2 = new TGraph(); gDigiTrace1 = new TGraph(); gDigiTrace2 = new TGraph(); gStyle->SetOptStat("neiou"); } MainWindow::~MainWindow() { delete fMenuBar; delete fMenuFile; delete fMenuDigitizers; delete fMenuUtility; delete boardIDEntry; delete chIDEntry; delete teLog; //delete tePath; delete bOpenDigitizers; delete bStartRun; delete bStopRun; delete cbMode; delete bPlotSingleTrace; delete bFitTrace; delete [] digi; delete boardSetting; delete channelSettingPHA; delete channelSettingPSD; delete registerSetting; delete triggerSummary; delete fillHistThread; delete gAnaTrace1; delete gAnaTrace2; delete gDigiTrace1; delete gDigiTrace2; for( int i = 0; i < MaxNBoards; i++){ delete hChannel[i]; for( int j = 0; j < MaxNChannels; j++) delete hEnergy[i][j]; } /// 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_BOARD_SETTINGS); //fMenuDigitizers->EnableEntry( M_CH_SETTING); }break; ///========================= File Open case M_FILE_OPEN:{ }break; ///========================= Exit case M_EXIT: GoodBye(); break; ///========================= Trigger summary case M_TRIGGER_SUMMARY: { triggerSummary = new TriggerSummary(gClient->GetRoot(), 600, 600, digi, nDigi); }break; case M_LOAD_SETTINGS:{ LoadSettingFromFile(); }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*)"); channelSettingPHA->Connect("SendPlotTraceCmd()", "MainWindow", this, "PlotSingleTrace()"); break; case M_CH_SETTING_PSD: channelSettingPSD = new ChannelSettingPSD(gClient->GetRoot(), 600, 600, digi, nDigi, 0); channelSettingPSD->Connect("LogMsg(char*)", "MainWindow", this, "LogMsg(char*)"); //channelSettingPSD->Connect("SendPlotTraceCmd()", "MainWindow", this, "PlotSingleTrace()"); 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; ///========================= Setting Summary case M_REGISTER_SETTING:{ registerSetting = new RegisterSetting(gClient->GetRoot(), 600, 600, digi, nDigi, Register::DPP::RecordLength_G); ///registerSetting->Connect("SendChangeSignal()", "ChannelSettingPHA", this, "ChangeCh()"); ///registerSetting->Connect("SendChangeSignal()", "ChannelSettingPSD", this, "ChangeCh()"); }break; ///========================= Program setting case M_PROGRAM_SETTINGS:{ LogMsg((char*)"[Program settings] Not impelmented"); }break; ///====================== Show channel rate; case M_SHOW_CHANNELS_RATE:{ }break; ///====================== Fit Gaussian case M_FINDPEAKS:{ LogMsg((char*)"[Find Gaussian Peaks] Not impelmented"); }break; } } void MainWindow::OpenDigitizers(){ /// if dig exist, say, from loading setting file without digitizer for( int i = 0 ; i < nDigi; i++ ) delete digi[i]; LogMsg((char*)"============= detect digitizers"); vector DPPType; DPPType.clear(); portID.clear(); boardID.clear(); nDigi = 0; Digitizer * dig = new Digitizer(); LogMsg((char*)"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(); } } } delete dig; 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); 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); fMenuDigitizers->EnableEntry( M_REGISTER_SETTING); bOpenDigitizers->SetEnabled(false); bStartRun->SetEnabled(true); if( nDigi > 1) boardIDEntry->SetState(true); chIDEntry->SetState(true); boardIDEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, nDigi-1); boardIDEntry->SetNumber(0, false); chIDEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, digi[0]->GetNChannel() -1 ); bPlotSingleTrace->SetEnabled(true); bFitTrace->SetEnabled(true); for( int i = 0; i < nDigi; i++){ hChannel[i] = new TH1F(Form("hBd%02d", i),Form("hBd%02d; ch; count", i), digi[i]->GetNChannel(), 0, digi[i]->GetNChannel()); for( int j = 0; j < MaxNChannels; j++) hEnergy[i][j] = new TH1F(Form("hE%02dch%02d", i, j),Form("hE bd-%02d ch-%02d; Energy[ch]; count", i, j), 400, 0, 20000); } } } void MainWindow::LoadSettingFromFile(){ const char *filetypes[] = { "Setting File", "*.bin", "ROOT files", "*.root", "ROOT macros", "*.C", "Text files", "*.[tT][xX][tT]", 0, 0 }; static TString dir("."); TGFileInfo fi; fi.fFileTypes = filetypes; fi.SetIniDir(dir); printf("fIniDir = %s\n", fi.fIniDir); new TGFileDialog(gClient->GetRoot(), fMain, kFDOpen, &fi); printf("Open file: %s (dir: %s)\n", fi.fFilename, fi.fIniDir); dir = fi.fIniDir; /// if no digitize open if( digi == NULL ) { }else{ } } void MainWindow::ChangeBoard(){ int boardID = boardIDEntry->GetNumber(); chIDEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, digi[boardID]->GetNChannel() -1 ); } void MainWindow::GoodBye(){ for( int i = 0; i < nDigi; i++) digi[i]->CloseDigitizer(); printf("----- bye bye ---- \n"); gApplication->Terminate(0); } void MainWindow::StartRun(){ LogMsg(Form("%s",__func__)); if( digi == NULL) return; for( int bd = 0; bd < nDigi; bd++){ hChannel[bd]->Reset(); for( int ch = 0; ch < MaxNChannels; ch++){ hEnergy[bd][ch]->Reset(); } } bStartRun->SetEnabled(false); bStopRun->SetEnabled(true); dataPrefix->SetEnabled(false); runIDEntry->SetState(false); bPlotSingleTrace->SetEnabled(false); bFitTrace->SetEnabled(false); if( cbMode->GetSelected() == Mode_DataRun ) cbMode->SetEnabled(false); bool threadFlag = false; for( int i = 0 ; i < nDigi; i++) { digi[i]->StartACQ(); if( digi[i]->IsRunning() ) threadFlag = true; } if( threadFlag ) fillHistThread->Run(); if( boardSetting != NULL ) boardSetting->ReadStatus(); } void MainWindow::StopRun(){ LogMsg(Form("%s",__func__)); if( digi == NULL) return; for( int i = 0; i < nDigi; i++){ digi[i]->StopACQ(); //Save last bit of buffer ///===== clear data; digi[i]->GetData()->ClearTriggerRate(); } bStartRun->SetEnabled(true); bStopRun->SetEnabled(false); dataPrefix->SetEnabled(true); runIDEntry->SetState(true); bPlotSingleTrace->SetEnabled(true); bFitTrace->SetEnabled(true); cbMode->SetEnabled(true); if( cbMode->GetSelected() == Mode_DataRun ){ int runID = runIDEntry->GetNumber(); runIDEntry->SetNumber(runID +1); } } void MainWindow::OpenChannelSetting(Int_t boardID){ if( digi == NULL ) return; 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, "PlotSingleTrace()"); } 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*)"); //channelSettingPSD->Connect("SendPlotTraceCmd()", "MainWindow", this, "PlotSingleTrace()"); } } 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::PlotSingleTrace(){ printf("=== %s\n", __func__); if( digi == NULL ) return; int boardID = boardIDEntry->GetNumber(); int chID = chIDEntry->GetNumber(); Data * data = digi[boardID]->GetData(); data->AllocateMemory(); int ch2ns = (int) digi[boardID]->GetCh2ns(); digi[boardID]->StartACQ(); int count = 0; while(count < 10){ usleep(100*1000); /// wait half sec digi[boardID]->ReadData(); if( data->nByte > 0 ){ data->DecodeBuffer(0); data->PrintStat(); gDigiTrace1->SetLineColor(4); int traceLength = (data->Waveform1[chID][0]).size(); printf("0----------%d \n", traceLength); if( traceLength == 0 ) { LogMsg((char *)"no trace"); bFitTrace->SetEnabled(false); }else{ for( int i = 0; i < traceLength ; i++) { gAnaTrace1->SetPoint(i, i*ch2ns, (data->Waveform1[chID][0])[i]); } if( traceLength <= gAnaTrace1->GetN() ){ for( int i = gAnaTrace1->GetN() -1 ; i >= traceLength ; i--){ gAnaTrace1->RemovePoint(i); gDigiTrace1->RemovePoint(i); } } double xmin, xmax, ymin, ymax; gAnaTrace1->ComputeRange(xmin, ymin, xmax, ymax); for( int i = 0; i < traceLength ; i++) { gDigiTrace1->SetPoint(i, i*ch2ns, (ymax-ymin)*(data->DigiWaveform1[chID][0])[i] + ymin); } } data->ClearData(); fEcanvas->GetCanvas()->cd(); gAnaTrace1->Draw("APL"); gDigiTrace1->Draw("L"); fEcanvas->GetCanvas()->Update(); break; bFitTrace->SetEnabled(true); } count++; }; digi[0]->StopACQ(); if( count == 10 ) LogMsg((char*)"Plot Trace TimeOut, please check setting"); } Double_t traceFunc(Double_t *x, Double_t *par){ ///par[0] = baseline ///par[1] = start time ///par[2] = rise time ///par[3] = Amp ///par[4] = decay time Double_t result = par[0]; if(x[0] > par[1]){ Double_t y = x[0]-par[1]; result += par[3] *(1 - TMath::Exp( - y / par[2])) * TMath::Exp(-y / par[4]); } return result; } void MainWindow::FitTrace(){ printf("=== %s not impletement.\n", __func__); if( gAnaTrace1->GetN() == 0 ) return; double xmin, xmax, ymin, ymax; gAnaTrace1->ComputeRange(xmin, ymin, xmax, ymax); TF1 * f1 = new TF1("f1", traceFunc, xmin, xmax, 5); f1->SetLineWidth(3); f1->SetLineColor(1); f1->SetNpx(1000); f1->SetParameter(0, ymin); f1->SetParameter(1, 1000); //TODO get from digi[Board]->PreTrigger * 4 * ch2ns f1->SetParameter(2, 20); f1->SetParameter(3, ymax-ymin); f1->SetParameter(4, 50000); gAnaTrace1->Fit("f1", "R"); fEcanvas->GetCanvas()->Update(); gSystem->ProcessEvents(); const Double_t* paraE = f1->GetParErrors(); const Double_t* paraA = f1->GetParameters(); LogMsg((char*)"---------- Fit result"); } //TODO use the ptr to tell which board, and each digitizer has an indivual thread for savign data and filling hists. void * MainWindow::FillHistogram(void * ptr){ printf("=== %s\n", __func__); if( digi == NULL ) return 0; int boardID = boardIDEntry->GetNumber(); int ch = 0; int ch2ns = 4; int traceLength = 0; uint32_t PreviousTime = get_time(); uint32_t CurrentTime = 0; uint32_t ElapsedTime = 0; TString dataFileName = dataPrefix->GetText(); dataFileName += Form("_run%03d_%03d", (int) runIDEntry->GetNumber(), (int) digi[boardID]->GetSerialNumber()); printf("|%s|\n", dataFileName.Data()); Data * data = digi[boardID]->GetData(); data->AllocateMemory(); while(digi[boardID]->IsRunning()){ usleep(100*1000); /// wait 100 msec digi[boardID]->ReadData(); if( boardSetting != NULL ) boardSetting->ReadStatus(); ch2ns = (int) digi[boardID]->GetCh2ns(); ch = chIDEntry->GetNumber(); if( data->nByte > 0 ){ //data->PrintStat(); if( cbMode->GetSelected() == Mode_DataRun ){ // Rate graph? data->SaveBuffer(dataFileName.Data()); }else{ data->DecodeBuffer(0); fEcanvas->GetCanvas()->cd(); ///Fill trace if( cbMode->GetSelected() == Mode_Oscilloscope){ unsigned short nData = data->NumEvents[ch]; traceLength = (data->Waveform1[ch][nData-1]).size(); if( traceLength > 0 ){ for( int i = 0; i < traceLength; i++) { gAnaTrace1->SetPoint(i, i*ch2ns, (data->Waveform1[ch][nData-1])[i]); } if( traceLength <= gAnaTrace1->GetN() ){ for( int i = gAnaTrace1->GetN() -1 ; i >= traceLength ; i--){ gAnaTrace1->RemovePoint(i); } } gAnaTrace1->Draw("APL"); } } } } CurrentTime = get_time(); ElapsedTime = CurrentTime - PreviousTime; /// milliseconds if( ElapsedTime > 500 ){ ///Fill Channel Count for( int i = 0 ; i < digi[boardID]->GetNChannel(); i++){ for( int j = 0; j < data->NumEvents[i]; j++) hChannel[boardID]->Fill(i); } ///Fill Energy histogram //for( int ch = 0; ch < digi[boardID]->GetNChannel(); ch++){ for( int i = 0; i < data->NumEvents[ch]; i++){ hEnergy[boardID][ch]->Fill( data->Energy[ch][i]); } //} if( cbMode->GetSelected() == Mode_EnergyHist ) hEnergy[boardID][ch]->Draw("hist"); if( cbMode->GetSelected() == Mode_CountHist ) hChannel[boardID]->Draw("hist"); data->ClearData(); PreviousTime = CurrentTime; } fEcanvas->GetCanvas()->Update(); gSystem->ProcessEvents(); } return ptr; } //############################################ 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; }