alice_esd_split.C

Go to the documentation of this file.
00001 // @(#)root/eve:$Id: alice_esd_split.C 30749 2009-10-15 16:33:04Z brun $
00002 // Author: Bertrand Bellenot
00003 
00004 // Complex example showing ALICE ESD visualization in several views.
00005 
00006 /*
00007   alice_esd_split.C - a simple event-display for ALICE ESD tracks and clusters
00008                       version with several windows in the same workspace
00009 
00010   ------------------------------------------------------------------------
00011   ------------------------------------------------------------------------
00012 
00013   Only standard ROOT is used to process the ALICE ESD files.
00014 
00015   No ALICE code is needed, only four simple coordinate-transformation
00016   functions declared in this macro.
00017 
00018   A simple geometry of 10KB, extracted from the full TGeo-geometry, is
00019   used to outline the central detectors of ALICE.
00020 
00021   All files are access from the web by using the "CACHEREAD" option.
00022 
00023   ------------------------------------------------------------------------
00024   ------------------------------------------------------------------------
00025 
00026   1. Automatic building of ALICE ESD class declarations and dictionaries.
00027   ------------------------------------------------------------------------
00028 
00029   ALICE ESD is a TTree containing tracks and other event-related
00030   information with one entry per event. All these classes are part of
00031   the AliROOT offline framework and are not available to standard
00032   ROOT.
00033 
00034   To be able to access the event data in a natural way, by using
00035   data-members of classes and object containers, the header files and
00036   class dictionaries are automatically generated from the
00037   TStreamerInfo classes stored in the ESD file by using the
00038   TFile::MakeProject() function. The header files and a shared library
00039   is created in the aliesd/ directory and can be loaded dynamically
00040   into the ROOT session.
00041 
00042   See alice_esd_loadlib().
00043   
00044 
00045   2. Creation of simple GUI for event navigation.
00046   ------------------------------------------------------------------------
00047 
00048   Most common use of the event-display is to browse through a
00049   collection of events. Thus a simple GUI allowing this is created in
00050   the function make_gui().
00051 
00052   Eve uses the configurable ROOT-browser as its main window and so we
00053   create an extra tab in the left working area of the browser and
00054   provide backward/forward buttons.
00055 
00056 
00057   3. Event-navigation functions.
00058   ------------------------------------------------------------------------
00059 
00060   As this is a simple macro, we store the information about the
00061   current event in the global variable 'Int_t esd_event_id'. The
00062   functions for event-navigation simply modify this variable and call
00063   the load_event() function which does the following:
00064   1. drop the old visualization objects;
00065   2. retrieve given event from the ESD tree;
00066   3. call alice_esd_read() function to create visualization objects
00067      for the new event.
00068 
00069 
00070   4. Reading of ALICE data and creation of visualization objects.
00071   ------------------------------------------------------------------------
00072 
00073   This is performed in alice_esd_read() function, with the following
00074   steps:
00075   1. create the track container object - TEveTrackList;
00076   2. iterate over the ESD tracks, create TEveTrack objects and append
00077      them to the container;
00078   3. instruct the container to extrapolate the tracks and set their
00079      visual attributes.
00080 
00081 */
00082 
00083 
00084 R__EXTERN TEveProjectionManager *gRPhiMgr;
00085 R__EXTERN TEveProjectionManager *gRhoZMgr;
00086 TEveGeoShape *gGeoShape;
00087 
00088 // Forward declarations.
00089 
00090 class AliESDEvent;
00091 class AliESDfriend;
00092 class AliESDtrack;
00093 class AliExternalTrackParam;
00094 
00095 Bool_t     alice_esd_loadlib(const char* file, const char* project);
00096 void       make_gui();
00097 void       load_event();
00098 void       update_projections();
00099 
00100 void       alice_esd_read();
00101 TEveTrack* esd_make_track(TEveTrackPropagator* trkProp, Int_t index, AliESDtrack* at,
00102                           AliExternalTrackParam* tp=0);
00103 Bool_t     trackIsOn(AliESDtrack* t, Int_t mask);
00104 void       trackGetPos(AliExternalTrackParam* tp, Double_t r[3]);
00105 void       trackGetMomentum(AliExternalTrackParam* tp, Double_t p[3]);
00106 Double_t   trackGetP(AliExternalTrackParam* tp);
00107 
00108 
00109 // Configuration and global variables.
00110 
00111 const char* esd_file_name         = "http://root.cern.ch/files/alice_ESDs.root";
00112 const char* esd_friends_file_name = "http://root.cern.ch/files/alice_ESDfriends.root";
00113 const char* esd_geom_file_name    = "http://root.cern.ch/files/alice_ESDgeometry.root";
00114 
00115 TFile *esd_file          = 0;
00116 TFile *esd_friends_file  = 0;
00117 
00118 TTree *esd_tree          = 0;
00119 
00120 AliESDEvent  *esd        = 0;
00121 AliESDfriend *esd_friend = 0;
00122 
00123 Int_t esd_event_id       = 0; // Current event id.
00124 
00125 TEveTrackList *track_list = 0;
00126 
00127 TGTextEntry *gTextEntry;
00128 TGHProgressBar *gProgress;
00129 
00130 /******************************************************************************/
00131 // Initialization and steering functions
00132 /******************************************************************************/
00133 
00134 //______________________________________________________________________________
00135 void alice_esd_split(Bool_t auto_size=kFALSE)
00136 {
00137    // Main function, initializes the application.
00138    //
00139    // 1. Load the auto-generated library holding ESD classes and ESD dictionaries.
00140    // 2. Open ESD data-files.
00141    // 3. Load cartoon geometry.
00142    // 4. Spawn simple GUI.
00143    // 5. Load first event.
00144 
00145    TFile::SetCacheFileDir(".");
00146 
00147    if (!alice_esd_loadlib(esd_file_name, "aliesd"))
00148    {
00149       Error("alice_esd", "Can not load project libraries.");
00150       return;
00151    }
00152 
00153    printf("*** Opening ESD ***\n");
00154    esd_file = TFile::Open(esd_file_name, "CACHEREAD");
00155    if (!esd_file)
00156       return;
00157 
00158    printf("*** Opening ESD-friends ***\n");
00159    esd_friends_file = TFile::Open(esd_friends_file_name, "CACHEREAD");
00160    if (!esd_friends_file)
00161       return;
00162 
00163    esd_tree = (TTree*) esd_file->Get("esdTree");
00164 
00165    esd = (AliESDEvent*) esd_tree->GetUserInfo()->FindObject("AliESDEvent");
00166 
00167    // Set the branch addresses.
00168    {
00169       TIter next(esd->fESDObjects);
00170       TObject *el;
00171       while ((el=(TNamed*)next()))
00172       {
00173          TString bname(el->GetName());
00174          if(bname.CompareTo("AliESDfriend")==0)
00175          {
00176             // AliESDfriend needs some '.' magick.
00177             esd_tree->SetBranchAddress("ESDfriend.", esd->fESDObjects->GetObjectRef(el));
00178          }
00179          else
00180          {
00181             esd_tree->SetBranchAddress(bname, esd->fESDObjects->GetObjectRef(el));
00182          }
00183       }
00184    }
00185 
00186    TEveManager::Create();
00187 
00188    // Adapt the main frame to the screen size...
00189    if (auto_size)
00190    {
00191       Int_t qq; 
00192       UInt_t ww, hh;
00193       gVirtualX->GetWindowSize(gVirtualX->GetDefaultRootWindow(), qq, qq, ww, hh);
00194       Float_t screen_ratio = (Float_t)ww/(Float_t)hh;
00195       if (screen_ratio > 1.5) {
00196          gEve->GetBrowser()->MoveResize(100, 50, ww - 300, hh - 100);
00197       } else {
00198          gEve->GetBrowser()->Move(50, 50);
00199       }
00200    }
00201 
00202    { // Simple geometry
00203       TFile* geom = TFile::Open(esd_geom_file_name, "CACHEREAD");
00204       if (!geom)
00205          return;
00206       TEveGeoShapeExtract* gse = (TEveGeoShapeExtract*) geom->Get("Gentle");
00207       gGeoShape = TEveGeoShape::ImportShapeExtract(gse, 0);
00208       geom->Close();
00209       delete geom;
00210       gEve->AddGlobalElement(gGeoShape);
00211    }
00212 
00213    make_gui();
00214 
00215    // import the geometry in the projection managers
00216    if (gRPhiMgr) {
00217       TEveProjectionAxes* a = new TEveProjectionAxes(gRPhiMgr);
00218       a->SetNdivisions(3);
00219       gEve->GetScenes()->FindChild("R-Phi Projection")->AddElement(a);
00220       gRPhiMgr->ImportElements(gGeoShape);
00221    }
00222    if (gRhoZMgr) {
00223       TEveProjectionAxes* a = new TEveProjectionAxes(gRhoZMgr);
00224       a->SetNdivisions(3);
00225       gEve->GetScenes()->FindChild("Rho-Z Projection")->AddElement(a);
00226       gRhoZMgr->ImportElements(gGeoShape);
00227    }
00228 
00229    load_event();
00230 
00231    update_projections();
00232    
00233    gEve->Redraw3D(kTRUE); // Reset camera after the first event has been shown.
00234 }
00235 
00236 //______________________________________________________________________________
00237 Bool_t alice_esd_loadlib(const char* file, const char* project)
00238 {
00239    // Make sure that shared library created from the auto-generated project
00240    // files exists and load it.
00241 
00242    TString lib(Form("%s/%s.%s", project, project, gSystem->GetSoExt()));
00243 
00244    if (gSystem->AccessPathName(lib, kReadPermission)) {
00245       TFile* f = TFile::Open(file, "CACHEREAD");
00246       if (f == 0)
00247          return kFALSE;
00248       f->MakeProject(project, "*", "++");
00249       f->Close();
00250       delete f;
00251    }
00252    return gSystem->Load(lib) >= 0;
00253 }
00254 
00255 //______________________________________________________________________________
00256 void load_event()
00257 {
00258    // Load event specified in global esd_event_id.
00259    // The contents of previous event are removed.
00260 
00261    printf("Loading event %d.\n", esd_event_id);
00262    gTextEntry->SetTextColor(0xff0000);
00263    gTextEntry->SetText(Form("Loading event %d...",esd_event_id));
00264    gSystem->ProcessEvents();
00265 
00266    if (track_list)
00267       track_list->DestroyElements();
00268 
00269    esd_tree->GetEntry(esd_event_id);
00270 
00271    alice_esd_read();
00272 
00273    gEve->Redraw3D(kFALSE, kTRUE);
00274    gTextEntry->SetTextColor(0x000000);
00275    gTextEntry->SetText(Form("Event %d loaded",esd_event_id));
00276    gROOT->ProcessLine("SplitGLView::UpdateSummary()");
00277 }
00278 
00279 //______________________________________________________________________________
00280 void update_projections()
00281 {
00282    // cleanup then import geometry and event 
00283    // in the projection managers
00284    
00285    TEveElement* top = gEve->GetCurrentEvent();
00286    if (gRPhiMgr && top) {
00287       gRPhiMgr->DestroyElements();
00288       gRPhiMgr->ImportElements(gGeoShape);
00289       gRPhiMgr->ImportElements(top);
00290    }
00291    if (gRhoZMgr && top) {
00292       gRhoZMgr->DestroyElements();
00293       gRhoZMgr->ImportElements(gGeoShape);
00294       gRhoZMgr->ImportElements(top);
00295    }
00296 }
00297 
00298 /******************************************************************************/
00299 // GUI
00300 /******************************************************************************/
00301 
00302 //______________________________________________________________________________
00303 // 
00304 // EvNavHandler class is needed to connect GUI signals.
00305 
00306 class EvNavHandler
00307 {
00308 public:
00309    void Fwd()
00310    {
00311       if (esd_event_id < esd_tree->GetEntries() - 1) {
00312          ++esd_event_id;
00313          load_event();
00314          update_projections();
00315       } else {
00316          gTextEntry->SetTextColor(0xff0000);
00317          gTextEntry->SetText("Already at last event");
00318          printf("Already at last event.\n");
00319       }
00320    }
00321    void Bck()
00322    {
00323       if (esd_event_id > 0) {
00324          --esd_event_id;
00325          load_event();
00326          update_projections();
00327       } else {
00328          gTextEntry->SetTextColor(0xff0000);
00329          gTextEntry->SetText("Already at first event");
00330          printf("Already at first event.\n");
00331       }
00332    }
00333 };
00334 
00335 //______________________________________________________________________________
00336 void make_gui()
00337 {
00338    // Create minimal GUI for event navigation.
00339 
00340    gROOT->ProcessLine(".L SplitGLView.C+");
00341 
00342    TEveBrowser* browser = gEve->GetBrowser();
00343 
00344    browser->ShowCloseTab(kFALSE);
00345    browser->ExecPlugin("SplitGLView", 0, "new SplitGLView(gClient->GetRoot(), 600, 450, kTRUE)");
00346    browser->ShowCloseTab(kTRUE);
00347 
00348    browser->StartEmbedding(TRootBrowser::kLeft);
00349 
00350    TGMainFrame* frmMain = new TGMainFrame(gClient->GetRoot(), 1000, 600);
00351    frmMain->SetWindowName("XX GUI");
00352    frmMain->SetCleanup(kDeepCleanup);
00353 
00354    TGHorizontalFrame* hf = new TGHorizontalFrame(frmMain);
00355    {
00356       
00357       TString icondir( Form("%s/icons/", gSystem->Getenv("ROOTSYS")) );
00358       TGPictureButton* b = 0;
00359       EvNavHandler    *fh = new EvNavHandler;
00360 
00361       b = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoBack.gif"));
00362       hf->AddFrame(b, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 10, 2, 10, 10));
00363       b->Connect("Clicked()", "EvNavHandler", fh, "Bck()");
00364 
00365       b = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoForward.gif"));
00366       hf->AddFrame(b, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 10, 10, 10));
00367       b->Connect("Clicked()", "EvNavHandler", fh, "Fwd()");
00368 
00369       gTextEntry = new TGTextEntry(hf);
00370       gTextEntry->SetEnabled(kFALSE);
00371       hf->AddFrame(gTextEntry, new TGLayoutHints(kLHintsLeft | kLHintsCenterY  | 
00372                    kLHintsExpandX, 2, 10, 10, 10));
00373    }
00374    frmMain->AddFrame(hf, new TGLayoutHints(kLHintsTop | kLHintsExpandX,0,0,20,0));
00375 
00376    gProgress = new TGHProgressBar(frmMain, TGProgressBar::kFancy, 100);
00377    gProgress->ShowPosition(kTRUE, kFALSE, "%.0f tracks");
00378    gProgress->SetBarColor("green");
00379    frmMain->AddFrame(gProgress, new TGLayoutHints(kLHintsExpandX, 10, 10, 5, 5));
00380 
00381    frmMain->MapSubwindows();
00382    frmMain->Resize();
00383    frmMain->MapWindow();
00384 
00385    browser->StopEmbedding();
00386    browser->SetTabTitle("Event Control", 0);
00387 }
00388 
00389 
00390 /******************************************************************************/
00391 // Code for reading AliESD and creating visualization objects
00392 /******************************************************************************/
00393 
00394 enum ESDTrackFlags {
00395    kITSin=0x0001,kITSout=0x0002,kITSrefit=0x0004,kITSpid=0x0008,
00396    kTPCin=0x0010,kTPCout=0x0020,kTPCrefit=0x0040,kTPCpid=0x0080,
00397    kTRDin=0x0100,kTRDout=0x0200,kTRDrefit=0x0400,kTRDpid=0x0800,
00398    kTOFin=0x1000,kTOFout=0x2000,kTOFrefit=0x4000,kTOFpid=0x8000,
00399    kHMPIDpid=0x20000,
00400    kEMCALmatch=0x40000,
00401    kTRDbackup=0x80000,
00402    kTRDStop=0x20000000,
00403    kESDpid=0x40000000,
00404    kTIME=0x80000000
00405 };
00406 
00407 //______________________________________________________________________________
00408 void alice_esd_read()
00409 {
00410    // Read tracks and associated clusters from current event.
00411 
00412    AliESDRun    *esdrun = (AliESDRun*)    esd->fESDObjects->FindObject("AliESDRun");
00413    TClonesArray *tracks = (TClonesArray*) esd->fESDObjects->FindObject("Tracks");
00414 
00415    // This needs further investigation. Clusters not shown.
00416    // AliESDfriend *frnd   = (AliESDfriend*) esd->fESDObjects->FindObject("AliESDfriend");
00417    // printf("Friend %p, n_tracks:%d\n", frnd, frnd->fTracks.GetEntries());
00418 
00419    if (track_list == 0) {
00420       track_list = new TEveTrackList("ESD Tracks"); 
00421       track_list->SetMainColor(6);
00422       //track_list->SetLineWidth(2);
00423       track_list->SetMarkerColor(kYellow);
00424       track_list->SetMarkerStyle(4);
00425       track_list->SetMarkerSize(0.5);
00426 
00427       gEve->AddElement(track_list);
00428    }
00429 
00430    TEveTrackPropagator* trkProp = track_list->GetPropagator();
00431    trkProp->SetMagField( 0.1 * esdrun->fMagneticField ); // kGaus to Tesla
00432 
00433    gProgress->Reset();
00434    gProgress->SetMax(tracks->GetEntriesFast());
00435    for (Int_t n=0; n<tracks->GetEntriesFast(); ++n)
00436    {
00437       AliESDtrack* at = (AliESDtrack*) tracks->At(n);
00438 
00439       // If ITS refit failed, take track parameters at inner TPC radius.
00440       AliExternalTrackParam* tp = at;
00441       if (! trackIsOn(at, kITSrefit)) {
00442          tp = at->fIp;
00443       }
00444 
00445       TEveTrack* track = esd_make_track(trkProp, n, at, tp);
00446       track->SetAttLineAttMarker(track_list);
00447       track_list->AddElement(track);
00448 
00449       // This needs further investigation. Clusters not shown.
00450       // if (frnd)
00451       // {
00452       //     AliESDfriendTrack* ft = (AliESDfriendTrack*) frnd->fTracks->At(n);
00453       //     printf("%d friend = %p\n", ft);
00454       // }
00455       gProgress->Increment(1);
00456    }
00457 
00458    track_list->MakeTracks();
00459 }
00460 
00461 //______________________________________________________________________________
00462 TEveTrack* esd_make_track(TEveTrackPropagator*   trkProp,
00463                           Int_t                  index,
00464                           AliESDtrack*           at,
00465                           AliExternalTrackParam* tp)
00466 {
00467    // Helper function creating TEveTrack from AliESDtrack.
00468    //
00469    // Optionally specific track-parameters (e.g. at TPC entry point)
00470    // can be specified via the tp argument.
00471 
00472    Double_t      pbuf[3], vbuf[3];
00473    TEveRecTrack  rt;
00474 
00475    if (tp == 0) tp = at;
00476 
00477    rt.fLabel  = at->fLabel;
00478    rt.fIndex  = index;
00479    rt.fStatus = (Int_t) at->fFlags;
00480    rt.fSign   = (tp->fP[4] > 0) ? 1 : -1;
00481 
00482    trackGetPos(tp, vbuf);      rt.fV.Set(vbuf);
00483    trackGetMomentum(tp, pbuf); rt.fP.Set(pbuf);
00484 
00485    Double_t ep = trackGetP(at);
00486    Double_t mc = 0.138; // at->GetMass(); - Complicated function, requiring PID.
00487 
00488    rt.fBeta = ep/TMath::Sqrt(ep*ep + mc*mc);
00489  
00490    TEveTrack* track = new TEveTrack(&rt, trkProp);
00491    track->SetName(Form("TEveTrack %d", rt.fIndex));
00492    track->SetStdTitle();
00493 
00494    return track;
00495 }
00496 
00497 //______________________________________________________________________________
00498 Bool_t trackIsOn(AliESDtrack* t, Int_t mask)
00499 {
00500    // Check is track-flag specified by mask are set.
00501 
00502    return (t->fFlags & mask) > 0;
00503 }
00504 
00505 //______________________________________________________________________________
00506 void trackGetPos(AliExternalTrackParam* tp, Double_t r[3])
00507 {
00508    // Get global position of starting point of tp.
00509 
00510   r[0] = tp->fX; r[1] = tp->fP[0]; r[2] = tp->fP[1];
00511 
00512   Double_t cs=TMath::Cos(tp->fAlpha), sn=TMath::Sin(tp->fAlpha), x=r[0];
00513   r[0] = x*cs - r[1]*sn; r[1] = x*sn + r[1]*cs;
00514 }
00515 
00516 //______________________________________________________________________________
00517 void trackGetMomentum(AliExternalTrackParam* tp, Double_t p[3])
00518 {
00519    // Return global momentum vector of starting point of tp.
00520 
00521    p[0] = tp->fP[4]; p[1] = tp->fP[2]; p[2] = tp->fP[3];
00522 
00523    Double_t pt=1./TMath::Abs(p[0]);
00524    Double_t cs=TMath::Cos(tp->fAlpha), sn=TMath::Sin(tp->fAlpha);
00525    Double_t r=TMath::Sqrt(1 - p[1]*p[1]);
00526    p[0]=pt*(r*cs - p[1]*sn); p[1]=pt*(p[1]*cs + r*sn); p[2]=pt*p[2];
00527 }
00528 
00529 //______________________________________________________________________________
00530 Double_t trackGetP(AliExternalTrackParam* tp)
00531 {
00532    // Return magnitude of momentum of tp.
00533 
00534    return TMath::Sqrt(1.+ tp->fP[3]*tp->fP[3])/TMath::Abs(tp->fP[4]);
00535 }

Generated on Tue Jul 5 15:43:49 2011 for ROOT_528-00b_version by  doxygen 1.5.1