alice_esd.C

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

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