#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; ClassImp(view::EventBrowser) namespace view { // Polling cycle of communication in auto-next mode, 0.1sec in msecs. const unsigned int EventBrowser::fDeltaT=100; EventBrowser::EventBrowser(const TGWindow* p, int width, int height) : TGMainFrame(p, width, height) { // Currently event is not changing. fIsEventChanging=false; // Welcome printout Welcome(); /* Add the menu */ fMenu = new EventBrowserMenu(this); /* Add the tabs for FD and SD data */ fTabs = new TGTab(this, width, height); fTabLayout = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 3, 3, 3, 3); TGCompositeFrame* eventDisplayFrame = fTabs->AddTab("Event Display"); TGCompositeFrame* rawDataFrame = fTabs->AddTab("Raw Data"); TGCompositeFrame* optionsFrame = fTabs->AddTab("Options"); fTabIsUpToDate[eEventDisplay] = false; fTabIsUpToDate[eOnlineDisplay] = false; fTabIsUpToDate[eCutTab] = true; fOptions = new EventBrowserOptions(optionsFrame); // create plot objects fEventDisplay = new EventDisplay(eventDisplayFrame); fOnlineMonitor = new OnlineMonitor(rawDataFrame); AddFrame(fTabs, fTabLayout); fStatusBar = new StatusBar(this); BindKeys(); SetWindowName("Shine EventBrowser - no input data "); MapSubwindows(); Resize(GetDefaultSize()); MapWindow(); UpdateBrowser(); CurrentEvent::GetInstance().SetEvent(fEvent); // input file name const string& fileName = OptionsManager::GetInstance().GetInputFilename(); if (fileName.empty()) fEventFile = new io::EventFile(); else { OpenDataFile(fileName); // If we have automatic event reading mode on, go for it. OptionsManager& options = OptionsManager::GetInstance(); if (options.IsAutomaticEventReadingMode()) AutoNextEvent(); } } EventBrowser::~EventBrowser() { delete fEventDisplay; delete fTabs; delete fTabLayout; delete fMenu; delete fEventFile; } string EventBrowser::GetRevision() { string revision("$Revision: 6558 $"); return revision.substr(1,revision.size()-2); } string EventBrowser::GetDate() { string date("$Date: 2012-04-04 16:37:26 +0200 (śro) $"); return date.substr(1,date.size()-2); } void EventBrowser::Welcome() { const string space = " "; cout << "\n" << "\033[1;31m \n" << space<< " ____ \n" << space<< " NA61/SHINE _ | ___ \\\n" << space << " _____ _____ _ __ | |_| |" << "_/ /_ __ _____ _____ ___ _ __ \n" << space << " / _ \\ \\ / / _ \\ '_ \\| __| _" << "__ \\ '__/ _ \\ \\ /\\ / / __|/ _ \\ '__|\n" << space << "| __/\\ V / __/ | | | |_| |_" << "/ / | | (_) \\ V V /\\__ \\ __/ | \n" << space << " \\___| \\_/ \\___|_| |_|\\__\\" << "____/|_| \\___/ \\_/\\_/ |___/\\___|_| \n\033[0m\n" << space << GetRevision() << "\n" << space << GetDate() << "\n" << endl; } bool EventBrowser::HandleKey(Event_t* event) { unsigned int keysym; char str[2]; gVirtualX->LookupString(event, str, sizeof(str), keysym); if (event->fType == kGKeyPress) { EKeySym theKeyPressed = (EKeySym) keysym; if (theKeyPressed == kKey_q || theKeyPressed == kKey_Q) CloseWindow(); else if (theKeyPressed == kKey_Escape) CloseWindow(); else if (theKeyPressed == kKey_PageDown) ChangeEvent(eNextEvent); else if (theKeyPressed == kKey_PageUp) ChangeEvent(ePreviousEvent); else if (theKeyPressed == kKey_Home) ChangeEvent(eFirstEvent); else if (theKeyPressed == kKey_End) ChangeEvent(eLastEvent); else if (theKeyPressed == kKey_Space || theKeyPressed == kKey_Backtab) ChangeTab(ePreviousTab); else if (theKeyPressed == kKey_Tab) ChangeTab(eNextTab); else { if (fEventDisplay) { if (event->fState & kKeyShiftMask) fEventDisplay->NavigateAround(theKeyPressed,kKey_Shift); else fEventDisplay->NavigateAround(theKeyPressed,kAnyKey); } } } return kTRUE; } Bool_t EventBrowser::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2) { // Process messages coming from widgets associated with the dialog. /* cout << " :ProcessMessage1 " << msg << " " << parm1 << " " << parm2 << endl; // debug cout << " " << GET_MSG (msg) << " " << GET_SUBMSG (msg) << endl; */ switch (GET_MSG (msg)) { case kC_COMMAND: switch (GET_SUBMSG(msg)) { case kCM_COMBOBOX: if (parm1 == eStatusBarEventList) { ChangeEvent(eCurrentEvent, parm2); } if (parm1 == eDetectorZoomList) fEventDisplay->ZoomToDetector(parm2); break; case kCM_TAB: UpdateTab(parm1); break; case kCM_BUTTON: if (parm1 == eNextEvent) ChangeEvent(eNextEvent); else if (parm1 == ePreviousEvent) ChangeEvent(ePreviousEvent); else if (parm1 == eFirstEvent) ChangeEvent(eFirstEvent); else if (parm1 == eLastEvent) ChangeEvent(eLastEvent); break; case kCM_CHECKBUTTON: /* */ break; case kCM_MENU: switch (parm1) { // ------------------- THE FILE MENU ---------------- case eFileOpen: { TString directory("."); TGFileInfo fi; fi.fIniDir = StrDup(directory.Data()); new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fi); if (fi.fFilename) OpenDataFile(string(fi.fFilename)); } break; case eConnectToDAQ: { string serverName(""); new SelectDAQServer(this, serverName); if (serverName != "") OpenDataFile(serverName); } break; case eFileClear: break; case eFileSaveROOT: SaveEvent(); break; case eLoadStyle: { string theDir = string(gSystem->ExpandPathName("$SHINE_BROWSER_CONFIG")); TString directory(theDir.c_str()); TGFileInfo fi; const char* styleFileTypes[] = { "Style files", "*.sty" , "All files", "*", 0, 0 }; fi.fFileTypes = styleFileTypes; fi.fIniDir = StrDup(directory.Data()); new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fi); if (fi.fFilename) { StyleManager::GetInstance().ReadStyleFile(fi.fFilename); UpdateBrowser(); } } break; case eFileQuit: CloseWindow(); break; // -------------------- THE OPTIONS MENU -------------------------- case eShowMCTracks: { bool mcflag = fMenu->ToggleMCOption(eShowMCTracks); OptionsManager::GetInstance().SetShowMCTracks(mcflag); UpdateBrowser(); } break; case eShowMCHits: { bool mcflag = fMenu->ToggleMCOption(eShowMCHits); OptionsManager::GetInstance().SetShowMCHits(mcflag); UpdateBrowser(); } break; case eShowOnlyMC: { bool mcflag = fMenu->ToggleMCOption(eShowOnlyMC); OptionsManager::GetInstance().SetShowOnlyMC(mcflag); UpdateBrowser(); } break; case eShowOnlyMCTracksWithHits: { bool mcflag = fMenu->ToggleMCOption(eShowOnlyMCTracksWithHits); OptionsManager::GetInstance().SetShowOnlyMCTracksWithHits(mcflag); UpdateBrowser(); } break; // ------------------- THE HELP MENU ---------------- case eAbout: { EMsgBoxIcon icontype = kMBIconAsterisk; EMsgBoxButton buttonType = kMBOk; Int_t retval; ostringstream info; info << "NA61 EventBrowser \n\n" << "Version: rev " << GetRevision() << " from " << GetDate() << "\n" << "Compiled with ROOT v" << gROOT->GetVersion() << "\n" << "Authors: I. Maris, R. Ulrich and M. Unger\n\n" << "have fun browsing !\n\n"; new TGMsgBox(gClient->GetRoot(), gClient->GetRoot(), "About",info.str().c_str(), icontype, buttonType, &retval); } break; } } } return kTRUE; } Bool_t EventBrowser::TrackSelect(TObject* /*obj*/, Bool_t /*signal*/) { fEventDisplay->Update(true); //UpdateBrowser(); //fEventDisplay->TrackSelect(); return true; } void EventBrowser::CloseWindow() { // TGMainFrame::CloseWindow(); // gApplication->Terminate(0); gSystem->ExitLoop(); // return from TApplication::Run() } void EventBrowser::UpdateBrowser() { // FIXME MU /* fTabs->SetEnabled(0, (fEventServer.IsMC() || fEventServer.GetEvent().HasRecData())); // no rec/MC data */ fTabIsUpToDate[eEventDisplay] = false; fTabIsUpToDate[eOnlineDisplay] = false; fEventDisplay->Clear(); UpdateTab(fTabs->GetCurrent()); } void EventBrowser::UpdateTab(unsigned int iTab) { if (!fTabIsUpToDate[iTab]) { switch(iTab) { case eEventDisplay: fEventDisplay->Update(); fTabIsUpToDate[eEventDisplay] = true; break; case eOnlineDisplay: fOnlineMonitor->Update(); fTabIsUpToDate[eOnlineDisplay] = true; break; } } } void EventBrowser::ProcessOptionButtons() { TGButton* button = (TGButton*)gTQSender; UInt_t id = button->WidgetId(); OptionsManager& options = OptionsManager::GetInstance(); switch(id) { // Vertex options case eShowMainVertex: case eShowBPDVertex: case eShowFitVertex: // DIPT options case eDIPTGolden: case eDIPTMerged: case eDIPTElectron: case eDIPTNoise: options.SetButtonState((EButtonSignals)id, button->IsDown()); fEventDisplay->Update(false); break; case eAutoReadEnable: options.SetAutomaticEventReadingMode(button->IsDown()); fStatusBar->SetButtonAutoMode(); if (options.IsAutomaticEventReadingMode()) AutoNextEvent(); break; default: cerr << " EventBrowser::ProcessOptionButtons() " << " unknwon signal " << id << endl; break; } } void EventBrowser::ChangeTab(Long_t where) { int nTabs = fTabs->GetNumberOfTabs(); int currTab=fTabs->GetCurrent(); if (where == eNextTab) { for (int i = currTab+1; iIsEnabled(i)) { fTabs->SetTab(i); return; } for (int i = 0; iIsEnabled(i)) { fTabs->SetTab(i); return; } } else if (where == ePreviousTab) { for (int i = currTab-1; i>-1; --i) if (fTabs->IsEnabled(i)) { fTabs->SetTab(i); return; } for (int i = nTabs-1; i>currTab ; --i) if (fTabs->IsEnabled(i)) { fTabs->SetTab(i); return; } } } void EventBrowser::OpenDataFile(const string& fileName) { if (fileName.empty()) { ERROR("No input file specified!"); return; } delete fEventFile; fEventFile = new io::EventFile(fileName); if (fEventFile->IsOpen()) { fStatusBar->Update(fileName, fEventFile->IsRandomAccess()); // If the first file is not a bosserver, read one event immediately. if (fileName.substr(0, 10) != "bosserver:") ChangeEvent(eNextEvent); } } void EventBrowser::ErrorMsg(const string& err) { EMsgBoxIcon icontype = kMBIconAsterisk; EMsgBoxButton buttonType = kMBClose; Int_t retval; new TGMsgBox(gClient->GetRoot(), gClient->GetRoot(), "Error", err.c_str(), icontype, buttonType, &retval); } bool EventBrowser::HasMCData() const { using namespace evt; const SimEvent& simEvent = CurrentEvent::GetInstance().GetEvent().GetSimEvent(); if (simEvent.GetNumberOf() || simEvent.GetNumberOf() || simEvent.GetNumberOf()) return true; else return false; } void EventBrowser::ChangeEvent(Long_t what, int eventId) { // If event is already changing, just ignore ChangeEvent command. if (fIsEventChanging) return; fIsEventChanging = true; using namespace io; EStatus status = eFail; try { if (what == eNextEvent) { status = fEventFile->Read(fEvent); } else if (what == ePreviousEvent) { const int position = fEventFile->GetCurrentPosition(); if (position == 0) { INFO("already at file beginning"); fIsEventChanging = false; return; } else if (position >= 0) status = fEventFile->Read(position-1, fEvent); // otherwise status = eFail beause position is -1 } else if (what == eLastEvent) { status = fEventFile->Read(fEventFile->GetNEvents()-1, fEvent); } else if (what == eFirstEvent) { status = fEventFile->Read(0, fEvent); } else if (what == eCurrentEvent) { status = fEventFile->Read(eventId, fEvent); } else { ostringstream msg; msg << "signal" << what << " not implemented"; WARNING(msg.str()); } } catch(const utl::ShineException& error) { CurrentEvent::GetInstance().AddWarningOrError(error.GetMessage()); } if (status == eSuccess) { // read away empty event if first event if (fEventFile->GetCurrentPosition() == 0 && !fEvent.GetEventHeader().IsInitialized()) { INFO("skipping time zero event"); status = fEventFile->Read(fEvent); } } if (status == eSuccess) { SetWindowName(("Shine EventBrowser - " + fEventFile->GetFilename()).c_str()); } else if (status == eEOF) { SetWindowName("Shine EventBrowser - end of file"); INFO("reached end of file"); fIsEventChanging = false; return; } else { SetWindowName("Shine EventBrowser - ERROR reading event"); ERROR("error reading event"); fIsEventChanging = false; return; } fStatusBar->Update(fEventFile->GetCurrentPosition()); const evt::EventHeader& header = fEvent.GetEventHeader(); det::Detector::GetInstance().Update(header.GetTime(), header.GetRunNumber()); // If we got the event, finally update displayed event. CurrentEvent::GetInstance().SetEvent(fEvent); if (fEvent.GetSimEvent().GetNumberOf()) fMenu->EnableMC(); UpdateBrowser(); // Event is ready. fIsEventChanging = false; } void EventBrowser::AutoNextEvent() { INFO("Entering to automatic event reading mode.\n"); OptionsManager& options = OptionsManager::GetInstance(); unsigned int elapsedTimeMSec=0; while (options.IsAutomaticEventReadingMode()) { if (elapsedTimeMSec>=options.GetAutomaticEventReadingModeDelay()*1000) { ChangeEvent(eNextEvent); elapsedTimeMSec=0; } gSystem->ProcessEvents(); usleep(fDeltaT*1000); elapsedTimeMSec+=fDeltaT; } INFO("Exiting from automatic event reading mode.\n"); } void EventBrowser::BindKeys() { const TGWindow* thisWindow = (const TGWindow*)this; // define keyboard strokes to be handled by the Eventbrowser BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Q), kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Escape), kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Down),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Left), kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Right),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Up), kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_PageDown),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_PageUp), kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Home),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_End), kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Space),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Tab),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Backtab),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_P),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Minus),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_Plus),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_S),kAnyModifier); BindKey(thisWindow, gVirtualX->KeysymToKeycode(kKey_A),kAnyModifier); } void EventBrowser::SaveEvent() { TString directory("."); TGFileInfo fi; fi.fIniDir = StrDup(directory.Data()); new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fi); if(fi.fFilename) { string fileName = fi.fFilename; if (fileName.find(".root")==string::npos) { ostringstream tmpName; tmpName << fileName << ".root"; fileName = tmpName.str(); } INFO("saving current event to "+fileName); io::ShineEventFile outputFile(fileName, io::eNew); outputFile.Write(CurrentEvent::GetInstance().GetEvent()); outputFile.Close(); } } }