#include "HKED.h" #include #include #include #include "HKED_Util.h" #include #include #include #include #include #include "EvNavHandler.h" #include "Rtypes.h" #include #include using HKED_Util::UnrollView; using HKED_Util::rotateTank; using std::cout; using std::endl; /** * Static methods should be defined outside the class. */ HKED* HKED::HKDisplayManager{nullptr}; std::mutex HKED::mutex_; /** * The first time we call GetInstance we will lock the storage location * and then we make sure again that the variable is null and then we * set the value. RU: */ HKED* HKED::GetInstance() { std::lock_guard lock(mutex_); if (HKDisplayManager == nullptr) { HKDisplayManager = new HKED(); } return HKDisplayManager; } HKED::HKED() {} void HKED::InitialiseWCSim(TFile* inFile) { WCSimFile=inFile; wcsimGeoT=(TTree *) WCSimFile->Get("wcsimGeoT"); if(wcsimGeoT == nullptr) { cout<<" Failed to open geometry tree wcsimGeoT in "<GetName()< SetBranchAddress ("wcsimrootgeom" ,&wcsimrootgeom ); wcsimGeoT->GetEntry(0) ; } /* Setup the views et. */ void HKED::Setup() { make_gui(); fiTQun.GetChernkovDisplay()->SetLimits(maxR, minZ, maxZ ); fiTQun.GetChernkovDisplay()->SetWCSimGeom(wcsimrootgeom); wcsimT = (TTree*)WCSimFile ->Get("wcsimT"); wcsimrootEvent = new WCSimRootEvent (); wcsimT -> SetBranchAddress ("wcsimrootevent" ,&wcsimrootEvent); wcsimT->GetBranch("wcsimrootevent")->SetAutoDelete(kTRUE); wcsimT->GetEvent(0); cout<<" There are "<GetEntries()<<" events in this file."<SpawnNewViewer(name,name); View->AddScene(scene); // add the special scene that only applies to this view View->AddScene(gEve->GetGlobalScene()); // add the geometry information View->GetGLViewer()->SetCurrentCamera(type); View->GetGLViewer()->GetLightSet()->SetLight( TGLLightSet::kLightFront,kFALSE); View->GetGLViewer()->SetResetCamerasOnUpdate(kFALSE); return View; } void HKED::reload_truth() { TEveElement::List_t matches; TPRegexp regexp("Truth Tracks*"); Int_t n = UnrolledScene->FindChildren ( matches,regexp); for( auto element : matches) { UnrolledScene->RemoveElement(element); } TEveElement::List_t matches2; n = gEve->GetCurrentEvent()->FindChildren ( matches2,regexp); for( auto element : matches2) { gEve->GetCurrentEvent()->RemoveElement(element); } for(int iTrigger=0;iTriggerGetNumberOfEvents();iTrigger++) { wcsimrootTrigger = wcsimrootEvent->GetTrigger(iTrigger); bool firstTrackIsNeutrino,secondTrackIsTarget; wcsim_load_truth_tracks(iTrigger,firstTrackIsNeutrino,secondTrackIsTarget); } gEve->Redraw3D(kFALSE, kTRUE); } /* Load an event. */ void HKED::load_event() { fHKEVInfo->ClearTemporary(); fHKEVInfo2D->ClearTemporary(); // Load event specified in global event_id. // The contents of previous event are removed. if(fFirstTime) { gStyle->SetPalette(fPredefinedPalette ,0); TColor::InvertPalette(); fFirstTime=kFALSE; } TEveEventManager* CurrentEvent =gEve->GetCurrentEvent(); if(! fAccumulateEvents ){ if( CurrentEvent != 0)CurrentEvent->DestroyElements(); if( UnrolledScene !=0 )UnrolledScene->DestroyElements(); } /* Get the next event from WCSim, loop over its triggers and put it into Eve */ wcsimT->GetEvent(event_id); fgHtmlSummary->Clear("D"); for(int iTrigger=0;iTriggerGetNumberOfEvents();iTrigger++) { wcsimrootTrigger = wcsimrootEvent->GetTrigger(iTrigger); bool firstTrackIsNeutrino,secondTrackIsTarget; wcsim_load_event(iTrigger,firstTrackIsNeutrino,secondTrackIsTarget); update_html_summary(iTrigger,wcsimrootTrigger,firstTrackIsNeutrino,secondTrackIsTarget); } fitqun_load_event(); fiTQun.CreateTable( fgHtmlSummary); fgHtmlSummary->SetTitle(Form("HyperK Event Display Summary, for entry %i",event_id)); fgHtmlSummary->Build(); fgHtml->Clear(); fgHtml->ParseText((char*)fgHtmlSummary->Html().Data()); fgHtml->Layout(); gEve->Redraw3D(kFALSE, kTRUE); } void HKED::fitqun_load_event() { fiTQun.Process(event_id); } void HKED::showTruthCones(bool drawThem) { /* First find the cones associated to truth in the default event (3D display) */ TEveElement::List_t matches; TPRegexp regexp("Truth Tracks*"); Int_t n = gEve->GetCurrentEvent()->FindChildren ( matches,regexp); for( auto element : matches) { TEveElement::List_t Particles; TPRegexp regexp("Truth*"); Int_t n = element->FindChildren ( Particles,regexp); for (auto particle : Particles) { // find a cone belonging to this particle TEveElement::List_t cones; TPRegexp regexp(".*cone.*"); Int_t n = particle->FindChildren ( cones,regexp); for (auto cone : cones) cone->SetRnrState(drawThem); } } /* Now look for collections of cones in Unrolled Scenes */ n = UnrolledScene->FindChildren ( matches,regexp); for( auto element : matches) { element->SetRnrState(drawThem); } gEve->GetDefaultViewer()->GetGLViewer()->UpdateScene(); UnrolledView->GetGLViewer()->UpdateScene(); } void HKED::wcsim_load_event(int iTrigger,bool &firstTrackIsNeutrino,bool &secondTrackIsTarget ) { wcsim_load_cherenkov(iTrigger); wcsim_load_truth_tracks(iTrigger,firstTrackIsNeutrino,secondTrackIsTarget); } /* Loop over cherenkov digits and add them to Eve */ void HKED::wcsim_load_cherenkov(int iTrigger){ /* Set up box set for 3D view */ TEveBoxSet* CherenkovHits= new TEveBoxSet(Form("Cherenkov Hits subevent %i",iTrigger)); CherenkovHits->SetPalette(fHitPalette); CherenkovHits->SetEmitSignals(kTRUE); CherenkovHits->SetCallbackFoo(&PrintCherenkovHitInformation3D); CherenkovHits->Reset(TEveBoxSet::kBT_Cone, kFALSE, 64); /* set up box set for unrolled view */ TEveBoxSet* CherenkovHits2= new TEveBoxSet(Form("CherenkovHits (Unrolled version) %i",iTrigger)); CherenkovHits2->SetPalette(fHitPalette); CherenkovHits2->SetEmitSignals(kTRUE); CherenkovHits2->SetCallbackFoo(&PrintCherenkovHitInformation2D); CherenkovHits2->Reset(TEveBoxSet::kBT_Cone, kFALSE, 64); float PMTRadius = wcsimrootgeom->GetWCPMTRadius() ; int max=wcsimrootTrigger->GetNcherenkovdigihits(); float maxCharge=0; float minT=1e10; float maxT=-1e10; /* Loop over hits and add them to the digit set objects We need the mean and standard deviation of the data to set a sensible range for the colours used in the display/ */ float count=0; float mean=0; float M2=0; for (int i = 0; iGetCherenkovDigiHits()->At(i); int tubeId=cDigiHit->GetTubeId(); float Q=cDigiHit->GetQ(); float Time=cDigiHit->GetT(); maxCharge=TMath::Max(Q,maxCharge); minT = TMath::Min(minT,Time); maxT = TMath::Max(maxT,Time); WCSimRootPMT pmt = wcsimrootgeom -> GetPMT ( tubeId ); double pmtX = pmt.GetPosition (0); double pmtY = pmt.GetPosition (1); double pmtZ = pmt.GetPosition (2); float R=sqrt(pmtX*pmtX+pmtY*pmtY+pmtZ*pmtZ); int location=pmt.GetCylLoc(); double pmtX2=pmtX; double pmtY2=pmtY; double pmtZ2=pmtZ; if(R<100 || location <0 || location >2) cout<<"INVALID photo tube location . Tube id:" <AddElement(TrueCones2D); // Get the number of tracks int ntrack = wcsimrootTrigger->GetNtrack(); if(ntrack>0) { int npar = wcsimrootTrigger->GetNpar(); int i; if(iTrigger==0) { firstTrackIsNeutrino=kFALSE; secondTrackIsTarget=kFALSE; // Take a first look and decide if we have a neutrino interaction. // If so the neutrino and target will need their start position // adjusting. TObject *element = (wcsimrootTrigger->GetTracks())->At(0); WCSimRootTrack *wcsimroottrack = dynamic_cast(element); int pdgCode=wcsimroottrack->GetIpnu(); if(abs(pdgCode)==12 || abs(pdgCode)==14) firstTrackIsNeutrino=kTRUE; if(ntrack>1) { TObject *element = (wcsimrootTrigger->GetTracks())->At(1); WCSimRootTrack *wcsimroottrack = dynamic_cast(element); int pdgCode=wcsimroottrack->GetIpnu(); if(abs(pdgCode)==2212 && wcsimroottrack->GetStart(0)==0.0 && wcsimroottrack->GetStart(1)==0.0 && wcsimroottrack->GetStart(2)==0.0 ) secondTrackIsTarget=kTRUE; } } // Loop through elements in the TClonesArray of WCSimTracks TEveElementList* TrueTracks = new TEveElementList(Form("Truth Tracks subevent %i",iTrigger)); for (i=0; iGetTracks())->At(i); WCSimRootTrack *wcsimroottrack = dynamic_cast(element); bool keep; bool draw; selectTruthTrack(wcsimroottrack,keep,draw); if(!keep)continue; int pdgCode=wcsimroottrack->GetIpnu(); if(pdgCode==0)continue; TString Name("Truth "+ParticleName(pdgCode)); if(iTrigger==0) { if(i==1 && secondTrackIsTarget) Name+=" (target) "; if(i==0 && firstTrackIsNeutrino) Name+=" (beam) "; } Name=Name+Form(" (%d) ",i); THKMCTrack* track=new THKMCTrack(Name); float Start[3]; float Stop[3]; float Mass=0; float Momentum=0; double Theta=0; double Phi=0; float Energy=0; track->SetElementTitle(Name); track->SetMainColor(kWhite); if(abs(pdgCode)==11)track->SetMainColor(kYellow); if(abs(pdgCode)==12)track->SetMainColor(kBlue); if(abs(pdgCode)==13)track->SetMainColor(kMagenta); if(abs(pdgCode)==14)track->SetMainColor(kGreen); if(abs(pdgCode)==2212)track->SetMainColor(kRed); FillStop(Stop,wcsimroottrack); FillStart(Stop,wcsimroottrack); /* Implement fix for neutrino and target start positions */ if(i==0 && firstTrackIsNeutrino && iTrigger == 0) { track->SetNextPoint(wcsimroottrack->GetStop(0),wcsimroottrack->GetStop(1),maxZ*-1.1); FillStop(Start,wcsimroottrack); Start[2]=maxZ*-1.1; } else { if(i==1 && secondTrackIsTarget && iTrigger == 0 ) { track->SetNextPoint(wcsimroottrack->GetStop(0),wcsimroottrack->GetStop(1),wcsimroottrack->GetStop(2)); FillStop(Start,wcsimroottrack); } else { track->SetNextPoint(wcsimroottrack->GetStart(0),wcsimroottrack->GetStart(1),wcsimroottrack->GetStart(2)); } } if(abs(pdgCode)==12 || abs(pdgCode)==14 || abs(pdgCode)==16 ||abs(pdgCode)==22 ||abs(pdgCode)==111 ||abs(pdgCode)==310) track->SetLineStyle(2); track->SetNextPoint(wcsimroottrack->GetStop(0),wcsimroottrack->GetStop(1),wcsimroottrack->GetStop(2)); Mass=wcsimroottrack->GetM(); Momentum=wcsimroottrack->GetP(); Energy=wcsimroottrack->GetE(); double PT[3]; double PTtot=0; if(wcsimroottrack->GetP()>0){ PT[0]=wcsimroottrack->GetP()*wcsimroottrack->GetPdir(0); PT[1]=wcsimroottrack->GetP()*wcsimroottrack->GetPdir(1); PT[2]=wcsimroottrack->GetP()*wcsimroottrack->GetPdir(2); CartesianToPolar(PTtot,Theta,Phi,PT); } track->SetValues(Start,Stop,Mass,Momentum,Energy,Theta,Phi,draw); /* Now add the predicted cherenkov cone for electrons and muons */ int abspdg=abs(pdgCode); if(abspdg==11 || abspdg == 13 ){ THKCherenkov2D* cone2D = new THKCherenkov2D(Name+" Cherenkov light cone",draw); THKCherenkov* cone = new THKCherenkov(Name+" Cherenkov light cone"); double pos[3]={Start[0],Start[1],Start[2]}; float totalLength = TrackLength(pos,Stop); float step = 10.0; float deltaX = step*(Stop[0]-Start[0])/totalLength; float deltaY = step*(Stop[1]-Start[1])/totalLength; float deltaZ = step*(Stop[2]-Start[2])/totalLength; float travelled{0.0}; bool OK=kFALSE; int nStep=0; do { bool result=CD.createCherenkov(cone,cone2D,Name,kGreen,Momentum,Theta,Phi,Mass,pos,kTRUE); OK= OK || result; pos[0]=pos[0]+deltaX; pos[1]=pos[1]+deltaY; pos[2]=pos[2]+deltaZ; travelled = TrackLength(Start,pos); nStep++; } while(travelledAddElement(cone); TrueCones2D->AddElement(cone2D); } if(!draw) { track->SetRnrState(false); cone2D->SetRnrState(false); } if(!drawTruthCones) { cone->SetRnrState(false); cone2D->SetRnrState(false); } } /* Add this track to the list */ TrueTracks->AddElement(track); } // End of loop over tracks if(ntrack>0)gEve->AddElement(TrueTracks); //Hists->Update(); } } void HKED::FillStop(float Stop[3],WCSimRootTrack* wcsimroottrack) { Stop[0]=wcsimroottrack->GetStop(0); Stop[1]=wcsimroottrack->GetStop(1); Stop[2]=wcsimroottrack->GetStop(2); } void HKED::FillStart(float Start[3],WCSimRootTrack* wcsimroottrack) { Start[0]=wcsimroottrack->GetStart(0); Start[1]=wcsimroottrack->GetStart(1); Start[2]=wcsimroottrack->GetStart(2); } float HKED::TrackLength(double Start[3], float Stop[3]){ float l=(Stop[0]-Start[0])*(Stop[0]-Start[0]) + (Stop[1]-Start[1])*(Stop[1]-Start[1]) + (Stop[2]-Start[2])*(Stop[2]-Start[2]); return sqrt(l); } float HKED::TrackLength(float Start[3], double Stop[3]){ float l=(Stop[0]-Start[0])*(Stop[0]-Start[0]) + (Stop[1]-Start[1])*(Stop[1]-Start[1]) + (Stop[2]-Start[2])*(Stop[2]-Start[2]); return sqrt(l); } /* Call back function for displaying information about Cherenkov hits */ void HKED::PrintCherenkovHitInformation(Picker* picker,TEveDigitSet* ds, Int_t idx, TObject* obj) { if(obj) { WCSimRootCherenkovDigiHit *cDigiHit=(WCSimRootCherenkovDigiHit*) obj; if(cDigiHit) { int tubeId=cDigiHit->GetTubeId(); float Q=cDigiHit->GetQ(); float Time=cDigiHit->GetT(); WCSimRootPMT pmt = wcsimrootgeom -> GetPMT ( tubeId ); int location=pmt.GetCylLoc(); picker->Output(TString::Format("WCSim Cherenkov Hit. Id: %d \n Charge: %f, Time : %f\n Position : (%8.5G,%8.5G,%8.5G) \n Location %d ",tubeId,cDigiHit->GetQ(), cDigiHit->GetT(),pmt.GetPosition (0),pmt.GetPosition (1),pmt.GetPosition (2),pmt.GetCylLoc())); } else cout<<" PrintCherenkovHitInformation called without a WCSimRootCherenkovDigiHit object."<fHKEVInfo->ClearTemporary(); HKDisplayManager->PrintCherenkovHitInformation(HKDisplayManager->fPicker,ds, idx, obj); gEve->GetDefaultViewer()->GetGLViewer()->UpdateScene(); } void HKED::PrintCherenkovHitInformation2D(TEveDigitSet* ds, Int_t idx, TObject* obj) { HKDisplayManager->fHKEVInfo2D->ClearTemporary(); HKDisplayManager->PrintCherenkovHitInformation(HKDisplayManager->fPicker2D, ds, idx, obj); HKDisplayManager->UnrolledView->GetGLViewer()->UpdateScene(); } // Convert x,y,z of phototubes to position in Unrolled view void HKED::selectTruthTrack(WCSimRootTrack * wcsimroottrack,bool& keep,bool& draw) { float Energy=wcsimroottrack->GetE(); keep=true; draw=true; if(EnergyGetNumberOfEvents();iTrigger++) { wcsimrootTrigger = wcsimrootEvent->GetTrigger(iTrigger); reload_wcsim_hits(iTrigger); } } void HKED::reload_wcsim_hits(int iTrigger) { TEveEventManager* CurrentEvent =gEve->GetCurrentEvent(); if(CurrentEvent != 0){ TEveElement* CherenkovHits=CurrentEvent->FindChild(Form("Cherenkov Hits subevent %i",iTrigger)); if(CherenkovHits !=NULL)CurrentEvent->RemoveElement(CherenkovHits); } if(UnrolledScene != 0){ TEveElement* CherenkovHits=UnrolledScene->FindChild(Form("CherenkovHits (Unrolled version) %i",iTrigger)); if(CherenkovHits!=NULL)UnrolledScene->RemoveElement(CherenkovHits); } wcsim_load_cherenkov(iTrigger); } void HKED::ColourIsTimeBoxChanged(Bool_t s) { fDigitIsTime=s; reload_wcsim_hits(); TString text=paletteText(); fPaletteTitle->SetText(text); fPaletteTitle2->SetText(text); gEve->GetDefaultGLViewer()->UpdateScene(); UnrolledView->GetGLViewer()->UpdateScene(); } bool HKED::SwitchGeometry() { if(fSimpleGeometry) { // simple to full fSimpleGeometry=kFALSE; gGeoManager->SetTopVolume(WorldVolume); TGeoNode* CurrentNode = gGeoManager->GetCurrentNode(); if(geomRoot!=NULL)gEve->GetGlobalScene()->RemoveElement(geomRoot); geomRoot = new TEveGeoTopNode(gGeoManager, CurrentNode); gEve->AddGlobalElement(geomRoot); } else { // full to simple fSimpleGeometry=kTRUE; gGeoManager->SetTopVolume(SimpleVolume); TGeoNode* CurrentNode = gGeoManager->GetCurrentNode(); if(geomRoot!=NULL)gEve->GetGlobalScene()->RemoveElement(geomRoot); geomRoot = new TEveGeoTopNode(gGeoManager, CurrentNode); gEve->AddGlobalElement(geomRoot); } gEve->GetDefaultGLViewer()->UpdateScene(); return fSimpleGeometry; } TString HKED::paletteText() { if(fDigitIsTime) return "PMT Hit Times"; else return "PMT Charge"; } void HKED::update_html_summary(int iTrigger,WCSimRootTrigger * wcsimrootTrigger,bool firstTrackIsNeutrino,bool secondTrackIsTarget) { // Update summary of current event. int ntrack = wcsimrootTrigger->GetNtrack(); if(ntrack==0)return; int nused=0; HtmlObjTable *table; if(iTrigger==0) table = fgHtmlSummary->AddTable(Form("Truth Tracks subevent: %i",iTrigger), 13,kTRUE,"first"); else table = fgHtmlSummary->AddTable(Form("Truth Tracks subevent: %i",iTrigger), 13,kTRUE,"other"); table->SetLabel(0, "Type"); table->SetLabel(1, "Start X"); table->SetLabel(2, "Start Y"); table->SetLabel(3, "Start Z"); table->SetLabel(4, "Stop X"); table->SetLabel(5, "Stop Y"); table->SetLabel(6, "Stop Z"); table->SetLabel(7, "Mass "); table->SetLabel(8, "Momentum "); table->SetLabel(9, "Energy "); table->SetLabel(10, "Theta"); table->SetLabel(11, "Phi"); table->SetLabel(12, "Drawn"); int i; int used=0; // Loop through elements in the TClonesArray of WCSimTrack for (i=0; iGetTracks())->At(i); WCSimRootTrack *wcsimroottrack = dynamic_cast(element); int pdgCode=wcsimroottrack->GetIpnu(); if(pdgCode==0)continue; TString Name(Form(" #%d (%d) ",i,pdgCode)); if(pdgCode==11)Name+="electron"; if(pdgCode==-11)Name+="positron"; if(pdgCode==12)Name+="electron neutrino"; if(pdgCode==-12)Name+="electron anti-neutrino"; if(pdgCode==13)Name+="muon"; if(pdgCode==-13)Name+="anti-muon"; if(pdgCode==14)Name+="muon neutrino"; if(pdgCode==-14)Name+="muon anti-neutrino"; if(pdgCode==2212)Name+="proton"; if(pdgCode==-2212)Name+="anti-proton"; if(pdgCode==22)Name+="photon"; //Name=Name+Form(" (%d) ",i); if(i==0 && firstTrackIsNeutrino) Name+=" (beam) "; if(i==1 && secondTrackIsTarget) Name+=" (target) "; table->SetRowName(used, Name); for(int l=0;l<3;l++){ table->SetValue(l+1,used,wcsimroottrack->GetStart(l)); table->SetValue(l+4,used,wcsimroottrack->GetStop(l)); } if(i==0 && firstTrackIsNeutrino && iTrigger==0) { table->SetValue(1,used,wcsimroottrack->GetStop(0)); table->SetValue(2,used,wcsimroottrack->GetStop(1)); table->SetValue(3,used,-1.1*maxZ); } if(i==1 && secondTrackIsTarget && iTrigger==0) { table->SetValue(1,used,wcsimroottrack->GetStop(0)); table->SetValue(2,used,wcsimroottrack->GetStop(1)); table->SetValue(3,used,wcsimroottrack->GetStop(2)); } // Int_t GetIpnu() const { return fIpnu;} table->SetValue(7,used,wcsimroottrack->GetM()); table->SetValue(8,used,wcsimroottrack->GetP()); table->SetValue(9,used,wcsimroottrack->GetE()); double PT[3]; double PTtot=0; double Theta=0; double Phi=0; if(wcsimroottrack->GetP()>0){ PT[0]=wcsimroottrack->GetP()*wcsimroottrack->GetPdir(0); PT[1]=wcsimroottrack->GetP()*wcsimroottrack->GetPdir(1); PT[2]=wcsimroottrack->GetP()*wcsimroottrack->GetPdir(2); CartesianToPolar(PTtot,Theta,Phi,PT); } table->SetValue(10,used,Theta); table->SetValue(11,used,Phi); bool keep; bool draw; selectTruthTrack(wcsimroottrack,keep,draw); if(draw) table->SetStringValue(12,used,"drawn"); else table->SetStringValue(12,used,"not drawn"); used++; } // End of loop over tracks // } void HKED::make_gui() { // Create minimal GUI for event navigation, etc. TEveBrowser* browser = gEve->GetBrowser(); browser->StartEmbedding(TRootBrowser::kLeft); TGMainFrame* frmMain = new TGMainFrame(gClient->GetRoot(), 1000, 600); frmMain->SetWindowName("HyperK Event Display"); frmMain->SetCleanup(kDeepCleanup); TGCanvas* fCanvasWindow = new TGCanvas(frmMain, 10, 240); TGCompositeFrame* fFrame = new TGCompositeFrame(fCanvasWindow->GetViewPort(), 10, 100, kVerticalFrame); fFrame->SetLayoutManager(new TGVerticalLayout(fFrame)); fCanvasWindow->SetContainer(fFrame); // use hierarchical cleaning for container fFrame->SetCleanup(kDeepCleanup); EvNavHandler *Navigator= new EvNavHandler(this); TGLayoutHints* hfHints = new TGLayoutHints(kLHintsCenterX | kLHintsExpandX ,5,5,3,4); TGLayoutHints* itemHints = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY ,5,5,3,4); TGGroupFrame* Group; { Group = new TGGroupFrame(fCanvasWindow->GetContainer(),"Event Navigation"); TGHorizontalFrame* hf = new TGHorizontalFrame(Group); { TString icondir( Form("%s/icons/", gSystem->Getenv("ROOTSYS")) ); TGPictureButton* b = 0; b = new TGPictureButton(hf, gClient->GetPicture(icondir+"GoBack.gif")); b->SetToolTipText("Go back one event"); hf->AddFrame(b,itemHints); b->Connect("Clicked()", "EvNavHandler", Navigator, "Bck()"); b = new TGPictureButton(hf, gClient->GetPicture(icondir+"GoForward.gif")); b->SetToolTipText("Go forward one event"); hf->AddFrame(b,itemHints); b->Connect("Clicked()", "EvNavHandler", Navigator, "Fwd()"); } Group->AddFrame(hf); fCanvasWindow->AddFrame(Group,hfHints); /* Control to toggle from full to simple geometry */ Group = new TGGroupFrame(fCanvasWindow->GetContainer(),"Geometry Choice"); fSimpleGeometry=kTRUE; hf = new TGHorizontalFrame(Group); { Navigator->fGeometrySwitchButton = new TGTextButton(Group, " Full Geometry "); Navigator->fGeometrySwitchButton->SetToolTipText("Switch to Full Geometry"); Navigator->fGeometrySwitchButton->Connect("Clicked()","EvNavHandler", Navigator,"SwitchGeometry()"); } Group->AddFrame( Navigator->fGeometrySwitchButton); fCanvasWindow->AddFrame(Group,hfHints); /* Control to toggle event accumulation on or off */ fAccumulateEvents=kFALSE; Group = new TGGroupFrame(fCanvasWindow->GetContainer(),"Event accumulation"); hf = new TGHorizontalFrame(Group); { TGCheckButton* fAccumulateEventsBox = new TGCheckButton(hf, "Accumulate events.",1); fAccumulateEventsBox->SetState(kButtonUp); fAccumulateEventsBox->SetToolTipText("If this is checked, don't unload events from Eve."); fAccumulateEventsBox->Connect("Toggled(Bool_t)", "EvNavHandler", Navigator, "AccumulateEventsBoxChanged(Bool_t)"); hf->AddFrame(fAccumulateEventsBox); } Group->AddFrame(hf); fCanvasWindow->AddFrame(Group,hfHints); /* Control to toggle event colour is time */ fDigitIsTime=kTRUE; Group = new TGGroupFrame(fCanvasWindow->GetContainer(),"Colour for Digits"); hf = new TGHorizontalFrame(Group); { TGCheckButton* fColourIsTimeBox = new TGCheckButton(hf, "Digit Colour is Time.",1); fColourIsTimeBox->SetState(kButtonDown); fColourIsTimeBox->SetToolTipText("If this is checked, digit colour represents time, otherwise it is charge."); fColourIsTimeBox->Connect("Toggled(Bool_t)", "EvNavHandler", Navigator, "ColourIsTimeBoxChanged(Bool_t)"); hf->AddFrame(fColourIsTimeBox); } Group->AddFrame(hf); fCanvasWindow->AddFrame(Group,hfHints); /* Control to clear temporary information from the overlay */ Group = new TGGroupFrame(fCanvasWindow->GetContainer(),"Display"); TGVerticalFrame* vf = new TGVerticalFrame(Group); hf = new TGHorizontalFrame(vf,500); { //TString icondir(gSystem->Getenv("$HKEVENTDISPLAY_ROOT/") ); TGPictureButton* b = 0; b = new TGPictureButton(hf, gClient->GetPicture("$HKEVENTDISPLAY_ROOT/eraser-icon-48.png")); b->SetToolTipText("Clear information about picked events from all event displays."); hf->AddFrame(b); b->Connect("Clicked()", "EvNavHandler", Navigator, "ClearOverlays()"); } vf->AddFrame(hf); hf = new TGHorizontalFrame(vf,500); { TGLayoutHints* LH = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY,5,5,3,4); TGLabel *label = new TGLabel(hf, "Unrolled Angle"); hf->AddFrame(label,LH); Navigator->fUnrolledViewAngleWidget = new TGNumberEntry(hf,0.01,4, 1,TGNumberFormat::kNESReal, TGNumberFormat::kNEAAnyNumber, TGNumberFormat::kNELLimitMinMax ,-9.0,9.00); Navigator->fUnrolledViewAngleWidget->Connect("ValueSet(Long_t)", "EvNavHandler", Navigator, "UnrolledEventAngleChanged()"); hf->AddFrame(Navigator->fUnrolledViewAngleWidget,LH); label = new TGLabel(hf, "Radians"); hf->AddFrame(label,LH); } vf->AddFrame(hf); Group->AddFrame(vf); fCanvasWindow->AddFrame(Group,hfHints); /* Control to set energy range for display of truth tracks */ Group = new TGGroupFrame(fCanvasWindow->GetContainer(),"Truth Track Display "); vf = new TGVerticalFrame(Group); hf = new TGHorizontalFrame(vf); { //"Minimum Energy" (MeV)" TGLayoutHints* LH = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY,5,5,3,4); TGLabel *label = new TGLabel(hf, "Minimum"); hf->AddFrame(label,LH); Navigator->fTruthTrackMinimumEnergyWidget = new TGNumberEntry(hf,minTruthTrackEnergyToDraw, 9, 1, TGNumberFormat::kNESReal, //style TGNumberFormat::kNEAPositive, //input value filter TGNumberFormat::kNELNoLimits, //specify limits 0.,10000.); Navigator->fTruthTrackMinimumEnergyWidget->Connect("ValueSet(Long_t)", "EvNavHandler", Navigator, "TruthTrackMinimumEnergyChanged()"); hf->AddFrame(Navigator->fTruthTrackMinimumEnergyWidget,LH); label = new TGLabel(hf, "MeV"); hf->AddFrame(label,LH); vf->AddFrame(hf); hf = new TGHorizontalFrame(vf); { TGCheckButton* fDrawTruthCones = new TGCheckButton(hf, "Draw True Cherenkov Light Cones.",1); fDrawTruthCones->SetState(kButtonDown); fDrawTruthCones->SetToolTipText("If this is checked true cherenkove light cones are drawn."); fDrawTruthCones->Connect("Toggled(Bool_t)", "EvNavHandler", Navigator, "DrawTruthConesChanged(Bool_t)"); //fDrawTruthCones->Connect("Toggled(Bool_t)", "EvNavHandler", Navigator, "ColourIsTimeBoxChanged(Bool_t)"); hf->AddFrame(fDrawTruthCones); } vf->AddFrame(hf); // "(MeV" } Group->AddFrame(vf); fCanvasWindow->AddFrame(Group,hfHints); } frmMain->AddFrame(fCanvasWindow,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 0, 0, 20, 20)); frmMain->MapSubwindows(); frmMain->Resize(); frmMain->MapWindow(); browser->StopEmbedding(); browser->SetTabTitle("Event Control", 0); /* Set up color palette object */ gStyle->SetPalette(fPredefinedPalette ,0); fHitPalette = new TEveRGBAPalette(0, 10000); fHitPalette->SetFixColorRange(kFALSE); fHitPalette->SetUnderflowAction( TEveRGBAPalette::kLA_Clip); fHitPalette->SetOverflowAction( TEveRGBAPalette::kLA_Clip); fHitPalette->SetupColorArray(); /* Create palette overlay once */ TEveRGBAPaletteOverlay* fPalletteOverlay =new TEveRGBAPaletteOverlay(fHitPalette, 0.7, 0.05, 0.3, 0.02); gEve->GetDefaultGLViewer()->AddOverlayElement(fPalletteOverlay); fPaletteTitle = new TGLAnnotation(gEve->GetDefaultGLViewer(),paletteText(), 0.7+(0.3/2.0)-0.05, 0.05+0.02+0.04); fPaletteTitle->SetState(TGLOverlayElement::kDisabled); fHitPalette->IncRefCount(); fHitPalette->IncRefCount(); gEve->GetBrowser()->GetTabRight()->SetTab(0); /* Create unrolled 2D scene and geometry and view */ UnrolledScene = gEve->SpawnNewScene("Unrolled Event"); flatGeometryScene = gEve->SpawnNewScene("Unrolled Geometry"); UnrolledView = New2dView("Unrolled View",TGLViewer::kCameraOrthoXnOY,UnrolledScene); flatGeometryScene->AddElement(FlatGeometry); UnrolledView->AddScene(flatGeometryScene); TEveSceneInfo* gSI= (TEveSceneInfo*) (UnrolledView->FindChild("SI - Geometry scene")); if(gSI!=NULL)gSI->Delete(); auto UGLV=UnrolledView->GetGLViewer(); UGLV->AddOverlayElement(fPalletteOverlay); fPaletteTitle2 = new TGLAnnotation(UGLV,paletteText(), 0.7+(0.3/2.0)-0.05, 0.05+0.02+0.04); fHitPalette->SetInterpolate(kTRUE); fHitPalette->SetupColorArray(); fHitPalette->IncRefCount(); fHitPalette->IncRefCount(); /*` ` set `up picking, connect viewer onClicke events to Picker object ` */ TGLViewer* GLViewer =gEve->GetDefaultViewer()->GetGLViewer(); fHKEVInfo = new HKEVInfo(GLViewer,0.0,0.99); fHKEVInfo->SetPermanent(" HyperK Event Display"); fPicker= new Picker(fHKEVInfo); GLViewer->Connect("Clicked(TObject*)", "Picker", fPicker, "Picked(TObject*)"); // also setup picking for 2D fHKEVInfo2D = new HKEVInfo(UGLV,0.0,0.99); fHKEVInfo2D->SetPermanent(" HyperK Event Display"); fPicker2D= new Picker(fHKEVInfo2D); UGLV->Connect("Clicked(TObject*)", "Picker", fPicker2D, "Picked(TObject*)"); }