Fork me on GitHub

source: git/examples/geometry.C@ 115298d

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

Working classes for automatic parsing of branches

Slightly less elegant, but it works.
The code in geometry.C is able to call the new methods and classes but
doesn't use it yet.

  • Property mode set to 100644
File size: 43.5 KB
Line 
1#include <set>
2#include <map>
3#include <utility>
4#include <vector>
5#include <algorithm>
6#include <sstream>
7#include <exception>
8#include "TGeoManager.h"
9#include "TGeoVolume.h"
10#include "TGeoMedium.h"
11#include "TGeoNode.h"
12#include "TGeoCompositeShape.h"
13#include "TGeoMatrix.h"
14#include "TGeoTube.h"
15#include "TGeoCone.h"
16#include "TGeoArb8.h"
17//#include "external/ExRootAnalysis/ExRootConfReader.h"
18//#include "external/ExRootAnalysis/ExRootTreeReader.h"
19//#include "display/DelphesCaloData.h"
20//#include "display/DelphesDisplay.h"
21//#include "display/DelphesBranchElement.h"
22//#include "classes/DelphesClasses.h"
23#include "TF2.h"
24#include "TH1F.h"
25#include "TChain.h"
26#include "TEveElement.h"
27#include "TEveJetCone.h"
28#include "TEveTrack.h"
29#include "TEveTrackPropagator.h"
30#include "TEveCalo.h"
31#include "TMath.h"
32#include "TSystem.h"
33#include "TEveManager.h"
34#include "TEveGeoNode.h"
35#include "TEveTrans.h"
36#include "TEveViewer.h"
37#include "TEveBrowser.h"
38#include "TRootBrowser.h"
39#include "TGLViewer.h"
40#include "TGButton.h"
41#include "TCollection.h"
42#include "TClonesArray.h"
43#include "TGLClip.h"
44#include "TEveArrow.h"
45
46/*
47 * assembly.C: sauvegarde as shape-extract -> implement in the geometry class (read/write)
48 * histobrowser.C: intégration d'histogrammes dans le display (on pourrait avoir Pt, eta, phi pour les principales collections)
49 * also from alice_esd: summary html table
50 *
51 */
52using namespace std;
53
54// Forward declarations.
55class Delphes3DGeometry;
56class ExRootTreeReader;
57class DelphesCaloData;
58class DelphesDisplay;
59class DelphesBranchBase;
60template<typename EveContainer> class DelphesBranchElement;
61void make_gui();
62void load_event();
63void delphes_read();
64void readConfig(const char *configFile, const Delphes3DGeometry& det3D, std::vector<DelphesBranchBase*>& elements, std::vector<TClonesArray*>& arrays);
65
66// Configuration and global variables.
67Int_t event_id = 0; // Current event id.
68Double_t gRadius = 1.29;
69Double_t gTotRadius = 2.0;
70Double_t gHalfLength = 3.0;
71Double_t gBz = 3.8;
72
73TAxis *gEtaAxis = 0;
74TAxis *gPhiAxis = 0;
75
76TChain gChain("Delphes");
77
78ExRootTreeReader *gTreeReader = 0;
79
80TClonesArray *gBranchTower = 0;
81TClonesArray *gBranchTrack = 0;
82TClonesArray *gBranchEle = 0;
83TClonesArray *gBranchMuon = 0;
84TClonesArray *gBranchPhoton = 0;
85TClonesArray *gBranchJet = 0;
86TClonesArray *gBranchGenJet = 0;
87TClonesArray *gBranchMet = 0;
88
89DelphesCaloData *gCaloData = 0;
90TEveElementList *gJetList = 0;
91TEveElementList *gGenJetList = 0;
92TEveElementList *gMetList = 0;
93TEveTrackList *gTrackList = 0;
94TEveTrackList *gElectronList = 0;
95TEveTrackList *gMuonList = 0;
96TEveTrackList *gPhotonList = 0;
97
98DelphesDisplay *gDelphesDisplay = 0;
99
100/******************************************************************************/
101// Construction of the geometry
102/******************************************************************************/
103
104// TODO: asymmetric detector
105
106class Delphes3DGeometry {
107 public:
108 Delphes3DGeometry(TGeoManager *geom = NULL);
109 ~Delphes3DGeometry() {}
110
111 void readFile(const char* filename, const char* ParticlePropagator="ParticlePropagator",
112 const char* TrackingEfficiency="ChargedHadronTrackingEfficiency",
113 const char* MuonEfficiency="MuonEfficiency",
114 const char* Calorimeters="Calorimeter");
115
116 void loadFromFile(const char* filename, const char* name="DelphesGeometry");
117 void save(const char* filename, const char* name="DelphesGeometry");
118
119 void setContingency(Double_t contingency) { contingency_ = contingency; }
120 void setCaloBarrelThickness(Double_t thickness) { calo_barrel_thickness_ = thickness; }
121 void setCaloEndcapThickness(Double_t thickness) { calo_endcap_thickness_ = thickness; }
122 void setMuonSystemThickness(Double_t thickness) { muonSystem_thickn_ = thickness; }
123
124 TGeoVolume* getDetector(bool withTowers = true);
125
126 Double_t getTrackerRadius() const { return tk_radius_; }
127 Double_t getDetectorRadius() const { return muonSystem_radius_; }
128 Double_t getTrackerHalfLength() const { return tk_length_; }
129 Double_t getDetectorHalfLength() const { return muonSystem_length_; }
130 Double_t getBField() const { return tk_Bz_; }
131 std::pair<TAxis*, TAxis*> getCaloAxes() { return std::make_pair(etaAxis_,phiAxis_); }
132
133 private:
134 std::pair<Double_t, Double_t> addTracker(TGeoVolume *top);
135 std::pair<Double_t, Double_t> addCalorimeter(TGeoVolume *top, const char* name, Double_t innerBarrelRadius, Double_t innerBarrelLength, set< pair<Double_t, Int_t> >& caloBinning);
136 std::pair<Double_t, Double_t> addMuonDets(TGeoVolume *top, const char* name, Double_t innerBarrelRadius, Double_t innerBarrelLength);
137 void addCaloTowers(TGeoVolume *top, const char* name, Double_t innerBarrelRadius, Double_t innerBarrelLength, set< pair<Double_t, Int_t> >& caloBinning);
138
139 private:
140
141 TGeoManager *geom_;
142
143 TGeoMedium *vacuum_;
144 TGeoMedium *tkmed_;
145 TGeoMedium *calomed_;
146 TGeoMedium *mudetmed_;
147
148 TAxis* etaAxis_;
149 TAxis* phiAxis_;
150
151 Double_t contingency_;
152 Double_t calo_barrel_thickness_;
153 Double_t calo_endcap_thickness_;
154 Double_t muonSystem_thickn_;
155 Double_t muonSystem_radius_;
156 Double_t muonSystem_length_;
157 Double_t tk_radius_;
158 Double_t tk_length_;
159 Double_t tk_etamax_;
160 Double_t tk_Bz_;
161
162 std::vector<std::string> calorimeters_;
163 std::vector<std::string> muondets_;
164
165 std::map<std::string, Double_t> muonSystem_etamax_;
166 std::map<std::string, set< pair<Double_t, Int_t> > > caloBinning_;
167
168};
169
170Delphes3DGeometry::Delphes3DGeometry(TGeoManager *geom) {
171
172 //--- the geometry manager
173 geom_ = geom==NULL? gGeoManager : geom;
174 //gGeoManager->DefaultColors();
175
176 //--- define some materials
177 TGeoMaterial *matVacuum = new TGeoMaterial("Vacuum", 0,0,0);
178 TGeoMaterial *matAl = new TGeoMaterial("Al", 26.98,13,2.7); // placeholder
179 //TODO: create different materials for different subdetectors???
180 matVacuum->SetTransparency(85); //TODO: tune
181 matAl->SetTransparency(85); //TODO: tune
182
183 //--- define some media
184 TGeoMedium *Vacuum = new TGeoMedium("Vacuum",1, matVacuum);
185 TGeoMedium *Al = new TGeoMedium("Root Material",2, matAl);
186 vacuum_ = Vacuum;
187 tkmed_ = Vacuum; // placeholder
188 calomed_ = Al; // placeholder
189 mudetmed_ = Al; // placeholder
190
191 // custom parameters
192 contingency_ = 10.;
193 calo_barrel_thickness_ = 50.;
194 calo_endcap_thickness_ = 75.;
195 muonSystem_thickn_ = 10.;
196
197 // read these parameters from the Delphes Card (with default values)
198 etaAxis_ = NULL;
199 phiAxis_ = NULL;
200 tk_radius_ = 120.;
201 tk_length_ = 150.;
202 tk_etamax_ = 3.0;
203 tk_Bz_ = 1.;
204 muonSystem_radius_ = 200.;
205}
206
207void Delphes3DGeometry::readFile(const char *configFile,
208 const char* ParticlePropagator, const char* TrackingEfficiency,
209 const char* MuonEfficiency, const char* Calorimeters) {
210
211 ExRootConfReader *confReader = new ExRootConfReader;
212 confReader->ReadFile(configFile);
213
214 tk_radius_ = confReader->GetDouble(Form("%s::Radius",ParticlePropagator), 1.0)*100.; // tk_radius
215 tk_length_ = confReader->GetDouble(Form("%s::HalfLength",ParticlePropagator), 3.0)*100.; // tk_length
216 tk_Bz_ = confReader->GetDouble("ParticlePropagator::Bz", 0.0); // tk_Bz
217
218 {
219 TString tkEffFormula = confReader->GetString(Form("%s::EfficiencyFormula",TrackingEfficiency),"abs(eta)<3.0");
220 tkEffFormula.ReplaceAll("pt","x");
221 tkEffFormula.ReplaceAll("eta","y");
222 tkEffFormula.ReplaceAll("phi","0.");
223 TF2* tkEffFunction = new TF2("tkEff",tkEffFormula,0,1000,-10,10);
224 TH1F etaHisto("eta","eta",100,5.,-5.);
225 Double_t pt,eta;
226 for(int i=0;i<1000;++i) {
227 tkEffFunction->GetRandom2(pt,eta);
228 etaHisto.Fill(eta);
229 }
230 Int_t bin = -1;
231 bin = etaHisto.FindFirstBinAbove(0.5);
232 Double_t etamin = (bin>-1) ? etaHisto.GetBinLowEdge(bin) : -10.;
233 bin = etaHisto.FindLastBinAbove(0.5);
234 Double_t etamax = (bin>-1) ? etaHisto.GetBinLowEdge(bin+1) : -10.;
235 tk_etamax_ = TMath::Max(fabs(etamin),fabs(etamax)); // tk_etamax
236 delete tkEffFunction;
237 }
238
239 {
240 muondets_.push_back("muons");
241 TString muonEffFormula = confReader->GetString(Form("%s::EfficiencyFormula",MuonEfficiency),"abs(eta)<2.0");
242 muonEffFormula.ReplaceAll("pt","x");
243 muonEffFormula.ReplaceAll("eta","y");
244 muonEffFormula.ReplaceAll("phi","0.");
245 TF2* muEffFunction = new TF2("muEff",muonEffFormula,0,1000,-10,10);
246 TH1F etaHisto("eta2","eta2",100,5.,-5.);
247 Double_t pt,eta;
248 for(int i=0;i<1000;++i) {
249 muEffFunction->GetRandom2(pt,eta);
250 etaHisto.Fill(eta);
251 }
252 Int_t bin = -1;
253 bin = etaHisto.FindFirstBinAbove(0.5);
254 Double_t etamin = (bin>-1) ? etaHisto.GetBinLowEdge(bin) : -10.;
255 bin = etaHisto.FindLastBinAbove(0.5);
256 Double_t etamax = (bin>-1) ? etaHisto.GetBinLowEdge(bin+1) : -10.;
257 muonSystem_etamax_["muons"] = TMath::Max(fabs(etamin),fabs(etamax)); // muonSystem_etamax
258 delete muEffFunction;
259 }
260
261 std::string s(Calorimeters);
262 std::replace( s.begin(), s.end(), ',', ' ' );
263 std::istringstream stream( s );
264 std::string word;
265 while (stream >> word) calorimeters_.push_back(word);
266
267 caloBinning_.clear(); // calo binning
268 for(std::vector<std::string>::const_iterator calo=calorimeters_.begin();calo!=calorimeters_.end(); ++calo) {
269 set< pair<Double_t, Int_t> > caloBinning;
270 ExRootConfParam paramEtaBins, paramPhiBins;
271 ExRootConfParam param = confReader->GetParam(Form("%s::EtaPhiBins",calo->c_str()));
272 Int_t size = param.GetSize();
273 for(int i = 0; i < size/2; ++i) {
274 paramEtaBins = param[i*2];
275 paramPhiBins = param[i*2+1];
276 assert(paramEtaBins.GetSize()==1);
277 caloBinning.insert(std::make_pair(paramEtaBins[0].GetDouble(),paramPhiBins.GetSize()-1));
278 }
279 caloBinning_[*calo] = caloBinning;
280 }
281
282 set< pair<Double_t, Int_t> > caloBinning = caloBinning_[*calorimeters_.begin()];
283 Double_t *etaBins = new Double_t[caloBinning.size()]; // note that this is the eta binning of the first calo
284 unsigned int ii = 0;
285 for(set< pair<Double_t, Int_t> >::const_iterator itEtaSet = caloBinning.begin(); itEtaSet != caloBinning.end(); ++itEtaSet) {
286 etaBins[ii++] = itEtaSet->first;
287 }
288 etaAxis_ = new TAxis(caloBinning.size() - 1, etaBins);
289 phiAxis_ = new TAxis(72, -TMath::Pi(), TMath::Pi()); // note that this is fixed while #phibins could vary, also with eta, which doesn't seem possible in ROOT
290
291 muonSystem_radius_ = tk_radius_ + contingency_ + (contingency_+calo_barrel_thickness_)*calorimeters_.size() + muonSystem_thickn_;
292 muonSystem_length_ = tk_length_ + contingency_ + (contingency_+calo_endcap_thickness_)*calorimeters_.size() + muonSystem_thickn_;
293
294 delete confReader;
295
296}
297
298TGeoVolume* Delphes3DGeometry::getDetector(bool withTowers) {
299 // compute the envelope
300 Double_t system_radius = tk_radius_+calo_barrel_thickness_+3*contingency_;
301 Double_t system_length = tk_length_+contingency_+(contingency_+calo_endcap_thickness_)*calorimeters_.size()+contingency_;
302 // the detector volume
303 TGeoVolume *top = geom_->MakeBox("Delphes3DGeometry", vacuum_, system_radius, system_radius, system_length);
304 // build the detector
305 std::pair<Double_t, Double_t> limits = addTracker(top);
306 Double_t radius = limits.first;
307 Double_t length = limits.second;
308 for(std::vector<std::string>::const_iterator calo = calorimeters_.begin(); calo != calorimeters_.end(); ++calo) {
309 limits = addCalorimeter(top,calo->c_str(),radius,length,caloBinning_[*calo]);
310 if (withTowers) {
311 addCaloTowers(top,calo->c_str(),radius,length,caloBinning_[*calo]);
312 }
313 radius = limits.first;
314 length = limits.second;
315 }
316 for(std::vector<std::string>::const_iterator muon = muondets_.begin(); muon != muondets_.end(); ++muon) {
317 limits = addMuonDets(top, muon->c_str(), radius, length);
318 radius = limits.first;
319 length = limits.second;
320 }
321 // return the result
322 return top;
323}
324
325std::pair<Double_t, Double_t> Delphes3DGeometry::addTracker(TGeoVolume *top) {
326 // tracker: a cylinder with two cones substracted
327 new TGeoCone("forwardTkAcceptance",(tk_length_/2.+0.05),0.,tk_radius_,(tk_length_)*2.*exp(-tk_etamax_)/(1-exp(-2.*tk_etamax_)),tk_radius_);
328 TGeoTranslation *tr1 = new TGeoTranslation("tkacc1",0., 0., tk_length_/2.);
329 tr1->RegisterYourself();
330 TGeoRotation *negz = new TGeoRotation("tknegz",0,180,0);
331 negz->RegisterYourself();
332 TGeoCombiTrans *tr2 = new TGeoCombiTrans("tkacc2",0.,0.,-tk_length_/2.,negz);
333 tr2->RegisterYourself();
334 TGeoCompositeShape* tracker_cs = new TGeoCompositeShape("tracker_cs","forwardTkAcceptance:tkacc1+forwardTkAcceptance:tkacc2");
335 TGeoVolume *tracker = new TGeoVolume("tracker",tracker_cs,tkmed_);
336 tracker->SetLineColor(kYellow);
337 top->AddNode(tracker,1);
338 return std::make_pair(tk_radius_,tk_length_);
339}
340
341std::pair<Double_t, Double_t> Delphes3DGeometry::addCalorimeter(TGeoVolume *top, const char* name,
342 Double_t innerBarrelRadius, Double_t innerBarrelLength, set< pair<Double_t, Int_t> >& caloBinning) {
343 // parameters derived from the inputs
344 Double_t calo_endcap_etamax = TMath::Max(fabs(caloBinning.begin()->first),fabs(caloBinning.rbegin()->first));
345 Double_t calo_barrel_innerRadius = innerBarrelRadius+contingency_;
346 Double_t calo_barrel_length = innerBarrelLength + calo_barrel_thickness_;
347 Double_t calo_endcap_etamin = -log(innerBarrelRadius/(2*innerBarrelLength));
348 Double_t calo_endcap_innerRadius1 = innerBarrelLength*2.*exp(-calo_endcap_etamax)/(1-exp(-2.*calo_endcap_etamax));
349 Double_t calo_endcap_innerRadius2 = (innerBarrelLength+calo_endcap_thickness_)*2.*exp(-calo_endcap_etamax)/(1-exp(-2.*calo_endcap_etamax));
350 Double_t calo_endcap_outerRadius1 = innerBarrelRadius;
351 Double_t calo_endcap_outerRadius2 = innerBarrelRadius+calo_barrel_thickness_;
352 Double_t calo_endcap_coneThickness = TMath::Min(calo_barrel_thickness_ * (1-exp(-2.*calo_endcap_etamin)) / (2.*exp(-calo_endcap_etamin)), calo_endcap_thickness_);
353 Double_t calo_endcap_diskThickness = TMath::Max(0.,calo_endcap_thickness_-calo_endcap_coneThickness);
354
355 // calorimeters: tube truncated in eta + cones
356 new TGeoTube(Form("%s_barrel_cylinder",name),calo_barrel_innerRadius,calo_barrel_innerRadius+calo_barrel_thickness_,calo_barrel_length);
357 new TGeoCone(Form("%s_endcap_cone",name),calo_endcap_coneThickness/2.,calo_endcap_innerRadius1,calo_endcap_outerRadius1,calo_endcap_innerRadius2,calo_endcap_outerRadius2);
358 new TGeoTube(Form("%s_endcap_disk",name),calo_endcap_innerRadius2,tk_radius_+calo_barrel_thickness_,calo_endcap_diskThickness/2.);
359 TGeoTranslation *tr1 = new TGeoTranslation(Form("%s_tr1",name),0., 0., (calo_endcap_coneThickness+calo_endcap_diskThickness)/2.);
360 tr1->RegisterYourself();
361 TGeoCompositeShape *calo_endcap_cs = new TGeoCompositeShape(Form("%s_endcap_cs",name),Form("%s_endcap_cone+%s_endcap_disk:%s_tr1",name,name,name));
362 TGeoTranslation *trc1 = new TGeoTranslation(Form("%s_endcap1_position",name),0.,0., innerBarrelLength+calo_endcap_coneThickness/2.);
363 trc1->RegisterYourself();
364 TGeoRotation *negz = new TGeoRotation(Form("%s_negz",name),0,180,0);
365 TGeoCombiTrans *trc2 = new TGeoCombiTrans(Form("%s_endcap2_position",name),0.,0.,-(innerBarrelLength+calo_endcap_coneThickness/2.),negz);
366 trc2->RegisterYourself();
367 TGeoTranslation *trc1c = new TGeoTranslation(Form("%s_endcap1_position_cont",name),0.,0., innerBarrelLength+calo_endcap_coneThickness/2.+contingency_);
368 trc1c->RegisterYourself();
369 TGeoCombiTrans *trc2c = new TGeoCombiTrans(Form("%s_endcap2_position_cont",name),0.,0.,-(innerBarrelLength+calo_endcap_coneThickness/2.)-contingency_,negz);
370 trc2c->RegisterYourself();
371 TGeoVolume *calo_endcap = new TGeoVolume(Form("%s_endcap",name),calo_endcap_cs,calomed_);
372 TGeoCompositeShape *calo_barrel_cs = new TGeoCompositeShape(Form("%s_barrel_cs",name),
373 Form("%s_barrel_cylinder-%s_endcap_cs:%s_endcap1_position-%s_endcap_cs:%s_endcap2_position",name,name,name,name,name));
374 TGeoVolume *calo_barrel = new TGeoVolume(Form("%s_barrel",name),calo_barrel_cs,calomed_);
375 calo_endcap->SetLineColor(kViolet);
376 calo_endcap->SetFillColor(kViolet);
377 calo_barrel->SetLineColor(kRed);
378 top->AddNode(calo_endcap,1,trc1c);
379 top->AddNode(calo_endcap,2,trc2c);
380 top->AddNode(calo_barrel,1);
381 return std::make_pair(calo_barrel_innerRadius+calo_barrel_thickness_,innerBarrelLength+calo_endcap_thickness_+contingency_);
382}
383
384std::pair<Double_t, Double_t> Delphes3DGeometry::addMuonDets(TGeoVolume *top, const char* name, Double_t innerBarrelRadius, Double_t innerBarrelLength) {
385 // muon system: tube + disks
386 Double_t muonSystem_radius = innerBarrelRadius + contingency_;
387 Double_t muonSystem_length = innerBarrelLength + contingency_;
388 Double_t muonSystem_rmin = muonSystem_length*2.*exp(-muonSystem_etamax_[name])/(1-exp(-2.*muonSystem_etamax_[name]));
389 TGeoVolume *muon_barrel = geom_->MakeTube(Form("%s_barrel",name),mudetmed_,muonSystem_radius,muonSystem_radius+muonSystem_thickn_,muonSystem_length);
390 muon_barrel->SetLineColor(kBlue);
391 top->AddNode(muon_barrel,1);
392 TGeoVolume *muon_endcap = geom_->MakeTube(Form("%s_endcap",name),mudetmed_,muonSystem_rmin,muonSystem_radius+muonSystem_thickn_,muonSystem_thickn_/2.);
393 muon_endcap->SetLineColor(kBlue);
394 TGeoTranslation *trm1 = new TGeoTranslation(Form("%sEndcap1_position",name),0.,0.,muonSystem_length);
395 trm1->RegisterYourself();
396 TGeoTranslation *trm2 = new TGeoTranslation(Form("%sEndcap2_position",name),0.,0.,-muonSystem_length);
397 trm1->RegisterYourself();
398 top->AddNode(muon_endcap,1,trm1);
399 top->AddNode(muon_endcap,2,trm2);
400 return std::make_pair(muonSystem_radius,muonSystem_length);
401}
402
403void Delphes3DGeometry::addCaloTowers(TGeoVolume *top, const char* name,
404 Double_t innerBarrelRadius, Double_t innerBarrelLength, set< pair<Double_t, Int_t> >& caloBinning) {
405
406 TGeoVolume* calo_endcap = top->GetNode(Form("%s_endcap_1",name))->GetVolume();
407 TGeoVolume* calo_barrel = top->GetNode(Form("%s_barrel_1",name))->GetVolume();
408 Double_t calo_endcap_etamin = -log(innerBarrelRadius/(2*innerBarrelLength));
409 Double_t calo_endcap_coneThickness = TMath::Min(calo_barrel_thickness_ * (1-exp(-2.*calo_endcap_etamin)) / (2.*exp(-calo_endcap_etamin)), calo_endcap_thickness_);
410
411 // calo towers in the barrel
412 Double_t vertices[16] = {0.,0.,0.,0.,0.,0.,0.,0.}; // summit of the pyramid
413 Double_t R = tk_radius_ + contingency_+(contingency_+calo_barrel_thickness_)*calorimeters_.size(); // radius of the muons system = height of the pyramid
414 Int_t nEtaBins = caloBinning.size();
415 // this rotation is to make the tower point "up"
416 TGeoRotation* initTowerRot = new TGeoRotation(Form("%s_initTowerRot",name),0.,90.,0.);
417 TGeoCombiTrans* initTower = new TGeoCombiTrans(Form("%s_initTower",name),0.,-R/2.,0.,initTowerRot);
418 initTower->RegisterYourself();
419 // eta bins... we build one pyramid per eta slice and then translate it nphi times.
420 // phi bins represented by rotations around z
421 Double_t *y = new Double_t[nEtaBins];
422 Double_t *dx = new Double_t[nEtaBins];
423 Int_t *nphi = new Int_t[nEtaBins];
424 Int_t etaslice = 0;
425 std::map<std::pair<int,int>, TGeoRotation*> phirotations;
426 for(set< pair<Double_t, Int_t> >::const_iterator bin=caloBinning.begin(); bin!=caloBinning.end();++bin) {
427 if(abs(bin->first)>calo_endcap_etamin) continue; // only in the barrel
428 nphi[etaslice] = bin->second;
429 y[etaslice] = 0.5*R*(1-exp(-2*bin->first))/exp(-bin->first);
430 Double_t phiRotationAngle = 360./nphi[etaslice];
431 dx[etaslice] = R*tan(TMath::Pi()*phiRotationAngle/360.);
432 for(int phislice=0;phislice<nphi[etaslice];++phislice) {
433 phirotations[make_pair(etaslice,phislice)] = new TGeoRotation(Form("%s_phi%d_%d",name,etaslice,phislice),phiRotationAngle*phislice,0.,0.);
434 phirotations[make_pair(etaslice,phislice)]->RegisterYourself();
435 }
436 ++etaslice;
437 }
438 nEtaBins = etaslice;
439 for(int i=0;i<nEtaBins-1;++i) { // loop on the eta slices
440 vertices[8] = -dx[i]; vertices[9] = y[i];
441 vertices[10] = -dx[i]; vertices[11] = y[i+1];
442 vertices[12] = dx[i]; vertices[13] = y[i+1];
443 vertices[14] = dx[i]; vertices[15] = y[i];
444 new TGeoArb8(Form("%s_tower%d",name,i),R/2., vertices); // tower in the proper eta slice, at phi=0
445 // intersection between the tower and the calo_barrel
446 TGeoCompositeShape *finaltower_cs = new TGeoCompositeShape(Form("%s_ftower%d_cs",name,i),Form("%s_tower%d:%s_initTower*%s_barrel_cs",name,i,name,name));
447 TGeoVolume *finaltower = new TGeoVolume(Form("%s_ftower%d",name,i),finaltower_cs,calomed_);
448 finaltower->SetLineColor(kRed);
449 for(int j=0;j<nphi[i];++j) { // loop on the phi slices
450 calo_barrel->AddNode(finaltower,j,phirotations[make_pair(i,j)]);
451 }
452 }
453 delete[] y;
454 delete[] dx;
455 delete[] nphi;
456 //the towers in the forward region
457 R = tk_length_+contingency_+(contingency_+calo_endcap_thickness_)*calorimeters_.size(); // Z of the muons system = height of the pyramid
458 nEtaBins = caloBinning.size();
459 // translation to bring the origin of the tower to (0,0,0) (well, not really as the endcap is not yet in place)
460 TGeoTranslation* towerdz = new TGeoTranslation(Form("%s_towerdz",name),0.,0.,R/2.-(innerBarrelLength+calo_endcap_coneThickness/2.));
461 towerdz->RegisterYourself();
462 // eta bins... we build one pyramid per eta slice and then translate it nphi times.
463 Double_t *r = new Double_t[nEtaBins];
464 nphi = new Int_t[nEtaBins];
465 etaslice = 0;
466 phirotations.clear();
467 for(set< pair<Double_t, Int_t> >::const_iterator bin=caloBinning.begin(); bin!=caloBinning.end();++bin) {
468 if(bin->first<calo_endcap_etamin) continue; // only in the + endcap
469 r[etaslice] = R*2*exp(-bin->first)/(1-exp(-2*bin->first));
470 nphi[etaslice] = bin->second;
471 Double_t phiRotationAngle = 360./nphi[etaslice];
472 for(int phislice=0;phislice<nphi[etaslice];++phislice) {
473 phirotations[make_pair(etaslice,phislice)] = new TGeoRotation(Form("%s_forward_phi%d_%d",name,etaslice,phislice),phiRotationAngle*phislice,0.,0.);
474 phirotations[make_pair(etaslice,phislice)]->RegisterYourself();
475 }
476 ++etaslice;
477 }
478 nEtaBins = etaslice;
479 for(int i=0;i<nEtaBins-1;++i) { // loop on the eta slices
480 vertices[8] = -r[i+1]*sin(TMath::Pi()/nphi[i]); vertices[9] = r[i+1]*cos(TMath::Pi()/nphi[i]);
481 vertices[10] = -r[i]*sin(TMath::Pi()/nphi[i]); vertices[11] = r[i]*cos(TMath::Pi()/nphi[i]);
482 vertices[12] = r[i]*sin(TMath::Pi()/nphi[i]); vertices[13] = r[i]*cos(TMath::Pi()/nphi[i]);
483 vertices[14] = r[i+1]*sin(TMath::Pi()/nphi[i]); vertices[15] = r[i+1]*cos(TMath::Pi()/nphi[i]);
484 new TGeoArb8(Form("%sfwdtower%d",name,i),R/2., vertices); // tower in the proper eta slice, at phi=0
485 // intersection between the tower and the calo_endcap
486 TGeoCompositeShape *finalfwdtower_cs = new TGeoCompositeShape(Form("%sffwdtower%d_cs",name,i),Form("%sfwdtower%d:%s_towerdz*%s_endcap_cs",name,i,name,name));
487 TGeoVolume *finalfwdtower = new TGeoVolume(Form("%sffwdtower%d",name,i),finalfwdtower_cs,calomed_);
488 finalfwdtower->SetLineColor(kViolet);
489 for(int j=0;j<nphi[i];++j) { // loop on the phi slices
490 calo_endcap->AddNode(finalfwdtower,j,phirotations[make_pair(i,j)]);
491 }
492 }
493 delete[] r;
494 delete[] nphi;
495}
496
497/******************************************************************************/
498// Initialization and steering functions
499/******************************************************************************/
500
501// function that parses the config to extract the branches of interest and prepare containers
502void readConfig(const char *configFile, Delphes3DGeometry& det3D, std::vector<DelphesBranchBase*>& elements, std::vector<TClonesArray*>& arrays) {
503 ExRootConfReader *confReader = new ExRootConfReader;
504 confReader->ReadFile(configFile);
505 Double_t tk_radius = det3D.getTrackerRadius();
506 Double_t tk_length = det3D.getTrackerHalfLength();
507 Double_t tk_Bz = det3D.getBField();
508 Double_t mu_radius = det3D.getDetectorRadius();
509 Double_t mu_length = det3D.getDetectorHalfLength();
510 TAxis* etaAxis = det3D.getCaloAxes().first;
511 TAxis* phiAxis = det3D.getCaloAxes().second;
512 ExRootConfParam branches = confReader->GetParam("TreeWriter::Branch");
513 Int_t nBranches = branches.GetSize()/3;
514 DelphesBranchElement<TEveTrackList>* tlist;
515 DelphesBranchElement<DelphesCaloData>* clist;
516 DelphesBranchElement<TEveTrackList>* elist;
517 for(Int_t b = 0; b<nBranches; ++b) {
518 TString input = branches[b*3].GetString();
519 TString name = branches[b*3+1].GetString();
520 TString className = branches[b*3+2].GetString();
521 if(className=="Track") {
522 if(input.Contains("eflow",TString::kIgnoreCase) || name.Contains("eflow",TString::kIgnoreCase)) continue; //no eflow
523 elist = new DelphesBranchElement<TEveTrackList>(name,"track",kBlue);
524 elements.push_back(elist);
525 TEveTrackPropagator *trkProp = elist->GetContainer()->GetPropagator();
526 trkProp->SetMagField(0., 0., -tk_Bz);
527 trkProp->SetMaxR(tk_radius);
528 trkProp->SetMaxZ(tk_length);
529 } else if(className=="Tower") {
530 if(input.Contains("eflow",TString::kIgnoreCase) || name.Contains("eflow",TString::kIgnoreCase)) continue; //no eflow
531 clist = new DelphesBranchElement<DelphesCaloData>(name,"tower",kBlack);
532 clist->GetContainer()->SetEtaBins(etaAxis);
533 clist->GetContainer()->SetPhiBins(phiAxis);
534 elements.push_back(clist);
535 } else if(className=="Jet") {
536 if(input.Contains("GenJetFinder")) {
537 elist = new DelphesBranchElement<TEveElementList>(name,"jet",kCyan);
538 elist->GetContainer()->SetRnrSelf(false);
539 elist->GetContainer()->SetRnrChildren(false);
540 elements.push_back(elist);
541 } else {
542 elements.push_back(new DelphesBranchElement<TEveElementList>(name,"jet",kYellow));
543 }
544 } else if(className=="Electron") {
545 tlist = new DelphesBranchElement<TEveTrackList>(name,"track",kRed);
546 elements.push_back(tlist);
547 TEveTrackPropagator *trkProp = tlist->GetContainer()->GetPropagator();
548 trkProp->SetMagField(0., 0., -tk_Bz);
549 trkProp->SetMaxR(tk_radius);
550 trkProp->SetMaxZ(tk_length);
551 } else if(className=="Photon") {
552 tlist = new DelphesBranchElement<TEveTrackList>(name,"photon",kYellow);
553 elements.push_back(tlist);
554 TEveTrackPropagator *trkProp = tlist->GetContainer()->GetPropagator();
555 trkProp->SetMagField(0., 0., 0.);
556 trkProp->SetMaxR(tk_radius);
557 trkProp->SetMaxZ(tk_length);
558 } else if(className=="Muon") {
559 tlist = new DelphesBranchElement<TEveTrackList>(name,"track",kGreen);
560 elements.push_back(tlist);
561 TEveTrackPropagator *trkProp = tlist->GetContainer()->GetPropagator();
562 trkProp->SetMagField(0., 0., -tk_Bz);
563 trkProp->SetMaxR(mu_radius);
564 trkProp->SetMaxZ(mu_length);
565 } else if(className=="MissingET") {
566 elements.push_back(new DelphesBranchElement<TEveElementList>(name,"vector",kViolet));
567 } else if(className=="GenParticle") {
568 tlist = new DelphesBranchElement<TEveTrackList>(name,"track",kCyan);
569 elements.push_back(tlist);
570 tlist->GetContainer()->SetRnrSelf(false);
571 tlist->GetContainer()->SetRnrChildren(false);
572 TEveTrackPropagator *trkProp = tlist->GetContainer()->GetPropagator();
573 trkProp->SetMagField(0., 0., -tk_Bz);
574 trkProp->SetMaxR(tk_radius);
575 trkProp->SetMaxZ(tk_length);
576 }
577 arrays.push_back(gTreeReader->UseBranch(name));
578 }
579}
580
581void delphes_event_display(const char *configFile, const char *inputFile, Delphes3DGeometry& det3D)
582{
583
584 // initialize the application
585 TEveManager::Create(kTRUE, "IV");
586 TGeoManager* geom = gGeoManager;
587
588 // build the detector
589 gRadius = det3D.getTrackerRadius();
590 gTotRadius = det3D.getDetectorRadius();
591 gHalfLength = det3D.getTrackerHalfLength();
592 gBz = det3D.getBField();
593 gEtaAxis = det3D.getCaloAxes().first;
594 gPhiAxis = det3D.getCaloAxes().second;
595
596 //TODO specific to some classical detector... could use better the det3D
597 TGeoVolume* top = det3D.getDetector(false);
598 geom->SetTopVolume(top);
599 TEveElementList *geometry = new TEveElementList("Geometry");
600 TEveGeoTopNode* trk = new TEveGeoTopNode(gGeoManager, top->FindNode("tracker_1"));
601 trk->SetVisLevel(6);
602 geometry->AddElement(trk);
603 TEveGeoTopNode* calo = new TEveGeoTopNode(gGeoManager, top->FindNode("Calorimeter_barrel_1"));
604 calo->SetVisLevel(3);
605 geometry->AddElement(calo);
606 calo = new TEveGeoTopNode(gGeoManager, top->FindNode("Calorimeter_endcap_1"));
607 calo->SetVisLevel(3);
608 calo->UseNodeTrans();
609 geometry->AddElement(calo);
610 calo = new TEveGeoTopNode(gGeoManager, top->FindNode("Calorimeter_endcap_2"));
611 calo->SetVisLevel(3);
612 calo->UseNodeTrans();
613 geometry->AddElement(calo);
614 TEveGeoTopNode* muon = new TEveGeoTopNode(gGeoManager, top->FindNode("muons_barrel_1"));
615 muon->SetVisLevel(4);
616 geometry->AddElement(muon);
617 muon = new TEveGeoTopNode(gGeoManager, top->FindNode("muons_endcap_1"));
618 muon->SetVisLevel(4);
619 muon->UseNodeTrans();
620 geometry->AddElement(muon);
621 muon = new TEveGeoTopNode(gGeoManager, top->FindNode("muons_endcap_2"));
622 muon->SetVisLevel(4);
623 muon->UseNodeTrans();
624 geometry->AddElement(muon);
625 //gGeoManager->DefaultColors();
626
627 // Create chain of root trees
628 gChain.Add(inputFile);
629
630 // Create object of class ExRootTreeReader
631 printf("*** Opening Delphes data file ***\n");
632 gTreeReader = new ExRootTreeReader(&gChain);
633
634 // prepare data collections
635 std::vector<DelphesBranchBase*> elements;
636 std::vector<TClonesArray*> arrays;
637 readConfig(configFile, det3D, elements, arrays);
638 // Get pointers to branches
639 // TODO not needed. use arrays above.
640 gBranchTower = gTreeReader->UseBranch("Tower");
641 gBranchTrack = gTreeReader->UseBranch("Track");
642 gBranchEle = gTreeReader->UseBranch("Electron");
643 gBranchMuon = gTreeReader->UseBranch("Muon");
644 gBranchPhoton = gTreeReader->UseBranch("Photon");
645 gBranchJet = gTreeReader->UseBranch("Jet");
646 gBranchGenJet = gTreeReader->UseBranch("GenJet");
647 gBranchMet = gTreeReader->UseBranch("MissingET");
648
649 // data
650 // TODO not needed. use elements above
651 gCaloData = new DelphesCaloData(2);
652 gCaloData->RefSliceInfo(0).Setup("ECAL", 0.1, kRed);
653 gCaloData->RefSliceInfo(1).Setup("HCAL", 0.1, kBlue);
654 gCaloData->SetEtaBins(gEtaAxis);
655 gCaloData->SetPhiBins(gPhiAxis);
656 gCaloData->IncDenyDestroy();
657
658 gJetList = new TEveElementList("Jets");
659 gJetList->SetMainColor(kYellow);
660 gEve->AddElement(gJetList);
661
662 gGenJetList = new TEveElementList("GenJets");
663 gGenJetList->SetMainColor(kCyan);
664 gGenJetList->SetRnrSelf(false);
665 gGenJetList->SetRnrChildren(false);
666 gEve->AddElement(gGenJetList);
667
668 gMetList = new TEveElementList("Missing Et");
669 gMetList->SetMainColor(kViolet);
670 gEve->AddElement(gMetList);
671
672 TEveTrackPropagator *trkProp;
673
674 gElectronList = new TEveTrackList("Electrons");
675 gElectronList->SetMainColor(kRed);
676 gElectronList->SetMarkerColor(kViolet);
677 gElectronList->SetMarkerStyle(kCircle);
678 gElectronList->SetMarkerSize(0.5);
679 gEve->AddElement(gElectronList);
680 trkProp = gElectronList->GetPropagator();
681 trkProp->SetMagField(0.0, 0.0, -gBz);
682 trkProp->SetMaxR(gRadius);
683 trkProp->SetMaxZ(gHalfLength);
684
685 gMuonList = new TEveTrackList("Muons");
686 gMuonList->SetMainColor(kGreen);
687 gMuonList->SetMarkerColor(kViolet);
688 gMuonList->SetMarkerStyle(kCircle);
689 gMuonList->SetMarkerSize(0.5);
690 gEve->AddElement(gMuonList);
691 trkProp = gMuonList->GetPropagator();
692 trkProp->SetMagField(0.0, 0.0, -gBz);
693 trkProp->SetMaxR(gTotRadius);
694 trkProp->SetMaxZ(gHalfLength);
695
696 gTrackList = new TEveTrackList("Tracks");
697 gTrackList->SetMainColor(kBlue);
698 gTrackList->SetMarkerColor(kRed);
699 gTrackList->SetMarkerStyle(kCircle);
700 gTrackList->SetMarkerSize(0.5);
701 gEve->AddElement(gTrackList);
702 trkProp = gTrackList->GetPropagator();
703 trkProp->SetMagField(0.0, 0.0, -gBz);
704 trkProp->SetMaxR(gRadius);
705 trkProp->SetMaxZ(gHalfLength);
706
707 gPhotonList= new TEveTrackList("Photons");
708 gPhotonList->SetMainColor(kYellow);
709 gPhotonList->SetLineStyle(7);
710 gPhotonList->SetMarkerColor(kViolet);
711 gPhotonList->SetMarkerStyle(kCircle);
712 gPhotonList->SetMarkerSize(0.5);
713 gEve->AddElement(gPhotonList);
714 trkProp = gPhotonList->GetPropagator();
715 trkProp->SetMagField(0.0, 0.0, 0.0);
716 trkProp->SetMaxR(gRadius);
717 trkProp->SetMaxZ(gHalfLength);
718
719 // viewers and scenes
720
721 TEveCalo3D *calo3d = new TEveCalo3D(gCaloData);
722 calo3d->SetBarrelRadius(gRadius);
723 calo3d->SetEndCapPos(gHalfLength);
724
725 //gStyle->SetPalette(1, 0);
726 TEveCaloLego *lego = new TEveCaloLego(gCaloData);
727 lego->InitMainTrans();
728 lego->RefMainTrans().SetScale(TMath::TwoPi(), TMath::TwoPi(), TMath::Pi());
729 lego->SetAutoRebin(kFALSE);
730 lego->Set2DMode(TEveCaloLego::kValSizeOutline);
731
732 gDelphesDisplay = new DelphesDisplay;
733 gEve->AddGlobalElement(geometry);
734 gEve->AddGlobalElement(calo3d);
735 gDelphesDisplay->ImportGeomRPhi(geometry);
736 gDelphesDisplay->ImportCaloRPhi(calo3d);
737 gDelphesDisplay->ImportGeomRhoZ(geometry);
738 gDelphesDisplay->ImportCaloRhoZ(calo3d);
739 gDelphesDisplay->ImportCaloLego(lego);
740 gEve->Redraw3D(kTRUE);
741
742}
743
744//______________________________________________________________________________
745void load_event()
746{
747 // Load event specified in global event_id.
748 // The contents of previous event are removed.
749
750 printf("Loading event %d.\n", event_id);
751
752 gEve->GetViewers()->DeleteAnnotations();
753
754 //TODO use the elements vector and call Reset for all
755 if(gCaloData) gCaloData->ClearTowers();
756 if(gJetList) gJetList->DestroyElements();
757 if(gMetList) gMetList->DestroyElements();
758 if(gGenJetList) gGenJetList->DestroyElements();
759 if(gTrackList) gTrackList->DestroyElements();
760 if(gElectronList) gElectronList->DestroyElements();
761 if(gMuonList) gMuonList->DestroyElements();
762 if(gPhotonList) gPhotonList->DestroyElements();
763
764 delphes_read();
765
766 TEveElement* top = (TEveElement*)gEve->GetCurrentEvent();
767 gDelphesDisplay->DestroyEventRPhi();
768 gDelphesDisplay->ImportEventRPhi(top);
769 gDelphesDisplay->DestroyEventRhoZ();
770 gDelphesDisplay->ImportEventRhoZ(top);
771
772 //update_html_summary();
773
774 gEve->Redraw3D(kFALSE, kTRUE);
775}
776
777void delphes_read()
778{
779
780 //TODO use the existing arrays in std loop.
781 TIter itTower(gBranchTower);
782 TIter itTrack(gBranchTrack);
783 TIter itElectron(gBranchEle);
784 TIter itPhoton(gBranchPhoton);
785 TIter itMuon(gBranchMuon);
786 TIter itJet(gBranchJet);
787 TIter itGenJet(gBranchGenJet);
788 TIter itMet(gBranchMet);
789
790 Tower *tower;
791 Track *track;
792 Electron *electron;
793 Muon *muon;
794 Photon *photon;
795 Jet *jet;
796 MissingET *MET;
797
798 TEveJetCone *eveJetCone;
799 TEveTrack *eveTrack;
800 TEveArrow *eveMet;
801
802 Int_t counter;
803 Float_t maxPt = 0.;
804
805 TEveTrackPropagator *trkProp = gTrackList->GetPropagator();
806 TEveTrackPropagator *photProp = gPhotonList->GetPropagator();
807 if(event_id >= gTreeReader->GetEntries()) return;
808
809 // Load selected branches with data from specified event
810 gTreeReader->ReadEntry(event_id);
811
812
813 //TODO the code below should go in small methods.
814 //it's maybe time to convert that in a class.
815
816 // Loop over all towers
817 itTower.Reset();
818 while((tower = (Tower *) itTower.Next()))
819 {
820 gCaloData->AddTower(tower->Edges[0], tower->Edges[1], tower->Edges[2], tower->Edges[3]);
821 gCaloData->FillSlice(0, tower->Eem);
822 gCaloData->FillSlice(1, tower->Ehad);
823 }
824 gCaloData->DataChanged();
825
826 // Loop over all tracks
827 itTrack.Reset();
828 counter = 0;
829 while((track = (Track *) itTrack.Next())) {
830 TParticle pb(track->PID, 1, 0, 0, 0, 0,
831 track->P4().Px(), track->P4().Py(),
832 track->P4().Pz(), track->P4().E(),
833 track->X, track->Y, track->Z, 0.0);
834
835 eveTrack = new TEveTrack(&pb, counter, trkProp);
836 eveTrack->SetName(Form("%s [%d]", pb.GetName(), counter++));
837 eveTrack->SetStdTitle();
838 eveTrack->SetAttLineAttMarker(gTrackList);
839 gTrackList->AddElement(eveTrack);
840 eveTrack->SetLineColor(kBlue);
841 eveTrack->MakeTrack();
842 maxPt = maxPt > track->PT ? maxPt : track->PT;
843 }
844
845 // Loop over all electrons
846 itElectron.Reset();
847 counter = 0;
848 while((electron = (Electron *) itElectron.Next())) {
849 TParticle pb(electron->Charge<0?11:-11, 1, 0, 0, 0, 0,
850 electron->P4().Px(), electron->P4().Py(),
851 electron->P4().Pz(), electron->P4().E(),
852 0., 0., 0., 0.);
853
854 eveTrack = new TEveTrack(&pb, counter, trkProp);
855 eveTrack->SetName(Form("%s [%d]", pb.GetName(), counter++));
856 eveTrack->SetStdTitle();
857 eveTrack->SetAttLineAttMarker(gElectronList);
858 gElectronList->AddElement(eveTrack);
859 eveTrack->SetLineColor(kRed);
860 eveTrack->MakeTrack();
861 maxPt = maxPt > electron->PT ? maxPt : electron->PT;
862 }
863
864 // Loop over all photons
865 itPhoton.Reset();
866 counter = 0;
867 while((photon = (Photon *) itPhoton.Next())) {
868 TParticle pb(22, 1, 0, 0, 0, 0,
869 photon->P4().Px(), photon->P4().Py(),
870 photon->P4().Pz(), photon->P4().E(),
871 0., 0., 0., 0.);
872
873 eveTrack = new TEveTrack(&pb, counter, photProp);
874 eveTrack->SetName(Form("%s [%d]", pb.GetName(), counter++));
875 eveTrack->SetStdTitle();
876 eveTrack->SetAttLineAttMarker(gPhotonList);
877 gPhotonList->AddElement(eveTrack);
878 eveTrack->SetLineColor(kYellow);
879 eveTrack->MakeTrack();
880 maxPt = maxPt > photon->PT ? maxPt : photon->PT;
881 }
882
883 // Loop over all muons
884 itMuon.Reset();
885 counter = 0;
886 while((muon = (Muon *) itMuon.Next())) {
887 TParticle pb(muon->Charge<0?13:-13, 1, 0, 0, 0, 0,
888 muon->P4().Px(), muon->P4().Py(),
889 muon->P4().Pz(), muon->P4().E(),
890 0., 0., 0., 0.);
891
892 eveTrack = new TEveTrack(&pb, counter, trkProp);
893 eveTrack->SetName(Form("%s [%d]", pb.GetName(), counter++));
894 eveTrack->SetStdTitle();
895 eveTrack->SetAttLineAttMarker(gMuonList);
896 gMuonList->AddElement(eveTrack);
897 eveTrack->SetLineColor(kGreen);
898 eveTrack->MakeTrack();
899 maxPt = maxPt > muon->PT ? maxPt : muon->PT;
900 }
901
902 // Loop over all jets
903 itJet.Reset();
904 counter = 0;
905 while((jet = (Jet *) itJet.Next()))
906 {
907 eveJetCone = new TEveJetCone();
908 eveJetCone->SetTitle(Form("jet [%d]: Pt=%f, Eta=%f, \nPhi=%f, M=%f",counter,jet->PT, jet->Eta, jet->Phi, jet->Mass));
909 eveJetCone->SetName(Form("jet [%d]", counter++));
910 eveJetCone->SetMainTransparency(60);
911 eveJetCone->SetLineColor(kYellow);
912 eveJetCone->SetFillColor(kYellow);
913 eveJetCone->SetCylinder(gRadius - 10, gHalfLength - 10);
914 eveJetCone->SetPickable(kTRUE);
915 eveJetCone->AddEllipticCone(jet->Eta, jet->Phi, jet->DeltaEta, jet->DeltaPhi);
916 gJetList->AddElement(eveJetCone);
917 maxPt = maxPt > jet->PT ? maxPt : jet->PT;
918 }
919
920 // Loop over all genjets
921 itJet.Reset();
922 counter = 0;
923 while((jet = (Jet *) itGenJet.Next()))
924 {
925 eveJetCone = new TEveJetCone();
926 eveJetCone->SetTitle(Form("jet [%d]: Pt=%f, Eta=%f, \nPhi=%f, M=%f",counter,jet->PT, jet->Eta, jet->Phi, jet->Mass));
927 eveJetCone->SetName(Form("jet [%d]", counter++));
928 eveJetCone->SetMainTransparency(60);
929 eveJetCone->SetLineColor(kCyan);
930 eveJetCone->SetFillColor(kCyan);
931 eveJetCone->SetCylinder(gRadius - 10, gHalfLength - 10);
932 eveJetCone->SetPickable(kTRUE);
933 eveJetCone->AddEllipticCone(jet->Eta, jet->Phi, jet->DeltaEta, jet->DeltaPhi);
934 gGenJetList->AddElement(eveJetCone);
935 }
936
937 // Missing Et
938 // recipe: gRadius * MET/maxpt(tracks, jets)
939 itMet.Reset();
940 while((MET = (MissingET*) itMet.Next())) {
941 eveMet = new TEveArrow((gRadius * MET->MET/maxPt)*cos(MET->Phi), (gRadius * MET->MET/maxPt)*sin(MET->Phi), 0., 0., 0., 0.);
942 eveMet->SetMainColor(kViolet);
943 eveMet->SetTubeR(0.04);
944 eveMet->SetConeR(0.08);
945 eveMet->SetConeL(0.10);
946 eveMet->SetPickable(kTRUE);
947 eveMet->SetName("Missing Et");
948 eveMet->SetTitle(Form("Missing Et (%.1f GeV)",MET->MET));
949 gMetList->AddElement(eveMet);
950 }
951}
952
953
954/******************************************************************************/
955// GUI
956/******************************************************************************/
957
958//______________________________________________________________________________
959//
960// EvNavHandler class is needed to connect GUI signals.
961
962class EvNavHandler
963{
964public:
965 void Fwd()
966 {
967 if (event_id < gTreeReader->GetEntries() - 1) {
968 ++event_id;
969 load_event();
970 } else {
971 printf("Already at last event.\n");
972 }
973 }
974 void Bck()
975 {
976 if (event_id > 0) {
977 --event_id;
978 load_event();
979 } else {
980 printf("Already at first event.\n");
981 }
982 }
983};
984
985//______________________________________________________________________________
986void make_gui()
987{
988 // Create minimal GUI for event navigation.
989 // TODO: better GUI could be made based on the ch15 of the manual (Writing a GUI)
990
991 // add a tab on the left
992 TEveBrowser* browser = gEve->GetBrowser();
993 browser->StartEmbedding(TRootBrowser::kLeft);
994
995 // set the main title
996 TGMainFrame* frmMain = new TGMainFrame(gClient->GetRoot(), 1000, 600);
997 frmMain->SetWindowName("Delphes Event Display");
998 frmMain->SetCleanup(kDeepCleanup);
999
1000 // build the navigation menu
1001 TGHorizontalFrame* hf = new TGHorizontalFrame(frmMain);
1002 {
1003 TString icondir;
1004 if(gSystem->Getenv("ROOTSYS"))
1005 icondir = Form("%s/icons/", gSystem->Getenv("ROOTSYS"));
1006 if(!gSystem->OpenDirectory(icondir))
1007 icondir = Form("%s/icons/", (const char*)gSystem->GetFromPipe("root-config --etcdir") );
1008 TGPictureButton* b = 0;
1009 EvNavHandler *fh = new EvNavHandler;
1010
1011 b = new TGPictureButton(hf, gClient->GetPicture(icondir+"GoBack.gif"));
1012 hf->AddFrame(b);
1013 b->Connect("Clicked()", "EvNavHandler", fh, "Bck()");
1014
1015 b = new TGPictureButton(hf, gClient->GetPicture(icondir+"GoForward.gif"));
1016 hf->AddFrame(b);
1017 b->Connect("Clicked()", "EvNavHandler", fh, "Fwd()");
1018 }
1019 frmMain->AddFrame(hf);
1020 frmMain->MapSubwindows();
1021 frmMain->Resize();
1022 frmMain->MapWindow();
1023 browser->StopEmbedding();
1024 browser->SetTabTitle("Event Control", 0);
1025}
1026
1027/******************************************************************************/
1028// MAIN
1029/******************************************************************************/
1030
1031void geometry(const char* filename = "delphes_card_CMS.tcl", const char* ParticlePropagator="ParticlePropagator",
1032 const char* TrackingEfficiency="ChargedHadronTrackingEfficiency",
1033 const char* MuonEfficiency="MuonEfficiency",
1034 const char* Calorimeters="Calorimeter")
1035{
1036
1037 // load the libraries
1038 gSystem->Load("libGeom");
1039 gSystem->Load("../libDelphes");
1040 gSystem->Load("../libDelphesDisplay");
1041
1042 // create the detector representation
1043 Delphes3DGeometry det3D(new TGeoManager("delphes", "Delphes geometry"));
1044 det3D.readFile(filename, ParticlePropagator, TrackingEfficiency, MuonEfficiency, Calorimeters);
1045
1046 // create the application items
1047 delphes_event_display("delphes_card_CMS.tcl", "../delphes_output.root", det3D); //TODO root file as input cfg
1048 make_gui();
1049 load_event();
1050 gEve->Redraw3D(kTRUE); // Reset camera after the first event has been shown.
1051
1052 // EClipType not exported to CINT (see TGLUtil.h):
1053 // 0 - no clip, 1 - clip plane, 2 - clip box
1054 TGLViewer *v = gEve->GetDefaultGLViewer();
1055 //Double_t plane[4] = { 0., 1., 0., 0. };
1056 //v->GetClipSet()->SetClipState(1,plane);
1057 //v->GetClipSet()->SetClipType(1);
1058 //v->ColorSet().Background().SetColor(kMagenta+4);
1059 //v->SetGuideState(TGLUtil::kAxesEdge, kTRUE, kFALSE, 0);
1060 v->RefreshPadEditor(v);
1061 v->CurrentCamera().RotateRad(-1.2, 0.5);
1062 v->DoDraw();
1063
1064}
1065
Note: See TracBrowser for help on using the repository browser.