Fork me on GitHub

source: git/display/DelphesEventDisplay.cc@ 5fbcfe8

ImprovedOutputFile Timing dual_readout llp
Last change on this file since 5fbcfe8 was 5fbcfe8, checked in by Christophe Delaere <christophe.delaere@…>, 10 years ago

First introduction of the HTML summary tab

At this stage, I did the bare minimum required to add one tab after
copy/pasting the ROOT example. Right now, it just adds a white page.

  • Property mode set to 100644
File size: 11.6 KB
RevLine 
[369744d]1/*
2 * Delphes: a framework for fast simulation of a generic collider experiment
3 * Copyright (C) 2012-2014 Universite catholique de Louvain (UCL), Belgium
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
[cfc3160]19#include <cassert>
[84dd1c8]20#include <iostream>
[cfc3160]21#include <utility>
22#include <algorithm>
23#include "TGeoManager.h"
24#include "TGeoVolume.h"
25#include "external/ExRootAnalysis/ExRootConfReader.h"
26#include "external/ExRootAnalysis/ExRootTreeReader.h"
27#include "display/DelphesCaloData.h"
28#include "display/DelphesBranchElement.h"
29#include "display/Delphes3DGeometry.h"
30#include "display/DelphesEventDisplay.h"
31#include "classes/DelphesClasses.h"
32#include "TEveElement.h"
33#include "TEveJetCone.h"
34#include "TEveTrack.h"
35#include "TEveTrackPropagator.h"
36#include "TEveCalo.h"
37#include "TEveManager.h"
38#include "TEveGeoNode.h"
39#include "TEveTrans.h"
40#include "TEveViewer.h"
41#include "TEveBrowser.h"
42#include "TEveArrow.h"
43#include "TMath.h"
44#include "TSystem.h"
45#include "TRootBrowser.h"
46#include "TGButton.h"
47#include "TClonesArray.h"
48
49DelphesEventDisplay::DelphesEventDisplay()
50{
[fafc433]51 event_id_ = 0;
[cfc3160]52 tkRadius_ = 1.29;
53 totRadius_ = 2.0;
54 tkHalfLength_ = 3.0;
[4fd37d4]55 muHalfLength_ = 6.0;
[cfc3160]56 bz_ = 3.8;
57 chain_ = new TChain("Delphes");
[fafc433]58 treeReader_ = 0;
59 delphesDisplay_ = 0;
[4fd37d4]60 etaAxis_ = 0;
61 phiAxis_ = 0;
[cfc3160]62}
63
64DelphesEventDisplay::~DelphesEventDisplay()
65{
66 delete chain_;
67}
68
69DelphesEventDisplay::DelphesEventDisplay(const char *configFile, const char *inputFile, Delphes3DGeometry& det3D)
70{
[fafc433]71 event_id_ = 0;
[cfc3160]72 tkRadius_ = 1.29;
73 totRadius_ = 2.0;
74 tkHalfLength_ = 3.0;
75 bz_ = 3.8;
76 chain_ = new TChain("Delphes");
[fafc433]77 treeReader_ = 0;
78 delphesDisplay_ = 0;
[cfc3160]79
80 // initialize the application
81 TEveManager::Create(kTRUE, "IV");
82 TGeoManager* geom = gGeoManager;
83
84 // build the detector
85 tkRadius_ = det3D.getTrackerRadius();
86 totRadius_ = det3D.getDetectorRadius();
87 tkHalfLength_ = det3D.getTrackerHalfLength();
[4fd37d4]88 muHalfLength_ = det3D.getDetectorHalfLength();
[cfc3160]89 bz_ = det3D.getBField();
[4fd37d4]90 etaAxis_ = det3D.getCaloAxes().first;
91 phiAxis_ = det3D.getCaloAxes().second;
[cfc3160]92 TGeoVolume* top = det3D.getDetector(false);
93 geom->SetTopVolume(top);
94 TEveElementList *geometry = new TEveElementList("Geometry");
[30bb83a]95 TObjArray* nodes = top->GetNodes();
96 TIter itNodes(nodes);
97 TGeoNode* nodeobj;
98 TEveGeoTopNode* node;
99 while((nodeobj = (TGeoNode*)itNodes.Next())) {
100 node = new TEveGeoTopNode(gGeoManager,nodeobj);
101 node->UseNodeTrans();
102 geometry->AddElement(node);
103 }
[cfc3160]104
105 // Create chain of root trees
106 chain_->Add(inputFile);
107
108 // Create object of class ExRootTreeReader
109 printf("*** Opening Delphes data file ***\n");
[fafc433]110 treeReader_ = new ExRootTreeReader(chain_);
[cfc3160]111
112 // prepare data collections
[4fd37d4]113 readConfig(configFile, elements_);
[fafc433]114 for(std::vector<DelphesBranchBase*>::iterator element = elements_.begin(); element<elements_.end(); ++element) {
[84dd1c8]115 DelphesBranchElement<TEveTrackList>* item_v1 = dynamic_cast<DelphesBranchElement<TEveTrackList>*>(*element);
[a3b2495]116 DelphesBranchElement<TEveElementList>* item_v2 = dynamic_cast<DelphesBranchElement<TEveElementList>*>(*element);
[84dd1c8]117 if(item_v1) gEve->AddElement(item_v1->GetContainer());
118 if(item_v2) gEve->AddElement(item_v2->GetContainer());
119 }
[cfc3160]120
121 // viewers and scenes
[fafc433]122 delphesDisplay_ = new DelphesDisplay;
[cfc3160]123 gEve->AddGlobalElement(geometry);
[fafc433]124 delphesDisplay_->ImportGeomRPhi(geometry);
125 delphesDisplay_->ImportGeomRhoZ(geometry);
[cfc3160]126 // find the first calo data and use that to initialize the calo display
[fafc433]127 for(std::vector<DelphesBranchBase*>::iterator data=elements_.begin();data<elements_.end();++data) {
[4fd37d4]128 if(TString((*data)->GetType())=="Tower") { // we could also use GetClassName()=="DelphesCaloData"
[cfc3160]129 DelphesCaloData* container = dynamic_cast<DelphesBranchElement<DelphesCaloData>*>((*data))->GetContainer();
130 assert(container);
131 TEveCalo3D *calo3d = new TEveCalo3D(container);
132 calo3d->SetBarrelRadius(tkRadius_);
133 calo3d->SetEndCapPos(tkHalfLength_);
134 gEve->AddGlobalElement(calo3d);
[fafc433]135 delphesDisplay_->ImportCaloRPhi(calo3d);
136 delphesDisplay_->ImportCaloRhoZ(calo3d);
[cfc3160]137 TEveCaloLego *lego = new TEveCaloLego(container);
138 lego->InitMainTrans();
139 lego->RefMainTrans().SetScale(TMath::TwoPi(), TMath::TwoPi(), TMath::Pi());
140 lego->SetAutoRebin(kFALSE);
141 lego->Set2DMode(TEveCaloLego::kValSizeOutline);
[fafc433]142 delphesDisplay_->ImportCaloLego(lego);
[cfc3160]143 break;
144 }
145 }
146
[5fbcfe8]147 // the GUI: control panel, summary tab
[fafc433]148 make_gui();
[5fbcfe8]149
150 //ready...
[fafc433]151 load_event();
[cfc3160]152 gEve->Redraw3D(kTRUE);
153
154}
[30bb83a]155
[cfc3160]156// function that parses the config to extract the branches of interest and prepare containers
[4fd37d4]157void DelphesEventDisplay::readConfig(const char *configFile, std::vector<DelphesBranchBase*>& elements) {
[cfc3160]158 ExRootConfReader *confReader = new ExRootConfReader;
159 confReader->ReadFile(configFile);
160 ExRootConfParam branches = confReader->GetParam("TreeWriter::Branch");
161 Int_t nBranches = branches.GetSize()/3;
162 DelphesBranchElement<TEveTrackList>* tlist;
163 DelphesBranchElement<DelphesCaloData>* clist;
164 DelphesBranchElement<TEveElementList>* elist;
[a3b2495]165 // first loop with all but tracks
[cfc3160]166 for(Int_t b = 0; b<nBranches; ++b) {
167 TString input = branches[b*3].GetString();
168 TString name = branches[b*3+1].GetString();
169 TString className = branches[b*3+2].GetString();
[a3b2495]170 if(className=="Tower") {
[cfc3160]171 if(input.Contains("eflow",TString::kIgnoreCase) || name.Contains("eflow",TString::kIgnoreCase)) continue; //no eflow
[4fd37d4]172 clist = new DelphesBranchElement<DelphesCaloData>(name,treeReader_->UseBranch(name),kBlack);
173 clist->GetContainer()->SetEtaBins(etaAxis_);
174 clist->GetContainer()->SetPhiBins(phiAxis_);
[cfc3160]175 elements.push_back(clist);
176 } else if(className=="Jet") {
177 if(input.Contains("GenJetFinder")) {
[4fd37d4]178 elist = new DelphesBranchElement<TEveElementList>(name,treeReader_->UseBranch(name),kCyan);
[cfc3160]179 elist->GetContainer()->SetRnrSelf(false);
180 elist->GetContainer()->SetRnrChildren(false);
[4fd37d4]181 elist->SetTrackingVolume(tkRadius_, tkHalfLength_, bz_);
[cfc3160]182 elements.push_back(elist);
183 } else {
[4fd37d4]184 elist = new DelphesBranchElement<TEveElementList>(name,treeReader_->UseBranch(name),kYellow);
185 elist->SetTrackingVolume(tkRadius_, tkHalfLength_, bz_);
186 elements.push_back(elist);
[cfc3160]187 }
188 } else if(className=="Electron") {
[4fd37d4]189 tlist = new DelphesBranchElement<TEveTrackList>(name,treeReader_->UseBranch(name),kRed);
190 tlist->SetTrackingVolume(tkRadius_, tkHalfLength_, bz_);
[cfc3160]191 elements.push_back(tlist);
192 } else if(className=="Photon") {
[4fd37d4]193 tlist = new DelphesBranchElement<TEveTrackList>(name,treeReader_->UseBranch(name),kYellow);
194 tlist->SetTrackingVolume(tkRadius_, tkHalfLength_, bz_);
[cfc3160]195 elements.push_back(tlist);
196 } else if(className=="Muon") {
[4fd37d4]197 tlist = new DelphesBranchElement<TEveTrackList>(name,treeReader_->UseBranch(name),kGreen);
198 tlist->SetTrackingVolume(totRadius_, muHalfLength_, bz_);
[cfc3160]199 elements.push_back(tlist);
200 } else if(className=="MissingET") {
[4fd37d4]201 elist = new DelphesBranchElement<TEveElementList>(name,treeReader_->UseBranch(name),kViolet);
202 elist->SetTrackingVolume(tkRadius_, tkHalfLength_, bz_);
203 elements.push_back(elist);
[cfc3160]204 } else if(className=="GenParticle") {
[4fd37d4]205 tlist = new DelphesBranchElement<TEveTrackList>(name,treeReader_->UseBranch(name),kCyan);
206 tlist->SetTrackingVolume(tkRadius_, tkHalfLength_, bz_);
[cfc3160]207 tlist->GetContainer()->SetRnrSelf(false);
208 tlist->GetContainer()->SetRnrChildren(false);
[4fd37d4]209 elements.push_back(tlist);
[a3b2495]210 } else {
211 continue;
[cfc3160]212 }
213 }
[a3b2495]214 // second loop for tracks
215 for(Int_t b = 0; b<nBranches; ++b) {
216 TString input = branches[b*3].GetString();
217 TString name = branches[b*3+1].GetString();
218 TString className = branches[b*3+2].GetString();
219 if(className=="Track") {
220 if(input.Contains("eflow",TString::kIgnoreCase) || name.Contains("eflow",TString::kIgnoreCase)) continue; //no eflow
[4fd37d4]221 tlist = new DelphesBranchElement<TEveTrackList>(name,treeReader_->UseBranch(name),kBlue);
222 tlist->SetTrackingVolume(tkRadius_, tkHalfLength_, bz_);
[a3b2495]223 elements.push_back(tlist);
224 }
225 }
[cfc3160]226}
227
228void DelphesEventDisplay::load_event()
229{
[fafc433]230 // Load event specified in global event_id_.
[cfc3160]231 // The contents of previous event are removed.
232
[30bb83a]233 // safety
234 if(event_id_ >= treeReader_->GetEntries() || event_id_<0 ) return;
235
[cfc3160]236 //TODO move this to the status bar ???
[fafc433]237 printf("Loading event %d.\n", event_id_);
[cfc3160]238
239 // clear the previous event
240 gEve->GetViewers()->DeleteAnnotations();
[fafc433]241 for(std::vector<DelphesBranchBase*>::iterator data=elements_.begin();data<elements_.end();++data) {
[cfc3160]242 (*data)->Reset();
243 }
244
[30bb83a]245 // Load selected branches with data from specified event
246 treeReader_->ReadEntry(event_id_);
[4fd37d4]247 for(std::vector<DelphesBranchBase*>::iterator data=elements_.begin();data<elements_.end();++data) {
248 (*data)->ReadBranch();
[30bb83a]249 }
[cfc3160]250
251 // update display
252 TEveElement* top = (TEveElement*)gEve->GetCurrentEvent();
[fafc433]253 delphesDisplay_->DestroyEventRPhi();
254 delphesDisplay_->ImportEventRPhi(top);
255 delphesDisplay_->DestroyEventRhoZ();
256 delphesDisplay_->ImportEventRhoZ(top);
[cfc3160]257 //update_html_summary();
258
[30bb83a]259 gEve->Redraw3D(kFALSE, kTRUE);
[cfc3160]260}
261
262/******************************************************************************/
263// GUI
264/******************************************************************************/
265
266void DelphesEventDisplay::make_gui()
267{
268 // Create minimal GUI for event navigation.
269 // TODO: better GUI could be made based on the ch15 of the manual (Writing a GUI)
270
271 // add a tab on the left
272 TEveBrowser* browser = gEve->GetBrowser();
273 browser->StartEmbedding(TRootBrowser::kLeft);
274
275 // set the main title
276 TGMainFrame* frmMain = new TGMainFrame(gClient->GetRoot(), 1000, 600);
277 frmMain->SetWindowName("Delphes Event Display");
278 frmMain->SetCleanup(kDeepCleanup);
279
280 // build the navigation menu
281 TGHorizontalFrame* hf = new TGHorizontalFrame(frmMain);
282 {
283 TString icondir;
284 if(gSystem->Getenv("ROOTSYS"))
285 icondir = Form("%s/icons/", gSystem->Getenv("ROOTSYS"));
286 if(!gSystem->OpenDirectory(icondir))
287 icondir = Form("%s/icons/", (const char*)gSystem->GetFromPipe("root-config --etcdir") );
288 TGPictureButton* b = 0;
289
290 b = new TGPictureButton(hf, gClient->GetPicture(icondir+"GoBack.gif"));
291 hf->AddFrame(b);
[fafc433]292 b->Connect("Clicked()", "DelphesEventDisplay", this, "Bck()");
[cfc3160]293
294 b = new TGPictureButton(hf, gClient->GetPicture(icondir+"GoForward.gif"));
295 hf->AddFrame(b);
[fafc433]296 b->Connect("Clicked()", "DelphesEventDisplay", this, "Fwd()");
[cfc3160]297 }
298 frmMain->AddFrame(hf);
299 frmMain->MapSubwindows();
300 frmMain->Resize();
301 frmMain->MapWindow();
302 browser->StopEmbedding();
303 browser->SetTabTitle("Event Control", 0);
[5fbcfe8]304
305 // the summary tab
306 htmlSummary_ = new DelphesHtmlSummary("Delphes Event Display Summary Table");
307 TEveWindowSlot* slot = TEveWindow::CreateWindowInTab(gEve->GetBrowser()->GetTabRight());
308 gHtml_ = new TGHtml(0, 100, 100);
309 TEveWindowFrame *wf = slot->MakeFrame(gHtml_);
310 gHtml_->MapSubwindows();
311 wf->SetElementName("Summary");
312
[cfc3160]313}
314
Note: See TracBrowser for help on using the repository browser.