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