#include #include #include #include #include #include #include #include #include "EXOEventDisplayGui.hh" #include "EXOUtilities/EXOErrorLogger.hh" #include "EXOUtilities/EXOTalkToManager.hh" #include "EXOUtilities/EXOEventData.hh" #include "EXOAnalysisManager/EXOAnalysisManager.hh" #include "EXOAnalysisManager/EXOAnalysisModule.hh" #include "EXOAnalysisManager/EXOBinaryFileInputModule.hh" #include "EXOAnalysisManager/EXOTreeInputModule.hh" #ifndef NOG4 #include "EXOAnalysisManager/EXOGeant4Module.hh" #endif #include "EXOAnalysisManager/EXOExampleModule.hh" #include "EXOAnalysisManager/EXOReconstructionModule.hh" #include "EXOAnalysisManager/EXOTreeOutputModule.hh" #include "EXOAnalysisManager/EXOBinaryFileOutputModule.hh" #include "EXOAnalysisManager/EXOEventDumpModule.hh" #include "EXOAnalysisManager/EXODataTrimModule.hh" #include using namespace std; // I'm declaring this stuff as global variables here, because // the geant4 stuff screws up the generation of the dictionary file // when it's located in the header file. EXOErrorLogger *errorLogger; EXOTalkToManager *talktoManager; EXOAnalysisManager *analysisManager; EXOEventData *eventData; EXOTreeInputModule *treeinputModule; EXOBinaryFileInputModule *binaryinputModule; #ifndef NOG4 EXOGeant4Module *geant4Module; #endif EXOExampleModule *exampleModule; EXOTreeOutputModule *treeoutputModule; EXOBinaryFileOutputModule *binaryoutputModule; EXOReconstructionModule *recModule; EXOEventDumpModule *eventdumpModule; EXODataTrimModule *datatrimModule; EXOInputModule *inputModule; EXOEventDisplayGui::EXOEventDisplayGui(const TGWindow *p,UInt_t w,UInt_t h, char *FILENAME) { filename = FILENAME; plotstyle = 1; linear_or_log = 1; // This stuff is copied from EXOAnalysis.cc // Create Error logger errorLogger = new EXOErrorLogger(); // Create Talk-To Manager talktoManager = new EXOTalkToManager(errorLogger); // if ( argc == 2 ) { // talktoManager->set_filename( "edcommand.exo" ); talktoManager->set_interactive( false ); // int result = 0; // result = talktoManager->OpenCommandFile(); // if ( result < 0 ) return; // } // else { // talktoManager->set_interactive( true ); // } // Get memory for event data eventData = new EXOEventData; // Create analysis manager analysisManager = new EXOAnalysisManager(errorLogger, talktoManager, eventData); analysisManager->set_verbose(false); // Create modules treeinputModule = new EXOTreeInputModule( "EXOTreeInputModule", analysisManager, errorLogger, talktoManager, eventData ); binaryinputModule = new EXOBinaryFileInputModule( "EXOBinaryFileInputModule", analysisManager, errorLogger, talktoManager, eventData ); #ifndef NOG4 geant4Module = new EXOGeant4Module( "EXOGeant4Module", analysisManager, errorLogger, talktoManager, eventData ); #endif exampleModule = new EXOExampleModule( "EXOExampleModule", analysisManager, errorLogger, talktoManager, eventData ); treeoutputModule = new EXOTreeOutputModule("EXOTreeOutputModule",analysisManager, errorLogger, talktoManager, eventData ); binaryoutputModule = new EXOBinaryFileOutputModule("EXOBinaryFileOutputModule",analysisManager, errorLogger, talktoManager, eventData ); recModule = new EXOReconstructionModule("EXOReconstructionModule",analysisManager, errorLogger, talktoManager, eventData ); eventdumpModule = new EXOEventDumpModule("EXOEventDumpModule",analysisManager, errorLogger, talktoManager, eventData ); datatrimModule = new EXODataTrimModule("EXODataTrimModule",analysisManager, errorLogger, talktoManager, eventData ); // register modules with analysisManager analysisManager->RegisterModule(treeinputModule,false,"tinput"); analysisManager->RegisterModule(binaryinputModule,false,"binput"); #ifndef NOG4 analysisManager->RegisterModule(geant4Module,false,"exosim"); #endif analysisManager->RegisterModule(exampleModule,false,"example"); analysisManager->RegisterModule(recModule,false,"rec"); analysisManager->RegisterModule(treeoutputModule,false,"toutput"); analysisManager->RegisterModule(binaryoutputModule,false,"boutput"); analysisManager->RegisterModule(eventdumpModule,false,"eventdump"); analysisManager->RegisterModule(datatrimModule,false,"trim"); // Show registered modules // analysisManager->ShowRegisteredModules(); // Create Talk-To commands. For now all we do is use the input module // and set the filename. int result = 0; result = analysisManager->CallTalkTos(); // cout << "proceeding to create main frame" << endl; // Create a main frame fMain = new TGMainFrame(p,w,h); ULong_t red; gClient->GetColorByName("red",red); //create frame widget for page buttons and canvas fTopFrame = new TGHorizontalFrame(fMain,800,200); //create frame widget for control buttons fBottomFrame = new TGHorizontalFrame(fMain,1200,200); fMain->AddFrame(fTopFrame, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,2,2)); fMain->AddFrame(fBottomFrame, new TGLayoutHints(kLHintsExpandX,2,2,2,2)); //need to fix the location on the gui exo_refresh = new TGPictureButton(fBottomFrame,"exologo_small.jpg"); exo_refresh->SetToolTipText("Refresh"); exo_refresh->Connect("Clicked()","EXOEventDisplayGui",this,"DoDraw()"); //this command is also temporary - needs to work with page layout fBottomFrame->AddFrame(exo_refresh, new TGLayoutHints(kLHintsLeft,35,2,2,2)); // Create a horizontal frame widget with buttons hframe = new TGHorizontalFrame(fBottomFrame,1200,40); fBottomFrame->AddFrame(hframe,new TGLayoutHints(kLHintsExpandX,50,2,2,2)); // //need to fix the location on the gui // exo_refresh = new TGPictureButton(fBottomFrame,"exologo_small.jpg"); // exo_refresh->SetToolTipText("Refresh"); // exo_refresh->Connect("Clicked()","EXOEventDisplayGui",this,"DoDraw()"); //this command is also temporary - needs to work with page layout // fBottomFrame->AddFrame(exo_refresh, new TGLayoutHints(kLHintsLeft,2,2,2,2)); // TGTextButton *draw = new TGTextButton(hframe, "&Draw"); // draw->Connect("Clicked()","EXOEventDisplayGui",this,"DoDraw()"); // hframe->AddFrame(draw, new TGLayoutHints(kLHintsCenterX,5,5,1,1)); //Create a vertical frame widget for all event info number entry fields requestframe = new TGVerticalFrame(hframe,210,210); hframe->AddFrame(requestframe, new TGLayoutHints(kLHintsLeft,2,2,2,2)); //Create number entry field for requested entry with up // and down arrows to navigate to next and previous events entryframe = new TGHorizontalFrame(requestframe,210,70); requestframe->AddFrame(entryframe,new TGLayoutHints(kLHintsLeft,2,2,2,2)); TGLabel *fentrynumlabel = new TGLabel(entryframe, "Entry #"); entryframe->AddFrame(fentrynumlabel, new TGLayoutHints(kLHintsCenterX|kLHintsCenterY,2,2,2,2)); fRequestEntry = new TGNumberEntry(entryframe); fRequestEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0,100000); fRequestEntry->SetFormat(TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); fRequestEntry->SetWidth(72); fRequestEntry->Connect("ValueSet(Long_t)","EXOEventDisplayGui",this,"EntryUpdate()" ); entryframe->AddFrame(fRequestEntry, new TGLayoutHints(kLHintsCenterX,2,2,2,2)); TGLabel *fline = new TGLabel(requestframe,"----------------------------------------------------"); requestframe->AddFrame(fline, new TGLayoutHints(kLHintsLeft,1,1,1,1)); //Create a horizontal frame widget for number entry fields for requested run and event numbers evinfoframe = new TGHorizontalFrame(requestframe,200,70); requestframe->AddFrame(evinfoframe, new TGLayoutHints(kLHintsLeft,2,2,2,2)); //Create number entry field for requested run number TGLabel *frunnumlabel = new TGLabel(evinfoframe, "Run #"); evinfoframe->AddFrame(frunnumlabel, new TGLayoutHints(kLHintsCenterX|kLHintsCenterY,8,2,2,2)); fRequestRun = new TGNumberEntryField(evinfoframe); fRequestRun->SetLimits(TGNumberFormat::kNELLimitMinMax, 0,100000); fRequestRun->SetFormat(TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); fRequestRun->SetWidth(60); // fRequestRun->Connect("ValueSet(Long_t)","EXOEventDisplayGui",this,"EventUpdate()" ); evinfoframe->AddFrame(fRequestRun, new TGLayoutHints(kLHintsCenterX,2,2,2,2)); //Create number entry field for requested event number TGLabel *fevnumlabel = new TGLabel(evinfoframe, "Event #"); evinfoframe->AddFrame(fevnumlabel, new TGLayoutHints(kLHintsCenterX|kLHintsCenterY,2,2,2,2)); fRequestEvent = new TGNumberEntryField(evinfoframe); fRequestEvent->SetLimits(TGNumberFormat::kNELLimitMinMax, 0,100000); fRequestEvent->SetFormat(TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); fRequestEvent->SetWidth(60); // fRequestEvent->Connect("ValueSet(Long_t)","EXOEventDisplayGui",this,"EventUpdate()" ); evinfoframe->AddFrame(fRequestEvent, new TGLayoutHints(kLHintsCenterX,2,2,2,2)); TGTextButton *RequestEvent = new TGTextButton(evinfoframe, " &Go "); RequestEvent->Connect("Clicked()","EXOEventDisplayGui",this,"EventUpdate()"); evinfoframe->AddFrame(RequestEvent, new TGLayoutHints(kLHintsCenterX,2,2,2,2)); TGLabel *fline2 = new TGLabel(requestframe,"----------------------------------------------------"); requestframe->AddFrame(fline2, new TGLayoutHints(kLHintsLeft,1,1,1,1)); // Create filename text entry field fileframe = new TGHorizontalFrame(requestframe,210,70); requestframe->AddFrame(fileframe, new TGLayoutHints(kLHintsLeft,2,2,2,2)); TGLabel *ffilenamelabel = new TGLabel(fileframe, "Input File:"); fileframe->AddFrame(ffilenamelabel, new TGLayoutHints(kLHintsCenterX|kLHintsCenterY,2,2,2,2)); fRequestFilename = new TGTextEntry(fileframe, new TGTextBuffer(100)); fRequestFilename->SetToolTipText("Enter filename"); fRequestFilename->Resize(300,fRequestFilename->GetDefaultHeight() ); fileframe->AddFrame(fRequestFilename, new TGLayoutHints(kLHintsCenterX,2,2,2,2)); TGTextButton *RequestFileButton = new TGTextButton(fileframe, " &Open "); RequestFileButton->Connect("Clicked()","EXOEventDisplayGui",this,"GetDataSource()"); fileframe->AddFrame(RequestFileButton, new TGLayoutHints(kLHintsRight,2,2,2,2)); // Create exit button TGTextButton *exit = new TGTextButton(hframe," &Exit ", "gApplication->Terminate(0)"); exit->SetBackgroundColor(red); hframe->AddFrame(exit, new TGLayoutHints(kLHintsCenterY|kLHintsRight,2,2,2,2)); // Create canvas widget fEcanvas = new TRootEmbeddedCanvas("Ecanvas",fTopFrame,600,600); fTopFrame->AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandY|kLHintsExpandX,200,2,2,2)); //Create a group of radio buttons in a vertical frame radiobg = new TGVButtonGroup(fTopFrame,"Plot Style"); //cout << "Right before TGRadioButtonPointers" << endl; fpage[0] = new TGRadioButton(radiobg, new TGHotString("Color")); //cout << "In between TGRadioButtonPointers" << endl; fpage[1] = new TGRadioButton(radiobg, new TGHotString("Greyscale")); //cout << "Right after TGRadioButtonPointers" << endl << endl; fpage[0]->SetState(kButtonDown); //Need to draw raw signals vs time radiobg->Connect("Clicked(Int_t)","EXOEventDisplayGui",this,"PushedPlotStyleButton(Int_t)"); radiobg->Show(); //draw first entry of file when display is launched if ( filename != NULL ) GetDataSource(); // TGRadioButton *pagexy = new TGRadioButton(vframe, new TGHotString("xy TPC view")); // TGRadioButton *pageyz = new TGRadioButton(vframe, new TGHotString("yz TPC view")); // vframe->AddFrame(pagexy, new TGLayoutHints(kLHintsCenterX,5,5,3,4)); // vframe->AddFrame(pageyz, new TGLayoutHints(kLHintsCenterX,5,5,3,4)); // fMain->AddFrame(vframe, new TGLayoutHints(kLHintsCenterY,2,2,2,2)); // Set a name to the main frame fMain->SetWindowName("EXO Event Display"); // Map all subwindows of main frame // cout << "Right Before MapSubwindows" <MapSubwindows(); // cout << "Right After MapSubwindows" << endl; // Initialize the layout algorithm fMain->Resize(fMain->GetDefaultSize()); // Map main frame fMain->MapWindow(); } void EXOEventDisplayGui::PushedPlotStyleButton( Int_t button_id) { // cout << "Pushed radio button number " << button_id << endl; plotstyle = button_id; DoDraw(); } void EXOEventDisplayGui::PushedPlotTypeButton( Int_t button_id) { cout << "Pushed plot type button number " << button_id << endl; linear_or_log = button_id; DoDraw(); } void EXOEventDisplayGui::DoDraw() { // Fill the signal histograms FillSignalHistograms(); // Get the pointers to the histrograms TH2F *h1000 = (TH2F*)gROOT->FindObject("h1000"); if ( h1000 == NULL ) { cout << "Error: can't find signal histogram h1000" << endl; return; } TH2F *h1100 = (TH2F*)gROOT->FindObject("h1100"); if ( h1100 == NULL ) { cout << "Error: can't find signal histogram h1100" << endl; return; } TH2F *h2000 = (TH2F*)gROOT->FindObject("h2000"); if ( h2000 == NULL ) { cout << "Error: can't find signal histogram h2000" << endl; return; } TH2F *h2100 = (TH2F*)gROOT->FindObject("h2100"); if ( h2100 == NULL ) { cout << "Error: can't find signal histogram h2100" << endl; return; } // Draws raw wire and apd signals in grayscale or color //need to add option to choose between color and grayscale // option 8 = grayscale // option 1 = color // gStyle->SetPalette(1,0); if ( plotstyle == 1 ) { gStyle->SetPalette(1); // color } else if ( plotstyle == 2 ) { gStyle->SetPalette(9); // greyscale } else { cout << "plotstyle not recognized" << endl; gStyle->SetPalette(1); } // Don't print statistics on the plot gStyle->SetOptStat(0000000); TCanvas *fCanvas = fEcanvas->GetCanvas(); fCanvas->Clear(); fCanvas->Divide(1,2); fCanvas->cd(2); h1000->DrawCopy("colz"); fCanvas->cd(1); h1100->DrawCopy("colz"); fCanvas->cd(); fCanvas->Update(); } void EXOEventDisplayGui::FillSignalHistograms() { //to be changed later to be robust using the analysis code (probably) //are these constants are defined in the reconstruction code EXODimensions.h? Int_t nsignal = eventData->nsig; //226, 228 including APD sums Int_t nsamp = eventData->nsample; Int_t nchannel_per_wireplane = 38; Int_t nwireplane = 4; Int_t nwires = nchannel_per_wireplane*nwireplane; Int_t napds = nsignal-nwires; TH2F *htest1 = (TH2F*)gROOT->FindObject("h1000"); if ( htest1 ) { delete htest1; } TH2F *htest11 = (TH2F*)gROOT->FindObject("h1100"); if ( htest11 ) { delete htest11; } TH2F *htest2 = (TH2F*)gROOT->FindObject("h2000"); if ( htest2 ) { delete htest2; } TH2F *htest22 = (TH2F*)gROOT->FindObject("h2100"); if ( htest22 ) { delete htest22; } TH2F *h1000 = new TH2F("h1000","", nsamp, 0, nsamp, nwires, 0, nwires); TH2F *h1100 = new TH2F("h1100","", nsamp, 0, nsamp-1, napds, nwires, nsignal); TH2F *h2000 = new TH2F("h2000","", nsamp, 0, nsamp, nwires, 0, nwires); TH2F *h2100 = new TH2F("h2100","", nsamp, 0, nsamp-1, napds, nwires, nsignal); h1000->SetTitle("Base subtracted wire signals vs time"); h1000->GetXaxis()->SetTitle("Time (#mus)"); h1000->GetYaxis()->SetTitle("Wire channel"); h1100->SetTitle("Base subtracted APD signals vs time"); h1100->GetXaxis()->SetTitle("Time (#mus)"); h1100->GetYaxis()->SetTitle("APD channel"); h2000->SetTitle("Derivative of raw wire signals vs time"); h2000->GetXaxis()->SetTitle("Time (#mus)"); h2000->GetYaxis()->SetTitle("Wire channel"); h2100->SetTitle("Derivative of raw APD signals vs time"); h2100->GetXaxis()->SetTitle("Time (#mus)"); h2100->GetYaxis()->SetTitle("APD channel"); for ( Int_t isig = 0; isig < nsignal; isig++ ) { Int_t ch = eventData->chan[isig]; if ( ch < 0 ) continue; for (Int_t i = 0; i < nsamp; i++ ) { Int_t base = 0; if ( ch < 0 ) { base = 0; } else if ( ch < nchannel_per_wireplane*nwireplane ) { if ( ((ch/nchannel_per_wireplane)%2) == 0 ) { base = (Int_t)UWIRES_ADC_BASELINE_COUNTS; } else { base = (Int_t)VWIRES_ADC_BASELINE_COUNTS; } } else { base = (Int_t)APD_ADC_BASELINE_COUNTS; } //plot raw wire signals with base subtraction if(ch < nwires){ h1000->SetBinContent(i+1,isig+1, (Double_t)(eventData->data[isig*nsamp+i]-base)); //plot difference between wire signals at time t+1 us and time t if ( i < nsamp - 1 ) { h2000->SetBinContent(i+1,isig+1, (Double_t)(eventData->data[isig*nsamp+i+1]-eventData->data[isig*nsamp+i])); } } else { //plot raw apd signals with base subtraction h1100->SetBinContent(i+1,isig-nwires+1, (Double_t)(eventData->data[isig*nsamp+i]-base)); if (i < nsamp - 1) { //plot difference between apd signals at time t+1 us and time t h2100->SetBinContent(i+1,isig-nwires+1, (Double_t)(eventData->data[isig*nsamp+i+1]-eventData->data[isig*nsamp+i])); } } } } } void EXOEventDisplayGui::GoPage(){ // Goes to specific page of event display } void EXOEventDisplayGui::NextPage(){ // Goes to next page of event display } void EXOEventDisplayGui::PreviousPage(){ // Goes to previous page of event display } void EXOEventDisplayGui::RequestEntry(int request_entrynumber) { analysisManager->RunEventDisplay(request_entrynumber, -1, -1); //update number entry fields for run and event numbers fRequestRun->SetIntNumber( eventData->nr ); fRequestEvent->SetIntNumber( eventData->ne ); fRequestEntry->SetIntNumber( inputModule->get_entry_number() ); //update plot when entry number is updated DoDraw(); // this is temporary since this should match whichever page/radio button is chosen } void EXOEventDisplayGui::RequestEvent(int request_runnumber, int request_eventnumber) { analysisManager->RunEventDisplay(-1, request_runnumber, request_eventnumber); //update number entry field for entry number fRequestEntry->SetIntNumber( inputModule->get_entry_number() ); fRequestRun->SetIntNumber( eventData->nr ); fRequestEvent->SetIntNumber( eventData->ne ); //update plot when event number is updated DoDraw(); // this is temporary since this should match whichever page/radio button is chosen } void EXOEventDisplayGui::EntryUpdate() { RequestEntry(fRequestEntry->GetIntNumber()); } void EXOEventDisplayGui::EventUpdate() { int request_runnumber = fRequestRun->GetIntNumber(); int request_eventnumber = fRequestEvent->GetIntNumber(); RequestEvent(request_runnumber, request_eventnumber); } void EXOEventDisplayGui::GetDataSource() { // If the user requested a file on the command line, then // filename will not be NULL. If filename is NULL, we // attempt to get the name of the file from the filename // field in the GUI. char filecommand[300]; if ( filename == NULL ) { sprintf(filecommand,"/input/file %-199s", fRequestFilename->GetText() ); } else { sprintf(filecommand,"/input/file %-199s", filename ); // Make sure the filename is diplayed in the GUI fRequestFilename->SetText( filename ); } // cout << "filecommand is: " << filecommand << endl; talktoManager->InterpretCommand( filecommand ); talktoManager->InterpretCommand( "use input"); // Order the modules. For the moment, all this does is set the inputModule pointer. int result = 0; result = analysisManager->OrderModules(); if ( result != 0 ) return; // Make sure that we have an input module inputModule = analysisManager->GetInputModule(); if ( analysisManager->GetInputModule() == NULL ) { errorLogger->LogError("EXOEventDisplayGui","Constructor", "no input module ",5); return; } // Initialize the input module analysisManager->GetInputModule()->Initialize(); RequestEntry( fRequestEntry->GetIntNumber() ); // look at first entry (default first entry = 0) } EXOEventDisplayGui::~EXOEventDisplayGui() { // Clean up used widgets: frames, buttons, layout hints fMain->Cleanup(); delete fMain; }