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