]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/EveBase/AliEveEventManager.cxx
Use GRP from event-directory if:
[u/mrichter/AliRoot.git] / EVE / EveBase / AliEveEventManager.cxx
1 // $Id$
2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4 /**************************************************************************
5  * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
7  * full copyright notice.                                                 *
8  **************************************************************************/
9
10 #include "AliEveEventManager.h"
11 #include "AliEveEventSelector.h"
12 #include "AliEveMacroExecutor.h"
13 #include <TEveManager.h>
14 #include <TEveViewer.h>
15
16 #include <AliRunLoader.h>
17 #include <AliRun.h>
18 #include <AliESDRun.h>
19 #include <AliESDEvent.h>
20 #include <AliESDfriend.h>
21 #include <AliAODEvent.h>
22
23 #include <AliDAQ.h>
24 #include <AliRawEventHeaderBase.h>
25 #include <AliRawReaderRoot.h>
26 #include <AliRawReaderFile.h>
27 #include <AliRawReaderDate.h>
28 #include <AliMagF.h>
29 #include <AliCDBManager.h>
30 #include <AliCDBStorage.h>
31 #include <AliGRPObject.h>
32 #include <AliHeader.h>
33 #include <AliGeomManager.h>
34 #include <AliGRPManager.h>
35
36 #include <TFile.h>
37 #include <TTree.h>
38 #include <TGeoManager.h>
39 #include <TGeoGlobalMagField.h>
40 #include <TSystem.h>
41 #include <TTimeStamp.h>
42 #include <TPRegexp.h>
43 #include <TError.h>
44
45 //==============================================================================
46 //==============================================================================
47 // AliEveEventManager
48 //==============================================================================
49
50 //______________________________________________________________________________
51 //
52 // Provides interface for loading and navigating standard AliRoot data
53 // (AliRunLoader), ESD, AOD and RAW.
54 //
55 // ESDfriend is attached automatically, if the file is found.
56 //
57 // AODfriends are not attached automatically as there are several
58 // possible files involved. To have a specific AODfriend attached, call
59 // static method
60 //   AliEveEventManager::AddAODfriend("AliAOD.VertexingHF.root");
61 // before initializing the event-manager.
62 //
63 // Also provides interface to magnetic-field and geometry. Mostly
64 // intended as wrappers over standard AliRoot functionality for
65 // convenient use from visualizateion macros.
66 //
67 // There can be a single main event-manger, it is stored in private
68 // data member fgMaster and can be accessed via static member function
69 // GetMaster().
70 //
71 // For event overlaying and embedding one can instantiate additional
72 // event-managers via static method AddDependentManager(const TString& path).
73 // This interface is under development.
74
75 ClassImp(AliEveEventManager)
76
77 Bool_t AliEveEventManager::fgAssertRunLoader = kFALSE;
78 Bool_t AliEveEventManager::fgAssertESD       = kFALSE;
79 Bool_t AliEveEventManager::fgAssertAOD       = kFALSE;
80 Bool_t AliEveEventManager::fgAssertRaw       = kFALSE;
81
82 TString  AliEveEventManager::fgESDFileName("AliESDs.root");
83 TString  AliEveEventManager::fgAODFileName("AliAOD.root");
84 TString  AliEveEventManager::fgRawFileName("raw.root");
85 TString  AliEveEventManager::fgCdbUri("local://$ALICE_ROOT/OCDB");
86
87 TList*   AliEveEventManager::fgAODfriends = 0;
88
89 Bool_t        AliEveEventManager::fgGRPLoaded    = kFALSE;
90 AliMagF*      AliEveEventManager::fgMagField     = 0;
91 Bool_t        AliEveEventManager::fgUniformField = kFALSE;
92
93 AliEveEventManager* AliEveEventManager::fgMaster  = 0;
94 AliEveEventManager* AliEveEventManager::fgCurrent = 0;
95
96 void AliEveEventManager::InitInternals()
97 {
98   // Initialize internal members.
99
100   static const TEveException kEH("AliEveEventManager::InitInternals ");
101
102   if (fgCurrent != 0)
103   {
104     throw(kEH + "Dependent event-managers should be created via static method AddDependentManager().");
105   }
106
107   if (fgMaster == 0)
108   {
109     fgMaster = this;
110   }
111
112   fgCurrent = this;
113
114   fAutoLoadTimer = new TTimer;
115   fAutoLoadTimer->Connect("Timeout()", "AliEveEventManager", this, "AutoLoadNextEvent()");
116
117   fExecutor = new AliEveMacroExecutor;
118
119   fTransients = new TEveElementList("Transients", "Transient per-event elements.");
120   fTransients->IncDenyDestroy();
121   gEve->AddToListTree(fTransients, kFALSE);
122
123   fTransientLists = new TEveElementList("Transient Lists", "Containers of transient elements.");
124   fTransientLists->IncDenyDestroy();
125   gEve->AddToListTree(fTransientLists, kFALSE);
126
127   fPEventSelector = new AliEveEventSelector(this);
128 }
129
130 AliEveEventManager::AliEveEventManager(const TString& name) :
131   TEveEventManager(name),
132
133   fPath      ( ), fEventId (-1),
134   fRunLoader (0),
135   fESDFile   (0), fESDTree (0), fESD (0),
136   fESDfriend (0), fESDfriendExists(kFALSE),
137   fAODFile   (0), fAODTree (0), fAOD (0),
138   fRawReader (0),
139   fAutoLoad  (kFALSE), fAutoLoadTime (5.),     fAutoLoadTimer(0),
140   fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
141   fExecutor    (0), fTransients(0), fTransientLists(0),
142   fPEventSelector(0),
143   fSubManagers (0),
144   fAutoLoadTimerRunning(kFALSE)
145 {
146   // Default constructor.
147
148   InitInternals();
149 }
150
151 AliEveEventManager::AliEveEventManager(const TString& name, const TString& path, Int_t ev) :
152   TEveEventManager(name, path),
153
154   fPath   (path), fEventId(-1),
155   fRunLoader (0),
156   fESDFile   (0), fESDTree (0), fESD (0),
157   fESDfriend (0), fESDfriendExists(kFALSE),
158   fAODFile   (0), fAODTree (0), fAOD (0),
159   fRawReader (0),
160   fAutoLoad  (kFALSE), fAutoLoadTime (5),      fAutoLoadTimer(0),
161   fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
162   fExecutor    (0), fTransients(0), fTransientLists(0),
163   fPEventSelector(0),
164   fSubManagers (0),
165   fAutoLoadTimerRunning(kFALSE)
166 {
167   // Constructor with event-directory URL and event-id.
168
169   InitInternals();
170
171   Open();
172   if (ev >= 0)
173   {
174     GotoEvent(ev);
175   }
176 }
177
178 AliEveEventManager::~AliEveEventManager()
179 {
180   // Destructor.
181
182   delete fSubManagers;
183
184   if (fIsOpen)
185   {
186     Close();
187   }
188
189   fTransients->DecDenyDestroy();
190   fTransients->Destroy();
191
192   fTransientLists->DecDenyDestroy();
193   fTransientLists->Destroy();
194 }
195
196 /******************************************************************************/
197
198 void AliEveEventManager::SetESDFileName(const TString& esd)
199 {
200   // Set file-name for opening ESD, default "AliESDs.root".
201
202   if ( ! esd.IsNull()) fgESDFileName = esd;
203 }
204
205 void AliEveEventManager::SetAODFileName(const TString& aod)
206 {
207   // Set file-name for opening AOD, default "AliAOD.root".
208
209   if ( ! aod.IsNull()) fgAODFileName = aod;
210 }
211
212 void AliEveEventManager::AddAODfriend(const TString& friendFileName)
213 {
214   // Add new AOD friend file-name to be attached when opening AOD.
215   // This should include '.root', as in 'AliAOD.VertexingHF.root'.
216
217   if (fgAODfriends == 0)
218   {
219     fgAODfriends = new TList;
220     fgAODfriends->SetOwner(kTRUE);
221   }
222   if (fgAODfriends->FindObject(friendFileName) == 0)
223   {
224     fgAODfriends->Add(new TObjString(friendFileName));
225   }
226 }
227
228 void AliEveEventManager::SetRawFileName(const TString& raw)
229 {
230   // Set file-name for opening of raw-data, default "raw.root"
231   if ( ! raw.IsNull()) fgRawFileName = raw;
232 }
233
234 void AliEveEventManager::SetCdbUri(const TString& cdb)
235 {
236   // Set path to CDB, default "local://$ALICE_ROOT/OCDB".
237
238   if ( ! cdb.IsNull()) fgCdbUri = cdb;
239 }
240
241 void AliEveEventManager::SetAssertElements(Bool_t assertRunloader, Bool_t assertEsd,
242                                            Bool_t assertAod, Bool_t assertRaw)
243 {
244   // Set global flags that detrmine which parts of the event-data must
245   // be present when the event is opened.
246
247   fgAssertRunLoader = assertRunloader;
248   fgAssertESD = assertEsd;
249   fgAssertAOD = assertAod;
250   fgAssertRaw = assertRaw;
251 }
252
253 /******************************************************************************/
254
255 void AliEveEventManager::Open()
256 {
257   // Open event-data from URL specified in fPath.
258   // Attempts to create AliRunLoader() and to open ESD with ESDfriends.
259   // Warning is reported if run-loader or ESD is not found.
260   // Global data-members fgAssertRunLoader and fgAssertESD can be set
261   // to throw exceptions instead.
262
263   static const TEveException kEH("AliEveEventManager::Open ");
264
265   if (fExternalCtrl)
266   {
267     throw (kEH + "Event-loop is under external control.");
268   }
269   if (fIsOpen)
270   {
271     throw (kEH + "Event-files already opened.");
272   }
273
274   gSystem->ExpandPathName(fPath);
275   // The following magick is required for ESDfriends to be loaded properly
276   // from non-current directory.
277   if (fPath.IsNull() || fPath == ".")
278   {
279     fPath = gSystem->WorkingDirectory();
280   }
281   else if ( ! fPath.BeginsWith("file:/"))
282   {
283     TUrl    url(fPath, kTRUE);
284     TString protocol(url.GetProtocol());
285     if (protocol == "file" && fPath[0] != '/')
286       fPath = Form("%s/%s", gSystem->WorkingDirectory(), fPath.Data());
287   }
288
289   Int_t runNo = -1;
290
291   // Open ESD and ESDfriends
292
293   TString esdPath(Form("%s/%s", fPath.Data(), fgESDFileName.Data()));
294   if ((fESDFile = TFile::Open(esdPath)))
295   {
296     fESD = new AliESDEvent();
297     fESDTree = (TTree*) fESDFile->Get("esdTree");
298     if (fESDTree != 0)
299     {
300       // Check if ESDfriends exists and attach the branch.
301       // We use TFile::Open() instead of gSystem->AccessPathName
302       // as it seems to work better when attachine alieve to a
303       // running reconstruction process with auto-save on.
304       // There was also a problem with TTree::Refresh() - it didn't
305       // save the friend branch on a separate file, fixed in 5.22.2 -
306       // so we might want to try the old way again soon.
307       TString p(Form("%s/AliESDfriends.root", fPath.Data()));
308       TFile *esdFriendFile = TFile::Open(p);
309       if (esdFriendFile)
310       {
311         if (!esdFriendFile->IsZombie())
312         {
313           esdFriendFile->Close();
314           fESDfriendExists = kTRUE;
315           fESDTree->SetBranchStatus ("ESDfriend*", 1);
316         }
317         delete esdFriendFile;
318       }
319
320       fESD->ReadFromTree(fESDTree);
321       if (fESDfriendExists)
322       {
323         fESDfriend = (AliESDfriend*) fESD->FindListObject("AliESDfriend");
324         Info(kEH, "found and attached ESD friend.");
325       }
326       else
327       {
328         Warning(kEH, "ESDfriend not found.");
329       }
330
331       if (fESDTree->GetEntry(0) <= 0)
332       {
333         delete fESDFile; fESDFile = 0;
334         delete fESD; fESD = 0;
335         Warning(kEH, "failed getting the first entry from esdTree.");
336       }
337       else
338       {
339         if (runNo < 0)
340           runNo = fESD->GetESDRun()->GetRunNumber();
341       }
342     }
343     else // esdtree == 0
344     {
345       delete fESDFile; fESDFile = 0;
346       delete fESD; fESD = 0;
347       Warning(kEH, "failed getting the esdTree.");
348     }
349   }
350   else // esd not readable
351   {
352     Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
353   }
354   if (fESDTree == 0)
355   {
356     if (fgAssertESD)
357     {
358       throw (kEH + "ESD not initialized. Its precence was requested.");
359     } else {
360       Warning(kEH, "ESD not initialized.");
361     }
362   }
363
364   // Open AOD and registered friends
365
366   TString aodPath(Form("%s/%s", fPath.Data(), fgAODFileName.Data()));
367   if ((fAODFile = TFile::Open(aodPath)))
368   {
369     fAOD = new AliAODEvent();
370     fAODTree = (TTree*) fAODFile->Get("aodTree");
371     if (fAODTree != 0)
372     {
373       // Check if AODfriends exist and attach them.
374       TIter       friends(fgAODfriends);
375       TObjString *name;
376       while ((name = (TObjString*) friends()) != 0)
377       {
378         TString p(Form("%s/%s", fPath.Data(), name->GetName()));
379         if (gSystem->AccessPathName(p, kReadPermission) == kFALSE)
380         {
381           fAODTree->AddFriend("aodTree", name->GetName());
382         }
383       }
384
385       fAOD->ReadFromTree(fAODTree);
386
387       if (fAODTree->GetEntry(0) <= 0)
388       {
389         delete fAODFile; fAODFile = 0;
390         delete fAOD;     fAOD     = 0;
391         Warning(kEH, "failed getting the first entry from addTree.");
392       }
393       else
394       {
395         if (runNo < 0)
396           runNo = fAOD->GetRunNumber();
397       }
398     }
399     else // aodtree == 0
400     {
401       delete fAODFile; fAODFile = 0;
402       delete fAOD;     fAOD     = 0;
403       Warning(kEH, "failed getting the aodTree.");
404     }
405   }
406   else // aod not readable
407   {
408     Warning(kEH, "can not read AOD file '%s'.", aodPath.Data());
409   }
410   if (fAODTree == 0)
411   {
412     if (fgAssertAOD)
413     {
414       throw (kEH + "AOD not initialized. Its precence was requested.");
415     } else {
416       Warning(kEH, "AOD not initialized.");
417     }
418   }
419
420   // Open RunLoader from galice.root
421
422   TString gaPath(Form("%s/galice.root", fPath.Data()));
423   // If i use open directly, we get fatal.
424   // Is AccessPathName check ok for xrootd / alien? Yes, not for http.
425   if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
426   {
427     fRunLoader = AliRunLoader::Open(gaPath, GetName());
428     if (fRunLoader)
429     {
430       TString alicePath = fPath + "/";
431       fRunLoader->SetDirName(alicePath);
432
433       if (fRunLoader->LoadgAlice() != 0)
434         Warning(kEH, "failed loading gAlice via run-loader.");
435
436       if (fRunLoader->LoadHeader() == 0)
437       {
438         if (runNo < 0)
439           runNo = fRunLoader->GetHeader()->GetRun();
440       }
441       else
442       {
443         Warning(kEH, "failed loading run-loader's header.");
444         delete fRunLoader;
445         fRunLoader = 0;
446       }
447     }
448     else // run-loader open failed
449     {
450       Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
451     }
452   }
453   else // galice not readable
454   {
455     Warning(kEH, "can not read '%s'.", gaPath.Data());
456   }
457   if (fRunLoader == 0)
458   {
459     if (fgAssertRunLoader)
460       throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
461     else
462       Warning(kEH, "Bootstraping of run-loader failed.");
463   }
464
465   // Open raw-data file
466
467   TString rawPath(Form("%s/%s", fPath.Data(), fgRawFileName.Data()));
468   // If i use open directly, raw-reader reports an error but i have
469   // no way to detect it.
470   // Is this (AccessPathName check) ok for xrootd / alien? Yes, not for http.
471   AliLog::EType_t oldLogLevel = (AliLog::EType_t) AliLog::GetGlobalLogLevel();
472   if (fgAssertRaw == kFALSE)
473   {
474     AliLog::SetGlobalLogLevel(AliLog::kFatal);
475   }
476   if (gSystem->AccessPathName(rawPath, kReadPermission) == kFALSE)
477   {
478     fRawReader = AliRawReader::Create(rawPath);
479   }
480   else
481   {
482     fRawReader = AliRawReader::Create(fgRawFileName);
483   }
484   if (fgAssertRaw == kFALSE)
485   {
486     AliLog::SetGlobalLogLevel(oldLogLevel);
487   }
488
489   if (fRawReader == 0)
490   {
491     if (fgAssertRaw)
492     {
493       throw (kEH + "raw-data not initialized. Its precence was requested.");
494     } else {
495       Warning(kEH, "raw-data not initialized.");
496     }
497   }
498
499   if (runNo < 0)
500   {
501     if (fRawReader)
502     {
503       fRawReader->NextEvent();
504       runNo = fRawReader->GetRunNumber();
505       Info(kEH, "Determining run-no from raw ... run=%d.", runNo);
506       fRawReader->RewindEvents();
507     } else {
508       throw (kEH + "unknown run number.");
509     }
510   }
511
512   // Initialize OCDB ... only in master event-manager
513
514   if (this == fgMaster)
515   {
516     AliCDBManager* cdb = AliCDBManager::Instance();
517     if (cdb->IsDefaultStorageSet() == kTRUE)
518     {
519       Warning(kEH, "CDB already set - using the old storage:\n  '%s'",
520               cdb->GetDefaultStorage()->GetURI().Data());
521     }
522     else
523     {
524       cdb->SetDefaultStorage(fgCdbUri);
525       if (cdb->IsDefaultStorageSet() == kFALSE)
526         throw (kEH + "CDB initialization failed.");
527     }
528     
529     TString expCDB(fgCdbUri);
530     gSystem->ExpandPathName(expCDB);
531     if (cdb->GetDefaultStorage()->GetURI() == expCDB)
532     {
533       TString grp     = "GRP/GRP/Data";
534       TString grppath = fPath + "/" + grp;
535       if (gSystem->AccessPathName(grppath, kReadPermission) == kFALSE)
536       {
537         if (cdb->GetSpecificStorage(grp))
538         {
539           Warning(kEH, "Local GRP exists, but the specific storage is already set.");
540         }
541         else
542         {
543           Info(kEH, "Setting CDB specific-storage for GRP from event directory.");
544           TString lpath("local://");
545           lpath += fPath;
546           cdb->SetSpecificStorage(grp, lpath);
547         }
548       }
549     }
550     cdb->SetRun(runNo);
551   }
552
553   fIsOpen = kTRUE;
554 }
555
556 void AliEveEventManager::SetEvent(AliRunLoader *runLoader, AliRawReader *rawReader, AliESDEvent *esd, AliESDfriend *esdf)
557 {
558   // Set an event from an external source.
559   // The method is used in the online visualisation.
560   // AOD is not supported.
561
562   static const TEveException kEH("AliEveEventManager::SetEvent ");
563
564   if (fIsOpen)
565   {
566     Warning(kEH, "Event-files were open. Closing and switching to external control.");
567     Close();
568   }
569
570   fRunLoader = runLoader;
571   fRawReader = rawReader;
572   fESD       = esd;
573   fESDfriend = esdf;
574   fAOD       = 0;
575
576   fEventId++;
577   fHasEvent     = kTRUE;
578   fExternalCtrl = kTRUE;
579
580   SetTitle("Online event in memory");
581   SetName ("Online Event");
582   ElementChanged();
583
584   AfterNewEventLoaded();
585
586   if (fAutoLoad) StartAutoLoadTimer();
587 }
588
589 Int_t AliEveEventManager::GetMaxEventId(Bool_t /*refreshESD*/) const
590 {
591   // Returns maximum available event id.
592   // If under external control or event is not opened -1 is returned.
593   // If raw-data is the only data-source this can not be known
594   // and 10,000,000 is returned.
595   // If neither data-source is initialised an exception is thrown.
596   // If refresh_esd is true and ESD is the primary event-data source
597   // its header is re-read from disk.
598
599   static const TEveException kEH("AliEveEventManager::GetMaxEventId ");
600
601   if (fExternalCtrl || fIsOpen == kFALSE)
602   {
603     return -1;
604   }
605
606   if (fESDTree)
607   {
608     // Refresh crashes with root-5.21.1-alice.
609     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
610     // when we move to a newer root.
611     // if (refreshESD)
612     //   fESDTree->Refresh();
613     return fESDTree->GetEntries() - 1;
614   }
615   else if (fAODTree)
616   {
617     return fAODTree->GetEntries() - 1;
618   }
619   else if (fRunLoader)
620   {
621     return fRunLoader->GetNumberOfEvents() - 1;
622   }
623   else if (fRawReader)
624   {
625     Int_t n = fRawReader->GetNumberOfEvents() - 1;
626     return n > -1 ? n : 10000000;
627   }
628   else
629   {
630     throw (kEH + "neither ESD, AOD, RunLoader nor Raw loaded.");
631   }
632 }
633
634 void AliEveEventManager::GotoEvent(Int_t event)
635 {
636   // Load data for specified event.
637   // If event is out of range an exception is thrown and old state
638   // is preserved.
639   // After successful loading of event, the virtual function
640   // AfterNewEventLoaded() is called. This executes commands that
641   // were registered via TEveEventManager::AddNewEventCommand().
642   //
643   // If event is negative, it is subtracted from the number of
644   // available events, thus passing -1 will load the last event.
645   // This is not supported when raw-data is the only data-source
646   // as the number of events is not known.
647
648   static const TEveException kEH("AliEveEventManager::GotoEvent ");
649
650   if (fAutoLoadTimerRunning)
651   {
652     throw (kEH + "Event auto-load timer is running.");
653   }
654   if (fExternalCtrl)
655   {
656     throw (kEH + "Event-loop is under external control.");
657   }
658   else if (!fIsOpen)
659   {
660     throw (kEH + "Event-files not opened.");
661   }
662
663   fHasEvent = kFALSE;
664
665   Int_t maxEvent = 0;
666   if (fESDTree)
667   {
668     // Refresh crashes with root-5.21.1-alice.
669     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
670     // when we move to a newer root.
671     // fESDTree->Refresh();
672     maxEvent = fESDTree->GetEntries() - 1;
673     if (event < 0)
674       event = fESDTree->GetEntries() + event;
675   }
676   else if (fAODTree)
677   {
678     maxEvent = fAODTree->GetEntries() - 1;
679     if (event < 0)
680       event = fAODTree->GetEntries() + event;
681   }
682   else if (fRunLoader)
683   {
684     maxEvent = fRunLoader->GetNumberOfEvents() - 1;
685     if (event < 0)
686       event = fRunLoader->GetNumberOfEvents() + event;
687   }
688   else if (fRawReader)
689   {
690     maxEvent = fRawReader->GetNumberOfEvents() - 1;
691     if (maxEvent < 0)
692     {
693       maxEvent = 10000000;
694       if (event < 0) {
695         Error(kEH, "current raw-data source does not support direct event access.");
696         return;
697       }
698       Info(kEH, "number of events unknown for current raw-data source, setting max-event id to 10M.");
699     }
700     else
701     {
702       if (event < 0)
703         event = fRawReader->GetNumberOfEvents() + event;
704     }
705   }
706   else
707   {
708     throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
709   }
710   if (event < 0 || event > maxEvent)
711   {
712     throw (kEH + Form("event %d not present, available range [%d, %d].",
713                       event, 0, maxEvent));
714   }
715
716   TEveManager::TRedrawDisabler rd(gEve);
717   gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
718
719   // !!! MT this is somewhat brutal; at least optionally, one could be
720   // a bit gentler, checking for objs owning their external refs and having
721   // additinal parents.
722   gEve->GetViewers()->DeleteAnnotations();
723   fTransients->DestroyElements();
724   for (TEveElement::List_i i = fTransientLists->BeginChildren();
725        i != fTransientLists->EndChildren(); ++i)
726   {
727     (*i)->DestroyElements();
728   }
729   DestroyElements();
730
731   if (fESDTree) {
732     if (fESDTree->GetEntry(event) <= 0)
733       throw (kEH + "failed getting required event from ESD.");
734
735     if (fESDfriendExists)
736       fESD->SetESDfriend(fESDfriend);
737   }
738
739   if (fAODTree) {
740     if (fAODTree->GetEntry(event) <= 0)
741       throw (kEH + "failed getting required event from AOD.");
742   }
743
744   if (fRunLoader) {
745     if (fRunLoader->GetEvent(event) != 0)
746       throw (kEH + "failed getting required event.");
747   }
748
749   if (fRawReader)
750   {
751     // AliRawReader::GotoEvent(Int_t) works for AliRawReaderRoot/Chain.
752     if (fRawReader->GotoEvent(event) == kFALSE)
753     {
754       // Use fallback method - iteration with NextEvent().
755       Int_t rawEv = fEventId;
756       if (event < rawEv)
757       {
758         fRawReader->RewindEvents();
759         rawEv = -1;
760       }
761
762       while (rawEv < event)
763       {
764         if ( ! fRawReader->NextEvent())
765         {
766           fRawReader->RewindEvents();
767           fEventId = -1;
768           throw (kEH + Form("Error going to next raw-event from event %d.", rawEv));
769         }
770         ++rawEv;
771       }
772       Warning(kEH, "Loaded raw-event %d with fallback method.\n", rawEv);
773     }
774   }
775
776   fHasEvent = kTRUE;
777   fEventId  = event;
778   if (this == fgMaster)
779   {
780     SetName(Form("Event %d", fEventId));
781     ElementChanged();
782   }
783
784   AfterNewEventLoaded();
785 }
786
787 void AliEveEventManager::NextEvent()
788 {
789   // Loads next event.
790   // Does magick needed for online display when under external event control.
791
792   static const TEveException kEH("AliEveEventManager::NextEvent ");
793
794   if (fAutoLoadTimerRunning)
795   {
796     throw (kEH + "Event auto-load timer is running.");
797   }
798
799   if (fExternalCtrl)
800   {
801     // !!! This should really go somewhere else. It is done in GotoEvent(),
802     // so here we should do it in SetEvent().
803     DestroyElements();
804
805     gSystem->ExitLoop();
806   }
807   else
808   {
809     Int_t nextevent=0;
810     if (fPEventSelector->FindNext(nextevent))
811     {
812       GotoEvent(nextevent);
813     }
814   }
815 }
816
817 void AliEveEventManager::PrevEvent()
818 {
819   // Loads previous event.
820
821   static const TEveException kEH("AliEveEventManager::PrevEvent ");
822
823   if (fAutoLoadTimerRunning)
824   {
825     throw (kEH + "Event auto-load timer is running.");
826   }
827   if (fExternalCtrl)
828   {
829     throw (kEH + "Event-loop is under external control.");
830   }
831   Int_t nextevent=0;
832   if (fPEventSelector->FindPrev(nextevent))
833   {
834     GotoEvent(nextevent);
835   }
836 }
837
838 void AliEveEventManager::Close()
839 {
840   // Close the event data-files and delete ESD, ESDfriend, run-loader
841   // and raw-reader.
842
843   static const TEveException kEH("AliEveEventManager::Close ");
844
845   if (!fIsOpen)
846   {
847     throw (kEH + "Event-files not opened.");
848   }
849
850   if (fAutoLoadTimerRunning)
851     StopAutoLoadTimer();
852
853   if (fESDTree) {
854     delete fESD;       fESD       = 0;
855     delete fESDfriend; fESDfriend = 0;
856     fESDfriendExists = kFALSE;
857
858     delete fESDTree;   fESDTree = 0;
859     delete fESDFile;   fESDFile = 0;
860   }
861
862   if (fAODTree) {
863     delete fAOD;       fAOD       = 0;
864
865     delete fAODTree;   fAODTree = 0;
866     delete fAODFile;   fAODFile = 0;
867   }
868
869   if (fRunLoader) {
870     delete fRunLoader; fRunLoader = 0;
871   }
872
873   if (fRawReader) {
874     delete fRawReader; fRawReader = 0;
875   }
876
877   fEventId  = -1;
878   fIsOpen   = kFALSE;
879   fHasEvent = kFALSE;
880 }
881
882
883 //------------------------------------------------------------------------------
884 // Static convenience functions, mainly used from macros.
885 //------------------------------------------------------------------------------
886
887 Bool_t AliEveEventManager::HasRunLoader()
888 {
889   // Check if AliRunLoader is initialized.
890
891   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRunLoader;
892 }
893
894 Bool_t AliEveEventManager::HasESD()
895 {
896   // Check if AliESDEvent is initialized.
897
898   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESD;
899 }
900
901 Bool_t AliEveEventManager::HasESDfriend()
902 {
903   // Check if AliESDfriend is initialized.
904
905   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESDfriend;
906 }
907
908 Bool_t AliEveEventManager::HasAOD()
909 {
910   // Check if AliESDEvent is initialized.
911
912   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fAOD;
913 }
914
915 Bool_t AliEveEventManager::HasRawReader()
916 {
917   // Check if raw-reader is initialized.
918
919   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRawReader;
920 }
921
922 AliRunLoader* AliEveEventManager::AssertRunLoader()
923 {
924   // Make sure AliRunLoader is initialized and return it.
925   // Throws exception in case run-loader is not available.
926   // Static utility for macros.
927
928   static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
929
930   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
931     throw (kEH + "ALICE event not ready.");
932   if (fgCurrent->fRunLoader == 0)
933     throw (kEH + "AliRunLoader not initialised.");
934   return fgCurrent->fRunLoader;
935 }
936
937 AliESDEvent* AliEveEventManager::AssertESD()
938 {
939   // Make sure AliESDEvent is initialized and return it.
940   // Throws exception in case ESD is not available.
941   // Static utility for macros.
942
943   static const TEveException kEH("AliEveEventManager::AssertESD ");
944
945   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
946     throw (kEH + "ALICE event not ready.");
947   if (fgCurrent->fESD == 0)
948     throw (kEH + "AliESD not initialised.");
949   return fgCurrent->fESD;
950 }
951
952 AliESDfriend* AliEveEventManager::AssertESDfriend()
953 {
954   // Make sure AliESDfriend is initialized and return it.
955   // Throws exception in case ESDfriend-loader is not available.
956   // Static utility for macros.
957
958   static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
959
960   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
961     throw (kEH + "ALICE event not ready.");
962   if (fgCurrent->fESDfriend == 0)
963     throw (kEH + "AliESDfriend not initialised.");
964   return fgCurrent->fESDfriend;
965 }
966
967 AliAODEvent* AliEveEventManager::AssertAOD()
968 {
969   // Make sure AliAODEvent is initialized and return it.
970   // Throws exception in case AOD is not available.
971   // Static utility for macros.
972
973   static const TEveException kEH("AliEveEventManager::AssertAOD ");
974
975   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
976     throw (kEH + "ALICE event not ready.");
977   if (fgCurrent->fAOD == 0)
978     throw (kEH + "AliAOD not initialised.");
979   return fgCurrent->fAOD;
980 }
981
982 AliRawReader* AliEveEventManager::AssertRawReader()
983 {
984   // Make sure raw-reader is initialized and return it.
985
986   static const TEveException kEH("AliEveEventManager::AssertRawReader ");
987
988   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
989     throw (kEH + "ALICE event not ready.");
990   if (fgCurrent->fRawReader == 0)
991     throw (kEH + "RawReader not ready.");
992
993   return fgCurrent->fRawReader;
994 }
995
996 //==============================================================================
997
998 AliMagF* AliEveEventManager::AssertMagField()    
999 {        
1000   // Make sure AliMagF is initialized and returns it.    
1001   // Throws exception in case magnetic field is not available.   
1002   // Static utility for macros.          
1003
1004   static const TEveException kEH("AliEveEventManager::AssertMagField ");         
1005                  
1006   if (fgMagField)
1007     return fgMagField;
1008
1009   if (!fgGRPLoaded)
1010   {
1011     InitGRP();
1012   }
1013
1014   if (TGeoGlobalMagField::Instance()->GetField())
1015   {
1016     fgMagField = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField());
1017     if (fgMagField == 0)
1018       throw kEH + "Global field set, but it is not AliMagF.";
1019   }
1020   else
1021   {
1022     throw kEH + "Could not initialize magnetic field.";
1023   }
1024
1025   return fgMagField;     
1026 }
1027
1028 TGeoManager* AliEveEventManager::AssertGeometry()
1029 {
1030   // Make sure AliGeomManager is initialized and returns the
1031   // corresponding TGeoManger.
1032   // gGeoManager is set to the return value.
1033   // Throws exception if geometry can not be loaded or if it is not
1034   // available and the TGeoManager is locked.
1035   // Static utility for macros.
1036
1037   static const TEveException kEH("AliEveEventManager::AssertGeometry ");
1038
1039   if (AliGeomManager::GetGeometry() == 0)
1040   {
1041     if (TGeoManager::IsLocked())
1042       throw (kEH + "geometry is not loaded but TGeoManager is locked.");
1043
1044     gGeoManager = 0;
1045     AliGeomManager::LoadGeometry();
1046     if ( ! AliGeomManager::GetGeometry())
1047     {
1048       throw (kEH + "can not load geometry.");
1049     }
1050     if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
1051     {
1052       ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
1053       // throw (kEH + "could not apply align objs.");
1054     }
1055     AliGeomManager::GetGeometry()->DefaultColors();
1056   }
1057
1058   gGeoManager = AliGeomManager::GetGeometry();
1059   return gGeoManager;
1060 }
1061
1062 //------------------------------------------------------------------------------
1063
1064 AliEveEventManager* AliEveEventManager::AddDependentManager(const TString& name, const TString& path)
1065 {
1066   // Create and attach a dependent event-manager.
1067   // It is not added into eve list tree.
1068
1069   static const TEveException kEH("AliEveEventManager::AddDependentManager ");
1070
1071   if (fgMaster == 0)
1072     throw(kEH + "Master event-manager must be instantiated first.");
1073
1074   if (fgMaster->fSubManagers == 0)
1075   {
1076     fgMaster->fSubManagers = new TList;
1077     fgMaster->fSubManagers->SetOwner(kTRUE);
1078   }
1079
1080   AliEveEventManager* new_mgr = 0;
1081   fgCurrent = 0;
1082   try
1083   {
1084     new_mgr = new AliEveEventManager(name, path, fgMaster->fEventId);
1085     fgMaster->fSubManagers->Add(new_mgr);
1086   }
1087   catch (TEveException& exc)
1088   {
1089     ::Error(kEH, "Creation of new event-manager failed: '%s'.", exc.Data());
1090   }
1091   fgCurrent = fgMaster;
1092
1093   return new_mgr;
1094 }
1095
1096 AliEveEventManager* AliEveEventManager::GetDependentManager(const TString& name)
1097 {
1098   // Get a dependant manager by name.
1099   // This will not change the current manager, use helper class
1100   // AliEveEventManager::CurrentChanger for that.
1101
1102   static const TEveException kEH("AliEveEventManager::GetDependentManager ");
1103
1104   if (fgMaster == 0)
1105     throw(kEH + "Master event-manager must be instantiated first.");
1106
1107   if (fgMaster->fSubManagers == 0)
1108     return 0;
1109
1110   return dynamic_cast<AliEveEventManager*>(fgMaster->fSubManagers->FindObject(name));
1111 }
1112
1113 AliEveEventManager* AliEveEventManager::GetMaster()
1114 {
1115   // Get master event-manager.
1116
1117   return fgMaster;
1118 }
1119
1120 AliEveEventManager* AliEveEventManager::GetCurrent()
1121 {
1122   // Get current event-manager.
1123
1124   return fgCurrent;
1125 }
1126
1127 void AliEveEventManager::RegisterTransient(TEveElement* element)
1128 {
1129   GetCurrent()->fTransients->AddElement(element);
1130 }
1131
1132 void AliEveEventManager::RegisterTransientList(TEveElement* element)
1133 {
1134   GetCurrent()->fTransientLists->AddElement(element);
1135 }
1136
1137 //------------------------------------------------------------------------------
1138 // Autoloading of events
1139 //------------------------------------------------------------------------------
1140
1141 void AliEveEventManager::SetAutoLoadTime(Float_t time)
1142 {
1143   // Set the auto-load time in seconds
1144
1145   fAutoLoadTime = time;
1146 }
1147
1148 void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
1149 {
1150   // Set the automatic event loading mode
1151
1152   static const TEveException kEH("AliEveEventManager::SetAutoLoad ");
1153
1154   if (fAutoLoad == autoLoad)
1155   {
1156     Warning(kEH, "Setting autoload to the same value as before - %s. Ignoring.", fAutoLoad ? "true" : "false");
1157     return;
1158   }
1159
1160   fAutoLoad = autoLoad;
1161   if (fAutoLoad)
1162   {
1163     StartAutoLoadTimer();
1164   }
1165   else
1166   {
1167     StopAutoLoadTimer();
1168   }
1169 }
1170
1171 void AliEveEventManager::StartAutoLoadTimer()
1172 {
1173   // Start the auto-load timer.
1174
1175   fAutoLoadTimer->SetTime((Long_t)(1000*fAutoLoadTime));
1176   fAutoLoadTimer->Reset();
1177   fAutoLoadTimer->TurnOn();
1178   fAutoLoadTimerRunning = kTRUE;
1179 }
1180
1181 void AliEveEventManager::StopAutoLoadTimer()
1182 {
1183   // Stop the auto-load timer.
1184
1185   fAutoLoadTimerRunning = kFALSE;
1186   fAutoLoadTimer->TurnOff();
1187 }
1188
1189 void AliEveEventManager::AutoLoadNextEvent()
1190 {
1191   // Called from auto-load timer, so it has to be public.
1192   // Do NOT call it directly.
1193
1194   static const TEveException kEH("AliEveEventManager::AutoLoadNextEvent ");
1195
1196   if ( ! fAutoLoadTimerRunning || ! fAutoLoadTimer->HasTimedOut())
1197   {
1198     Warning(kEH, "Called unexpectedly - ignoring the call. Should ONLY be called from an internal timer.");
1199     return;
1200   }
1201
1202   StopAutoLoadTimer();
1203   NextEvent();
1204   if (fAutoLoad && !fExternalCtrl)
1205     StartAutoLoadTimer();
1206 }
1207
1208 //------------------------------------------------------------------------------
1209 // Post event-loading functions
1210 //------------------------------------------------------------------------------
1211
1212 void AliEveEventManager::AfterNewEventLoaded()
1213 {
1214   // Execute registered macros and commands.
1215   // At the end emit NewEventLoaded signal.
1216   //
1217   // Virtual from TEveEventManager.
1218
1219   static const TEveException kEH("AliEveEventManager::AfterNewEventLoaded ");
1220
1221   if (fExecutor)
1222     fExecutor->ExecMacros();
1223
1224   TEveEventManager::AfterNewEventLoaded();
1225
1226   NewEventLoaded();
1227
1228   if (this == fgMaster && fSubManagers != 0)
1229   {
1230     TIter next(fSubManagers);
1231     while ((fgCurrent = dynamic_cast<AliEveEventManager*>(next())) != 0)
1232     {
1233       gEve->SetCurrentEvent(fgCurrent);
1234       try
1235       {
1236         fgCurrent->GotoEvent(fEventId);
1237       }
1238       catch (TEveException& exc)
1239       {
1240         // !!! Should somehow tag / disable / remove it?
1241         Error(kEH, "Getting event %d for sub-event-manager '%s' failed: '%s'.",
1242               fEventId, fgCurrent->GetName(), exc.Data());
1243       }
1244     }
1245     fgCurrent = fgMaster;
1246     gEve->SetCurrentEvent(fgMaster);
1247   }
1248 }
1249
1250 void AliEveEventManager::NewEventLoaded()
1251 {
1252   // Emit NewEventLoaded signal.
1253
1254   Emit("NewEventLoaded()");
1255 }
1256
1257
1258 //------------------------------------------------------------------------------
1259 // Event info dumpers
1260 //------------------------------------------------------------------------------
1261
1262 TString AliEveEventManager::GetEventInfoHorizontal() const
1263 {
1264   // Dumps the event-header contents in vertical formatting.
1265
1266   TString rawInfo, esdInfo;
1267
1268   if (!fRawReader)
1269   {
1270     rawInfo = "No raw-data event info is available!\n";
1271   }
1272   else
1273   {
1274     const UInt_t* attr = fRawReader->GetAttributes();
1275     TTimeStamp ts(fRawReader->GetTimestamp());
1276     rawInfo.Form("RAW event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1277                  "Trigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x  Timestamp: %s\n",
1278                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1279                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1280                  fRawReader->GetClassMask(),
1281                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1282                  attr[0],attr[1],attr[2], ts.AsString("s"));
1283   }
1284
1285   if (!fESD)
1286   {
1287     esdInfo = "No ESD event info is available!";
1288   }
1289   else
1290   {
1291     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1292     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1293     TTimeStamp ts(fESD->GetTimeStamp());
1294     esdInfo.Form("ESD event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1295                  "Active trigger classes: %s\nTrigger: %llx (%s)\nEvent# in file: %d  Timestamp: %s, MagField: %.2e",
1296                  fESD->GetRunNumber(),
1297                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1298                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1299                  acttrclasses.Data(),
1300                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1301                  fESD->GetEventNumberInFile(), ts.AsString("s"), fESD->GetMagneticField());
1302   }
1303
1304   return rawInfo + esdInfo;
1305 }
1306
1307 TString AliEveEventManager::GetEventInfoVertical() const
1308 {
1309   // Dumps the event-header contents in vertical formatting.
1310
1311   TString rawInfo, esdInfo;
1312
1313   if (!fRawReader)
1314   {
1315     rawInfo = "No raw-data event info is available!\n";
1316   }
1317   else
1318   {
1319     const UInt_t* attr = fRawReader->GetAttributes();
1320     rawInfo.Form("Raw-data event info:\nRun#: %d\nEvent type: %d (%s)\nPeriod: %x\nOrbit: %x   BC: %x\nTrigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x\nTimestamp: %x\n",
1321                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1322                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1323                  fRawReader->GetClassMask(),
1324                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1325                  attr[0],attr[1],attr[2],
1326                  fRawReader->GetTimestamp());
1327   }
1328
1329   if (!fESD)
1330   {
1331     esdInfo = "No ESD event info is available!\n";
1332   }
1333   else
1334   {
1335     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1336     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1337     esdInfo.Form("ESD event info:\nRun#: %d\nActive trigger classes: %s\nEvent type: %d (%s)\nPeriod: %x\nOrbit: %x   BC: %x\nTrigger: %llx (%s)\nEvent# in file:%d\nTimestamp: %x\n",
1338                  fESD->GetRunNumber(),
1339                  acttrclasses.Data(),
1340                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1341                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1342                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1343                  fESD->GetEventNumberInFile(),
1344                  fESD->GetTimeStamp());
1345   }
1346
1347   return rawInfo + "\n" + esdInfo;
1348 }
1349
1350
1351 //==============================================================================
1352 // Reading of GRP and MagneticField.
1353 // This is a reap-off from reconstruction ... should really be a common
1354 // code to do this somewhere in STEER.
1355 //==============================================================================
1356
1357 Bool_t AliEveEventManager::InitGRP()
1358 {
1359   //------------------------------------
1360   // Initialization of the GRP entry 
1361   //------------------------------------
1362
1363   static const TEveException kEH("AliEveEventManager::InitGRP ");
1364
1365   AliGRPManager grpMgr;
1366   if (!grpMgr.ReadGRPEntry()) {
1367     return kFALSE;
1368   }
1369   fgGRPLoaded = kTRUE;
1370   if (!grpMgr.SetMagField()) {
1371     throw kEH + "Setting of field failed!";
1372   }
1373
1374   //*** Get the diamond profiles from OCDB
1375   // Eventually useful.
1376
1377   /*
1378     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1379     if (entry) {
1380     fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1381     } else {
1382     ::Error(kEH, "No SPD diamond profile found in OCDB!");
1383     }
1384
1385     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1386     if (entry) {
1387     fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1388     } else {
1389     ::Error(kEH, "No diamond profile found in OCDB!");
1390     }
1391
1392     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1393     if (entry) {
1394     fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1395     } else {
1396     ::Error(kEH, "No TPC diamond profile found in OCDB!");
1397     }
1398   */
1399
1400   return kTRUE;
1401