Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
run_alice_esd_split.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_eve
3/// Complex example showing ALICE ESD visualization in several views.
4/// alice_esd_split.C - a simple event-display for ALICE ESD tracks and clusters
5/// version with several windows in the same workspace
6///
7///
8/// Only standard ROOT is used to process the ALICE ESD files.
9///
10/// No ALICE code is needed, only four simple coordinate-transformation
11/// functions declared in this macro.
12///
13/// A simple geometry of 10KB, extracted from the full TGeo-geometry, is
14/// used to outline the central detectors of ALICE.
15///
16/// All files are access from the web by using the "CACHEREAD" option.
17///
18///
19/// ### Automatic building of ALICE ESD class declarations and dictionaries.
20///
21/// ALICE ESD is a TTree containing tracks and other event-related
22/// information with one entry per event. All these classes are part of
23/// the AliROOT offline framework and are not available to standard
24/// ROOT.
25///
26/// To be able to access the event data in a natural way, by using
27/// data-members of classes and object containers, the header files and
28/// class dictionaries are automatically generated from the
29/// TStreamerInfo classes stored in the ESD file by using the
30/// TFile::MakeProject() function. The header files and a shared library
31/// is created in the aliesd/ directory and can be loaded dynamically
32/// into the ROOT session.
33///
34/// See the run_alice_esd.C macro.
35///
36///
37/// ### Creation of simple GUI for event navigation.
38///
39/// Most common use of the event-display is to browse through a
40/// collection of events. Thus a simple GUI allowing this is created in
41/// the function make_gui().
42///
43/// Eve uses the configurable ROOT-browser as its main window and so we
44/// create an extra tab in the left working area of the browser and
45/// provide backward/forward buttons.
46///
47///
48/// ### Event-navigation functions.
49///
50/// As this is a simple macro, we store the information about the
51/// current event in the global variable 'Int_t esd_event_id'. The
52/// functions for event-navigation simply modify this variable and call
53/// the load_event() function which does the following:
54/// 1. drop the old visualization objects;
55/// 2. retrieve given event from the ESD tree;
56/// 3. call alice_esd_read() function to create visualization objects
57/// for the new event.
58///
59///
60/// ### Reading of ALICE data and creation of visualization objects.
61///
62/// This is performed in alice_esd_read() function, with the following
63/// steps:
64/// 1. create the track container object - TEveTrackList;
65/// 2. iterate over the ESD tracks, create TEveTrack objects and append
66/// them to the container;
67/// 3. instruct the container to extrapolate the tracks and set their
68/// visual attributes.
69///
70/// \image html eve_alice_esd_split.png
71/// \macro_code
72///
73/// \author Bertrand Bellenot
74
76#include "aliesd/AliESDEvent.h"
77#include "aliesd/AliESDRun.h"
78#include "aliesd/AliESDtrack.h"
79
83
84class AliESDEvent;
85class AliESDfriend;
86class AliESDtrack;
88
89void make_gui();
90void load_event();
92
93void alice_esd_read();
99
100// Configuration and global variables.
101
102const char *esd_file_name = "http://root.cern.ch/files/alice_ESDs.root";
103const char *esd_friends_file_name = "http://root.cern.ch/files/alice_ESDfriends.root";
104const char *esd_geom_file_name = "http://root.cern.ch/files/alice_ESDgeometry.root";
105
106TFile *esd_file = nullptr;
107TFile *esd_friends_file = nullptr;
108
109TTree *esd_tree = nullptr;
110
111AliESDEvent *esd = nullptr;
112AliESDfriend *esd_friend = nullptr;
113
114Int_t esd_event_id = 0; // Current event id.
115
116TEveTrackList *track_list = nullptr;
117
118TGTextEntry *gTextEntry = nullptr;
119TGHProgressBar *gProgress = nullptr;
120
121/******************************************************************************/
122// Initialization and steering functions
123/******************************************************************************/
124
125//______________________________________________________________________________
127{
128 // Main function, initializes the application.
129 //
130 // 1. Load the auto-generated library holding ESD classes and ESD dictionaries.
131 // 2. Open ESD data-files.
132 // 3. Load cartoon geometry.
133 // 4. Spawn simple GUI.
134 // 5. Load first event.
135
137
138 printf("*** Opening ESD ***\n");
139 esd_file = TFile::Open(esd_file_name, "CACHEREAD");
140 if (!esd_file)
141 return;
142
143 printf("*** Opening ESD-friends ***\n");
145 if (!esd_friends_file)
146 return;
147
148 esd_tree = (TTree *)esd_file->Get("esdTree");
149
150 esd = (AliESDEvent *)esd_tree->GetUserInfo()->FindObject("AliESDEvent");
151
152 // Set the branch addresses.
153 {
154 TIter next(esd->fESDObjects);
155 TObject *el;
156 while ((el = (TNamed *)next())) {
157 TString bname(el->GetName());
158 if (bname.CompareTo("AliESDfriend") == 0) {
159 // AliESDfriend needs some '.' magick.
160 esd_tree->SetBranchAddress("ESDfriend.", esd->fESDObjects->GetObjectRef(el));
161 } else {
162 esd_tree->SetBranchAddress(bname, esd->fESDObjects->GetObjectRef(el));
163 }
164 }
165 }
166
168
169 // Adapt the main frame to the screen size...
170 if (auto_size) {
171 Int_t qq;
172 UInt_t ww, hh;
173 gVirtualX->GetWindowSize(gVirtualX->GetDefaultRootWindow(), qq, qq, ww, hh);
175 if (screen_ratio > 1.5) {
176 gEve->GetBrowser()->MoveResize(100, 50, ww - 300, hh - 100);
177 } else {
178 gEve->GetBrowser()->Move(50, 50);
179 }
180 }
181
182 { // Simple geometry
183 TFile *geom = TFile::Open(esd_geom_file_name, "CACHEREAD");
184 if (!geom)
185 return;
186 TEveGeoShapeExtract *gse = (TEveGeoShapeExtract *)geom->Get("Gentle");
188 geom->Close();
189 delete geom;
191 }
192
193 make_gui();
194
195 // import the geometry in the projection managers
196 if (gRPhiMgr) {
198 a->SetNdivisions(3);
199 gEve->GetScenes()->FindChild("R-Phi Projection")->AddElement(a);
200 gRPhiMgr->ImportElements(gGeoShape);
201 }
202 if (gRhoZMgr) {
204 a->SetNdivisions(3);
205 gEve->GetScenes()->FindChild("Rho-Z Projection")->AddElement(a);
206 gRhoZMgr->ImportElements(gGeoShape);
207 }
208
209 load_event();
210
212
213 gEve->Redraw3D(kTRUE); // Reset camera after the first event has been shown.
214}
215
216//______________________________________________________________________________
217void load_event()
218{
219 // Load event specified in global esd_event_id.
220 // The contents of previous event are removed.
221
222 printf("Loading event %d.\n", esd_event_id);
223 gTextEntry->SetTextColor(0xff0000);
224 gTextEntry->SetText(Form("Loading event %d...", esd_event_id));
226
227 if (track_list)
228 track_list->DestroyElements();
229
230 esd_tree->GetEntry(esd_event_id);
231
233
235 gTextEntry->SetTextColor((Pixel_t)0x000000);
236 gTextEntry->SetText(Form("Event %d loaded", esd_event_id));
237 gROOT->ProcessLine("SplitGLView::UpdateSummary()");
238}
239
240//______________________________________________________________________________
242{
243 // cleanup then import geometry and event
244 // in the projection managers
245
247 if (gRPhiMgr && top) {
248 gRPhiMgr->DestroyElements();
249 gRPhiMgr->ImportElements(gGeoShape);
250 gRPhiMgr->ImportElements(top);
251 }
252 if (gRhoZMgr && top) {
253 gRhoZMgr->DestroyElements();
254 gRhoZMgr->ImportElements(gGeoShape);
255 gRhoZMgr->ImportElements(top);
256 }
257}
258
259/******************************************************************************/
260// GUI
261/******************************************************************************/
262
263//______________________________________________________________________________
264//
265// EvNavHandler class is needed to connect GUI signals.
266
267class EvNavHandler {
268public:
269 void Fwd()
270 {
271 if (esd_event_id < esd_tree->GetEntries() - 1) {
272 ++esd_event_id;
273 load_event();
275 } else {
276 gTextEntry->SetTextColor(0xff0000);
277 gTextEntry->SetText("Already at last event");
278 printf("Already at last event.\n");
279 }
280 }
281 void Bck()
282 {
283 if (esd_event_id > 0) {
284 --esd_event_id;
285 load_event();
287 } else {
288 gTextEntry->SetTextColor(0xff0000);
289 gTextEntry->SetText("Already at first event");
290 printf("Already at first event.\n");
291 }
292 }
293};
294
295//______________________________________________________________________________
296void make_gui()
297{
298 // Create minimal GUI for event navigation.
299
300 gROOT->ProcessLine(".L SplitGLView.C+");
301
303
304 browser->ShowCloseTab(kFALSE);
305 browser->ExecPlugin("SplitGLView", 0, "new SplitGLView(gClient->GetRoot(), 600, 450, kTRUE)");
306 browser->ShowCloseTab(kTRUE);
307
308 browser->StartEmbedding(TRootBrowser::kLeft);
309
310 TGMainFrame *frmMain = new TGMainFrame(gClient->GetRoot(), 1000, 600);
311 frmMain->SetWindowName("XX GUI");
312 frmMain->SetCleanup(kDeepCleanup);
313
315 {
316
317 TString icondir(Form("%s/icons/", gSystem->Getenv("ROOTSYS")));
318 TGPictureButton *b = 0;
319 EvNavHandler *fh = new EvNavHandler;
320
321 b = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoBack.gif"));
322 hf->AddFrame(b, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 10, 2, 10, 10));
323 b->Connect("Clicked()", "EvNavHandler", fh, "Bck()");
324
325 b = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoForward.gif"));
326 hf->AddFrame(b, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 10, 10, 10));
327 b->Connect("Clicked()", "EvNavHandler", fh, "Fwd()");
328
330 gTextEntry->SetEnabled(kFALSE);
331 hf->AddFrame(gTextEntry, new TGLayoutHints(kLHintsLeft | kLHintsCenterY | kLHintsExpandX, 2, 10, 10, 10));
332 }
333 frmMain->AddFrame(hf, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 20, 0));
334
336 gProgress->ShowPosition(kTRUE, kFALSE, "%.0f tracks");
337 gProgress->SetBarColor("green");
338 frmMain->AddFrame(gProgress, new TGLayoutHints(kLHintsExpandX, 10, 10, 5, 5));
339
340 frmMain->MapSubwindows();
341 frmMain->Resize();
342 frmMain->MapWindow();
343
344 browser->StopEmbedding();
345 browser->SetTabTitle("Event Control", 0);
346}
347
348/******************************************************************************/
349// Code for reading AliESD and creating visualization objects
350/******************************************************************************/
351
352enum ESDTrackFlags {
353 kITSin = 0x0001,
354 kITSout = 0x0002,
355 kITSrefit = 0x0004,
356 kITSpid = 0x0008,
357 kTPCin = 0x0010,
358 kTPCout = 0x0020,
359 kTPCrefit = 0x0040,
360 kTPCpid = 0x0080,
361 kTRDin = 0x0100,
362 kTRDout = 0x0200,
363 kTRDrefit = 0x0400,
364 kTRDpid = 0x0800,
365 kTOFin = 0x1000,
366 kTOFout = 0x2000,
367 kTOFrefit = 0x4000,
368 kTOFpid = 0x8000,
369 kHMPIDpid = 0x20000,
370 kEMCALmatch = 0x40000,
371 kTRDbackup = 0x80000,
372 kTRDStop = 0x20000000,
373 kESDpid = 0x40000000,
374 kTIME = 0x80000000
375};
376
377//______________________________________________________________________________
378void alice_esd_read()
379{
380 // Read tracks and associated clusters from current event.
381
382 AliESDRun *esdrun = (AliESDRun *)esd->fESDObjects->FindObject("AliESDRun");
383 TClonesArray *tracks = (TClonesArray *)esd->fESDObjects->FindObject("Tracks");
384
385 // This needs further investigation. Clusters not shown.
386 // AliESDfriend *frnd = (AliESDfriend*) esd->fESDObjects->FindObject("AliESDfriend");
387 // printf("Friend %p, n_tracks:%d\n", frnd, frnd->fTracks.GetEntries());
388
389 if (track_list == 0) {
390 track_list = new TEveTrackList("ESD Tracks");
391 track_list->SetMainColor(6);
392 // track_list->SetLineWidth(2);
393 track_list->SetMarkerColor(kYellow);
394 track_list->SetMarkerStyle(4);
395 track_list->SetMarkerSize(0.5);
396
398 }
399
400 TEveTrackPropagator *trkProp = track_list->GetPropagator();
401 trkProp->SetMagField(0.1 * esdrun->fMagneticField); // kGaus to Tesla
402
403 gProgress->Reset();
404 gProgress->SetMax(tracks->GetEntriesFast());
405 for (Int_t n = 0; n < tracks->GetEntriesFast(); ++n) {
406 AliESDtrack *at = (AliESDtrack *)tracks->At(n);
407
408 // If ITS refit failed, take track parameters at inner TPC radius.
410 if (!trackIsOn(at, kITSrefit)) {
411 tp = at->fIp;
412 }
413
415 track->SetAttLineAttMarker(track_list);
416 track_list->AddElement(track);
417
418 // This needs further investigation. Clusters not shown.
419 // if (frnd)
420 // {
421 // AliESDfriendTrack* ft = (AliESDfriendTrack*) frnd->fTracks->At(n);
422 // printf("%d friend = %p\n", ft);
423 // }
424 gProgress->Increment(1);
425 }
426
427 track_list->MakeTracks();
428}
429
430//______________________________________________________________________________
432{
433 // Helper function creating TEveTrack from AliESDtrack.
434 //
435 // Optionally specific track-parameters (e.g. at TPC entry point)
436 // can be specified via the tp argument.
437
438 Double_t pbuf[3], vbuf[3];
440
441 if (tp == 0)
442 tp = at;
443
444 rt.fLabel = at->fLabel;
445 rt.fIndex = index;
446 rt.fStatus = (Int_t)at->fFlags;
447 rt.fSign = (tp->fP[4] > 0) ? 1 : -1;
448
450 rt.fV.Set(vbuf);
452 rt.fP.Set(pbuf);
453
454 Double_t ep = trackGetP(at);
455 Double_t mc = 0.138; // at->GetMass(); - Complicated function, requiring PID.
456
457 rt.fBeta = ep / TMath::Sqrt(ep * ep + mc * mc);
458
460 track->SetName(Form("TEveTrack %d", rt.fIndex));
461 track->SetStdTitle();
462
463 return track;
464}
465
466//______________________________________________________________________________
468{
469 // Check is track-flag specified by mask are set.
470
471 return (t->fFlags & mask) > 0;
472}
473
474//______________________________________________________________________________
476{
477 // Get global position of starting point of tp.
478
479 r[0] = tp->fX;
480 r[1] = tp->fP[0];
481 r[2] = tp->fP[1];
482
483 Double_t cs = TMath::Cos(tp->fAlpha), sn = TMath::Sin(tp->fAlpha), x = r[0];
484 r[0] = x * cs - r[1] * sn;
485 r[1] = x * sn + r[1] * cs;
486}
487
488//______________________________________________________________________________
490{
491 // Return global momentum vector of starting point of tp.
492
493 p[0] = tp->fP[4];
494 p[1] = tp->fP[2];
495 p[2] = tp->fP[3];
496
497 Double_t pt = 1. / TMath::Abs(p[0]);
498 Double_t cs = TMath::Cos(tp->fAlpha), sn = TMath::Sin(tp->fAlpha);
499 Double_t r = TMath::Sqrt(1 - p[1] * p[1]);
500 p[0] = pt * (r * cs - p[1] * sn);
501 p[1] = pt * (p[1] * cs + r * sn);
502 p[2] = pt * p[2];
503}
504
505//______________________________________________________________________________
507{
508 // Return magnitude of momentum of tp.
509
510 return TMath::Sqrt(1. + tp->fP[3] * tp->fP[3]) / TMath::Abs(tp->fP[4]);
511}
#define R__EXTERN
Definition DllImport.h:26
ULong_t Pixel_t
Pixel value.
Definition GuiTypes.h:40
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
double Double_t
Definition RtypesCore.h:59
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
@ kYellow
Definition Rtypes.h:66
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
R__EXTERN TEveManager * gEve
#define gClient
Definition TGClient.h:157
@ kDeepCleanup
Definition TGFrame.h:42
@ kLHintsLeft
Definition TGLayout.h:24
@ kLHintsCenterY
Definition TGLayout.h:28
@ kLHintsTop
Definition TGLayout.h:27
@ kLHintsExpandX
Definition TGLayout.h:30
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
#define gROOT
Definition TROOT.h:414
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
#define gVirtualX
Definition TVirtualX.h:337
An array of clone (identical) objects.
Specialization of TRootBrowser for Eve.
Base class for TEveUtil visualization elements, providing hierarchy management, rendering control and...
Definition TEveElement.h:36
virtual void AddElement(TEveElement *el)
Add el to the list of children.
TEveElement * FindChild(const TString &name, const TClass *cls=nullptr)
Find the first child with given name.
Globally positioned TGeoShape with rendering attributes and an optional list of daughter shape-extrac...
Wrapper for TGeoShape with absolute positioning and color attributes allowing display of extracted TG...
static TEveGeoShape * ImportShapeExtract(TEveGeoShapeExtract *gse, TEveElement *parent=nullptr)
Import a shape extract 'gse' under element 'parent'.
void AddElement(TEveElement *element, TEveElement *parent=nullptr)
Add an element.
void AddGlobalElement(TEveElement *element, TEveElement *parent=nullptr)
Add a global element, i.e.
TEveSceneList * GetScenes() const
TEveBrowser * GetBrowser() const
static TEveManager * Create(Bool_t map_window=kTRUE, Option_t *opt="FIV")
If global TEveManager* gEve is not set initialize it.
void Redraw3D(Bool_t resetCameras=kFALSE, Bool_t dropLogicals=kFALSE)
TEveEventManager * GetCurrentEvent() const
Axes for non-linear projections.
Manager class for steering of projections and managing projected objects.
A list of tracks supporting change of common attributes and selection based on track parameters.
Definition TEveTrack.h:140
Holding structure for a number of track rendering parameters.
Visual representation of a track.
Definition TEveTrack.h:33
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:131
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:4131
static Bool_t SetCacheFileDir(std::string_view cacheDir, Bool_t operateDisconnected=kTRUE, Bool_t forceCacheread=kFALSE)
Sets the directory where to locally stage/cache remote files.
Definition TFile.cxx:4674
void MoveResize(Int_t x, Int_t y, UInt_t w=0, UInt_t h=0) override
Move and/or resize the frame.
Definition TGFrame.cxx:629
void Move(Int_t x, Int_t y) override
Move frame.
Definition TGFrame.cxx:593
A composite frame that layout their children in horizontal way.
Definition TGFrame.h:387
This class describes layout hints used by the layout classes.
Definition TGLayout.h:50
Defines top level windows that interact with the system Window Manager.
Definition TGFrame.h:399
Yield an action as soon as it is clicked.
Definition TGButton.h:228
A TGTextEntry is a one line text input widget.
Definition TGTextEntry.h:24
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
Mother of all ROOT objects.
Definition TObject.h:41
Basic string class.
Definition TString.h:139
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1677
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition TSystem.cxx:416
A TTree represents a columnar dataset.
Definition TTree.h:84
TPaveText * pt
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:666
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:598
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:592
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
void tracks()
Definition tracks.C:48