Complex example showing ALICE ESD visualization in several views.
alice_esd_split.C - a simple event-display for ALICE ESD tracks and clusters version with several windows in the same workspace
Only standard ROOT is used to process the ALICE ESD files.
No ALICE code is needed, only four simple coordinate-transformation functions declared in this macro.
A simple geometry of 10KB, extracted from the full TGeo-geometry, is used to outline the central detectors of ALICE.
All files are access from the web by using the "CACHEREAD" option.
Automatic building of ALICE ESD class declarations and dictionaries.
ALICE ESD is a TTree containing tracks and other event-related information with one entry per event. All these classes are part of the AliROOT offline framework and are not available to standard ROOT.
To be able to access the event data in a natural way, by using data-members of classes and object containers, the header files and class dictionaries are automatically generated from the TStreamerInfo classes stored in the ESD file by using the TFile::MakeProject() function. The header files and a shared library is created in the aliesd/ directory and can be loaded dynamically into the ROOT session.
See the run_alice_esd.C macro.
Creation of simple GUI for event navigation.
Most common use of the event-display is to browse through a collection of events. Thus a simple GUI allowing this is created in the function make_gui().
Eve uses the configurable ROOT-browser as its main window and so we create an extra tab in the left working area of the browser and provide backward/forward buttons.
Event-navigation functions.
As this is a simple macro, we store the information about the current event in the global variable 'Int_t esd_event_id'. The functions for event-navigation simply modify this variable and call the load_event() function which does the following:
- drop the old visualization objects;
- retrieve given event from the ESD tree;
- call alice_esd_read() function to create visualization objects for the new event.
Reading of ALICE data and creation of visualization objects.
This is performed in alice_esd_read() function, with the following steps:
- create the track container object - TEveTrackList;
- iterate over the ESD tracks, create TEveTrack objects and append them to the container;
- instruct the container to extrapolate the tracks and set their visual attributes.
#ifndef __RUN_ALICE_ESD_SPLIT__
void alice_esd_split()
{
gROOT->LoadMacro(dir +
"SplitGLView.C+");
const char* esd_file_name = "http://root.cern.ch/files/alice_ESDs.root";
if (f == 0) return;
tree->SetBranchStatus (
"ESDfriend*", 1);
delete f;
}
gROOT->ProcessLine(
"#define __RUN_ALICE_ESD_SPLIT__ 1");
gROOT->ProcessLine(
"#include \"alice_esd_split.C\"");
gROOT->ProcessLine(
"run_alice_esd_split()");
gROOT->ProcessLine(
"#undef __RUN_ALICE_ESD_SPLIT__");
}
#else
class AliESDEvent;
class AliESDfriend;
class AliESDtrack;
class AliExternalTrackParam;
void make_gui();
void load_event();
void update_projections();
void alice_esd_read();
AliExternalTrackParam* tp=0);
void trackGetPos(AliExternalTrackParam* tp,
Double_t r[3]);
void trackGetMomentum(AliExternalTrackParam* tp,
Double_t p[3]);
Double_t trackGetP(AliExternalTrackParam* tp);
const char* esd_file_name = "http://root.cern.ch/files/alice_ESDs.root";
const char* esd_friends_file_name = "http://root.cern.ch/files/alice_ESDfriends.root";
const char* esd_geom_file_name = "http://root.cern.ch/files/alice_ESDgeometry.root";
TFile *esd_friends_file = 0;
AliESDEvent *esd = 0;
AliESDfriend *esd_friend = 0;
{
printf("*** Opening ESD ***\n");
if (!esd_file)
return;
printf("*** Opening ESD-friends ***\n");
esd_friends_file =
TFile::Open(esd_friends_file_name,
"CACHEREAD");
if (!esd_friends_file)
return;
esd_tree = (
TTree*) esd_file->
Get(
"esdTree");
{
TIter next(esd->fESDObjects);
{
if(bname.CompareTo("AliESDfriend")==0)
{
}
else
{
}
}
}
if (auto_size)
{
if (screen_ratio > 1.5) {
} else {
}
}
{
if (!geom)
return;
delete geom;
}
make_gui();
if (gRPhiMgr) {
gRPhiMgr->ImportElements(gGeoShape);
}
if (gRhoZMgr) {
gRhoZMgr->ImportElements(gGeoShape);
}
load_event();
update_projections();
}
void load_event()
{
printf("Loading event %d.\n", esd_event_id);
gTextEntry->
SetText(
Form(
"Loading event %d...",esd_event_id));
if (track_list)
alice_esd_read();
gTextEntry->
SetText(
Form(
"Event %d loaded",esd_event_id));
gROOT->ProcessLine(
"SplitGLView::UpdateSummary()");
}
void update_projections()
{
if (gRPhiMgr && top) {
gRPhiMgr->ImportElements(gGeoShape);
gRPhiMgr->ImportElements(top);
}
if (gRhoZMgr && top) {
gRhoZMgr->DestroyElements();
gRhoZMgr->ImportElements(gGeoShape);
gRhoZMgr->ImportElements(top);
}
}
class EvNavHandler
{
public:
void Fwd()
{
if (esd_event_id < esd_tree->GetEntries() - 1) {
++esd_event_id;
load_event();
update_projections();
} else {
gTextEntry->
SetText(
"Already at last event");
printf("Already at last event.\n");
}
}
void Bck()
{
if (esd_event_id > 0) {
--esd_event_id;
load_event();
update_projections();
} else {
gTextEntry->
SetText(
"Already at first event");
printf("Already at first event.\n");
}
}
};
void make_gui()
{
gROOT->ProcessLine(
".L SplitGLView.C+");
browser->
ExecPlugin(
"SplitGLView", 0,
"new SplitGLView(gClient->GetRoot(), 600, 450, kTRUE)");
{
EvNavHandler *fh = new EvNavHandler;
b->Connect(
"Clicked()",
"EvNavHandler", fh,
"Bck()");
b->Connect(
"Clicked()",
"EvNavHandler", fh,
"Fwd()");
}
}
enum ESDTrackFlags {
kITSin=0x0001,kITSout=0x0002,kITSrefit=0x0004,kITSpid=0x0008,
kTPCin=0x0010,kTPCout=0x0020,kTPCrefit=0x0040,kTPCpid=0x0080,
kTRDin=0x0100,kTRDout=0x0200,kTRDrefit=0x0400,kTRDpid=0x0800,
kTOFin=0x1000,kTOFout=0x2000,kTOFrefit=0x4000,kTOFpid=0x8000,
kHMPIDpid=0x20000,
kEMCALmatch=0x40000,
kTRDbackup=0x80000,
kTRDStop=0x20000000,
kESDpid=0x40000000,
kTIME=0x80000000
};
void alice_esd_read()
{
AliESDRun *esdrun = (AliESDRun*) esd->fESDObjects->FindObject("AliESDRun");
if (track_list == 0) {
}
{
AliESDtrack* at = (AliESDtrack*) tracks->
At(
n);
AliExternalTrackParam* tp = at;
if (! trackIsOn(at, kITSrefit)) {
tp = at->fIp;
}
TEveTrack* track = esd_make_track(trkProp,
n, at, tp);
}
}
AliESDtrack* at,
AliExternalTrackParam* tp)
{
if (tp == 0) tp = at;
rt.
fSign = (tp->fP[4] > 0) ? 1 : -1;
trackGetPos(tp, vbuf); rt.
fV.
Set(vbuf);
trackGetMomentum(tp, pbuf); rt.
fP.
Set(pbuf);
return track;
}
{
return (t->fFlags & mask) > 0;
}
void trackGetPos(AliExternalTrackParam* tp,
Double_t r[3])
{
r[0] = tp->fX;
r[1] = tp->fP[0];
r[2] = tp->fP[1];
r[0] =
x*cs -
r[1]*sn;
r[1] =
x*sn +
r[1]*cs;
}
void trackGetMomentum(AliExternalTrackParam* tp,
Double_t p[3])
{
p[0] = tp->fP[4]; p[1] = tp->fP[2]; p[2] = tp->fP[3];
p[0]=
pt*(
r*cs - p[1]*sn); p[1]=
pt*(p[1]*cs +
r*sn); p[2]=
pt*p[2];
}
Double_t trackGetP(AliExternalTrackParam* tp)
{
}
#endif
- Author
- Bertrand Bellenot
Definition in file alice_esd_split.C.