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