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