Change how ESDfriend is set in alieve.
[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       // We use TFile::Open() instead of gSystem->AccessPathName
214       // as it seems to work better when attachine alieve to a
215       // running reconstruction process with auto-save on.
216       // There was also a problem with TTree::Refresh() - it didn't
217       // save the friend branch on a separate file, fixed in 5.22.2 -
218       // so we might want to try the old way again soon.
219       TString p(Form("%s/AliESDfriends.root", fPath.Data()));
220       TFile *esdFriendFile = TFile::Open(p);
221       if (esdFriendFile)
222       {
223         if (!esdFriendFile->IsZombie())
224         {
225           esdFriendFile->Close();
226           fESDfriendExists = kTRUE;
227           fESDTree->SetBranchStatus ("ESDfriend*", 1);
228         }
229         delete esdFriendFile;
230       }
231
232       fESD->ReadFromTree(fESDTree);
233       if (fESDfriendExists)
234       {
235         fESDfriend = (AliESDfriend*) fESD->FindListObject("AliESDfriend");
236         Info(kEH, "found and attached ESD friend.");
237       }
238       else
239       {
240         Warning(kEH, "ESDfriend not found.");
241       }
242
243       if (fESDTree->GetEntry(0) <= 0)
244       {
245         delete fESDFile; fESDFile = 0;
246         delete fESD; fESD = 0;
247         Warning(kEH, "failed getting the first entry from esdTree.");
248       }
249       else
250       {
251         if (runNo < 0)
252           runNo = fESD->GetESDRun()->GetRunNumber();
253       }
254     }
255     else // esdtree == 0
256     {
257       delete fESDFile; fESDFile = 0;
258       delete fESD; fESD = 0;
259       Warning(kEH, "failed getting the esdTree.");
260     }
261   }
262   else // esd not readable
263   {
264     Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
265   }
266   if (fESDTree == 0)
267   {
268     if (fgAssertESD)
269     {
270       throw (kEH + "ESD not initialized. Its precence was requested.");
271     } else {
272       Warning(kEH, "ESD not initialized.");
273     }
274   }
275
276   // Open RunLoader from galice.root
277
278   TString gaPath(Form("%s/galice.root", fPath.Data()));
279   // If i use open directly, we get fatal.
280   // Is AccessPathName check ok for xrootd / alien? Yes, not for http.
281   if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
282   {
283     fRunLoader = AliRunLoader::Open(gaPath);
284     if (fRunLoader)
285     {
286       TString alicePath = fPath + "/";
287       fRunLoader->SetDirName(alicePath);
288
289       if (fRunLoader->LoadgAlice() != 0)
290         Warning(kEH, "failed loading gAlice via run-loader.");
291
292       if (fRunLoader->LoadHeader() == 0)
293       {
294         if (runNo < 0)
295           runNo = fRunLoader->GetHeader()->GetRun();
296       }
297       else
298       {
299         Warning(kEH, "failed loading run-loader's header.");
300         delete fRunLoader;
301         fRunLoader = 0;
302       }
303     }
304     else // run-loader open failed
305     {
306       Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
307     }
308   }
309   else // galice not readable
310   {
311     Warning(kEH, "can not read '%s'.", gaPath.Data());
312   }
313   if (fRunLoader == 0)
314   {
315     if (fgAssertRunLoader)
316       throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
317     else
318       Warning(kEH, "Bootstraping of run-loader failed.");
319   }
320
321   // Open raw-data file
322
323   TString rawPath(Form("%s/%s", fPath.Data(), fgRawFileName.Data()));
324   // If i use open directly, raw-reader reports an error but i have      
325   // no way to detect it.        
326   // Is this (AccessPathName check) ok for xrootd / alien? Yes, not for http.    
327   if (gSystem->AccessPathName(rawPath, kReadPermission) == kFALSE)       
328   {
329     fRawReader = AliRawReader::Create(rawPath);
330   }
331   else
332   {
333     fRawReader = AliRawReader::Create(fgRawFileName);
334   }
335   if (fRawReader == 0)
336   {
337     if (fgAssertRaw)
338     {
339       throw (kEH + "raw-data not initialized. Its precence was requested.");
340     } else {
341       Warning(kEH, "raw-data not initialized.");
342     }
343   }
344
345   if (runNo < 0)
346   {
347     if (fRawReader)
348     {
349       fRawReader->NextEvent();
350       runNo = fRawReader->GetRunNumber();
351       Info(kEH, "Determining run-no from raw ... run=%d.", runNo);
352       fRawReader->RewindEvents();
353     } else {
354       throw (kEH + "unknown run number.");
355     }
356   }
357
358   {
359     AliCDBManager* cdb = AliCDBManager::Instance();
360     cdb->SetDefaultStorage(fgCdbUri);
361     if (cdb->IsDefaultStorageSet() == kFALSE)
362       throw (kEH + "CDB initialization failed.");
363     cdb->SetRun(runNo);
364   }
365
366   SetName(Form("Event %d", fEventId));
367   SetTitle(fPath);
368   fIsOpen = kTRUE;
369 }
370
371 void AliEveEventManager::SetEvent(AliRunLoader *runLoader, AliRawReader *rawReader, AliESDEvent *esd)
372 {
373   // Set an event from an external source
374   // The method is used in the online visualisation
375
376   static const TEveException kEH("AliEveEventManager::SetEvent ");
377
378   if (fIsOpen)
379   {
380     Warning(kEH, "Event-files were open. Closing and switching to external control.");
381     Close();
382   }
383
384   fRunLoader = runLoader;
385   fRawReader = rawReader;
386   fESD       = esd;
387
388   fEventId++;
389   fHasEvent     = kTRUE;
390   fExternalCtrl = kTRUE;
391
392   SetTitle("Online event in memory");
393   SetName ("Online Event");
394
395   ElementChanged();
396   AfterNewEventLoaded();
397
398   if (fAutoLoad) StartAutoLoadTimer(); 
399 }
400
401 Int_t AliEveEventManager::GetMaxEventId(Bool_t /*refreshESD*/) const
402 {
403   // Returns maximum available event id.
404   // If under external control or event is not opened -1 is returned.
405   // If raw-data is the only data-source this can not be known
406   // and 10,000,000 is returned.
407   // If neither data-source is initialised an exception is thrown.
408   // If refresh_esd is true and ESD is the primary event-data source
409   // its header is re-read from disk.
410
411   static const TEveException kEH("AliEveEventManager::GetMaxEventId ");
412
413   if (fExternalCtrl || fIsOpen == kFALSE)
414   {
415     return -1;
416   }
417
418   if (fESDTree)
419   {
420     // Refresh crashes with root-5.21.1-alice.
421     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
422     // when we move to a newer root.
423     // if (refreshESD)
424     //   fESDTree->Refresh();
425     return fESDTree->GetEntries() - 1;
426   }
427   else if (fRunLoader)
428   {
429     return fRunLoader->GetNumberOfEvents() - 1;
430   }
431   else if (fRawReader)
432   {
433     Int_t n = fRawReader->GetNumberOfEvents() - 1;
434     return n > -1 ? n : 10000000;
435   }
436   else
437   {
438     throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
439   }
440 }
441
442 void AliEveEventManager::GotoEvent(Int_t event)
443 {
444   // Load data for specified event.
445   // If event is out of range an exception is thrown and old state
446   // is preserved.
447   // After successful loading of event, the virtual function
448   // AfterNewEventLoaded() is called. This executes commands that
449   // were registered via TEveEventManager::AddNewEventCommand().
450   //
451   // If event is negative, it is subtracted from the number of
452   // available events, thus passing -1 will load the last event.
453   // This is not supported when raw-data is the only data-source
454   // as the number of events is not known.
455
456   static const TEveException kEH("AliEveEventManager::GotoEvent ");
457
458   if (fAutoLoadTimerRunning)
459   {
460     throw (kEH + "Event auto-load timer is running.");
461   }
462   if (fExternalCtrl)
463   {
464     throw (kEH + "Event-loop is under external control.");
465   }
466   else if (!fIsOpen)
467   {
468     throw (kEH + "Event-files not opened.");
469   }
470
471   fHasEvent = kFALSE;
472
473   Int_t maxEvent = 0;
474   if (fESDTree)
475   {
476     // Refresh crashes with root-5.21.1-alice.
477     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
478     // when we move to a newer root.
479     // fESDTree->Refresh();
480     maxEvent = fESDTree->GetEntries() - 1;
481     if (event < 0)
482       event = fESDTree->GetEntries() + event;
483   }
484   else if (fRunLoader)
485   {
486     maxEvent = fRunLoader->GetNumberOfEvents() - 1;
487     if (event < 0)
488       event = fRunLoader->GetNumberOfEvents() + event;
489   }
490   else if (fRawReader)
491   {
492     maxEvent = fRawReader->GetNumberOfEvents() - 1;
493     if (maxEvent < 0)
494     {
495       maxEvent = 10000000;
496       if (event < 0) {
497         Error(kEH, "current raw-data source does not support direct event access.");
498         return;
499       }
500       Info(kEH, "number of events unknown for current raw-data source, setting max-event id to 10M.");
501     }
502     else
503     {
504       if (event < 0)
505         event = fRawReader->GetNumberOfEvents() + event;
506     }
507   }
508   else
509   {
510     throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
511   }
512   if (event < 0 || event > maxEvent)
513   {
514     throw (kEH + Form("event %d not present, available range [%d, %d].",
515                       event, 0, maxEvent));
516   }
517
518   TEveManager::TRedrawDisabler rd(gEve);
519   gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
520
521   // !!! MT this is somewhat brutal; at least optionally, one could be
522   // a bit gentler, checking for objs owning their external refs and having
523   // additinal parents.
524   DestroyElements();
525
526   if (fESDTree) {
527     if (fESDTree->GetEntry(event) <= 0)
528       throw (kEH + "failed getting required event from ESD.");
529
530     if (fESDfriendExists)
531       fESD->SetESDfriend(fESDfriend);
532   }
533
534   if (fRunLoader) {
535     if (fRunLoader->GetEvent(event) != 0)
536       throw (kEH + "failed getting required event.");
537   }
538
539   if (fRawReader)
540   {
541     // AliRawReader::GotoEvent(Int_t) works for AliRawReaderRoot/Chain.
542     if (fRawReader->GotoEvent(event) == kFALSE)
543     {
544       // Use fallback method - iteration with NextEvent().
545       Int_t rawEv = fEventId;
546       if (event < rawEv)
547       {
548         fRawReader->RewindEvents();
549         rawEv = -1;
550       }
551
552       while (rawEv < event)
553       {
554         if ( ! fRawReader->NextEvent())
555         {
556           fRawReader->RewindEvents();
557           fEventId = -1;
558           throw (kEH + Form("Error going to next raw-event from event %d.", rawEv));
559         }
560         ++rawEv;
561       }
562       Warning(kEH, "Loaded raw-event %d with fallback method.\n", rawEv);
563     }
564   }
565
566   fHasEvent = kTRUE;
567   fEventId  = event;
568   SetName(Form("Event %d", fEventId));
569   ElementChanged();
570
571   AfterNewEventLoaded();
572 }
573
574 void AliEveEventManager::NextEvent()
575 {
576   // Loads next event.
577   // Does magick needed for online display when under external event control.
578   
579   static const TEveException kEH("AliEveEventManager::NextEvent ");
580
581   if (fAutoLoadTimerRunning)
582   {
583     throw (kEH + "Event auto-load timer is running.");
584   }
585
586   if (fExternalCtrl)
587   {
588     // !!! This should really go somewhere else. It is done in GotoEvent(),
589     // so here we should do it in SetEvent().
590     DestroyElements();
591
592     gSystem->ExitLoop();
593   }
594   else
595   {
596     if (fEventId < GetMaxEventId(kTRUE))
597       GotoEvent(fEventId + 1);
598     else
599       GotoEvent(0);
600   }
601 }
602
603 void AliEveEventManager::PrevEvent()
604 {
605   // Loads previous event.
606
607   static const TEveException kEH("AliEveEventManager::PrevEvent ");
608
609   if (fAutoLoadTimerRunning)
610   {
611     throw (kEH + "Event auto-load timer is running.");
612   }
613   if (fExternalCtrl)
614   {
615     throw (kEH + "Event-loop is under external control.");
616   }
617
618   GotoEvent(fEventId - 1);
619 }
620
621 void AliEveEventManager::Close()
622 {
623   // Close the event data-files and delete ESD, ESDfriend, run-loader
624   // and raw-reader.
625
626   static const TEveException kEH("AliEveEventManager::Close ");
627
628   if (!fIsOpen)
629   {
630     throw (kEH + "Event-files not opened.");
631   }
632
633   if (fAutoLoadTimerRunning)
634     StopAutoLoadTimer();
635
636   if (fESDTree) {
637     delete fESD;       fESD       = 0;
638     delete fESDfriend; fESDfriend = 0;
639     fESDfriendExists = kFALSE;
640
641     delete fESDTree;   fESDTree = 0;
642     delete fESDFile;   fESDFile = 0;
643   }
644
645   if (fRunLoader) {
646     delete fRunLoader; fRunLoader = 0;
647   }
648
649   if (fRawReader) {
650     delete fRawReader; fRawReader = 0;
651   }
652
653   fEventId  = -1;
654   fIsOpen   = kFALSE;
655   fHasEvent = kFALSE;
656 }
657
658
659 //------------------------------------------------------------------------------
660 // Static convenience functions, mainly used from macros.
661 //------------------------------------------------------------------------------
662
663 Bool_t AliEveEventManager::HasRunLoader()
664 {
665   // Check if AliRunLoader is initialized.
666
667   return gAliEveEvent && gAliEveEvent->fHasEvent && gAliEveEvent->fRunLoader;
668 }
669
670 Bool_t AliEveEventManager::HasESD()
671 {
672   // Check if AliESDEvent is initialized.
673
674   return gAliEveEvent && gAliEveEvent->fHasEvent && gAliEveEvent->fESD;
675 }
676
677 Bool_t AliEveEventManager::HasESDfriend()
678 {
679   // Check if AliESDfriend is initialized.
680
681   return gAliEveEvent && gAliEveEvent->fHasEvent && gAliEveEvent->fESDfriend;
682 }
683
684 Bool_t AliEveEventManager::HasRawReader()
685 {
686   // Check if raw-reader is initialized.
687
688   return gAliEveEvent && gAliEveEvent->fHasEvent && gAliEveEvent->fRawReader;
689 }
690
691 AliRunLoader* AliEveEventManager::AssertRunLoader()
692 {
693   // Make sure AliRunLoader is initialized and return it.
694   // Throws exception in case run-loader is not available.
695   // Static utility for macros.
696
697   static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
698
699   if (gAliEveEvent == 0 || gAliEveEvent->fHasEvent == kFALSE)
700     throw (kEH + "ALICE event not ready.");
701   if (gAliEveEvent->fRunLoader == 0)
702     throw (kEH + "AliRunLoader not initialised.");
703   return gAliEveEvent->fRunLoader;
704 }
705
706 AliESDEvent* AliEveEventManager::AssertESD()
707 {
708   // Make sure AliESDEvent is initialized and return it.
709   // Throws exception in case ESD is not available.
710   // Static utility for macros.
711
712   static const TEveException kEH("AliEveEventManager::AssertESD ");
713
714   if (gAliEveEvent == 0 || gAliEveEvent->fHasEvent == kFALSE)
715     throw (kEH + "ALICE event not ready.");
716   if (gAliEveEvent->fESD == 0)
717     throw (kEH + "AliESD not initialised.");
718   return gAliEveEvent->fESD;
719 }
720
721 AliESDfriend* AliEveEventManager::AssertESDfriend()
722 {
723   // Make sure AliESDfriend is initialized and return it.
724   // Throws exception in case ESDfriend-loader is not available.
725   // Static utility for macros.
726
727   static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
728
729   if (gAliEveEvent == 0 || gAliEveEvent->fHasEvent == kFALSE)
730     throw (kEH + "ALICE event not ready.");
731   if (gAliEveEvent->fESDfriend == 0)
732     throw (kEH + "AliESDfriend not initialised.");
733   return gAliEveEvent->fESDfriend;
734 }
735
736 AliRawReader* AliEveEventManager::AssertRawReader()
737 {
738   // Make sure raw-reader is initialized and return it.
739
740   static const TEveException kEH("AliEveEventManager::AssertRawReader ");
741
742   if (gAliEveEvent == 0 || gAliEveEvent->fHasEvent == kFALSE)
743     throw (kEH + "ALICE event not ready.");
744   if (gAliEveEvent->fRawReader == 0)
745     throw (kEH + "RawReader not ready.");
746
747   return gAliEveEvent->fRawReader;
748 }
749
750 AliMagF* AliEveEventManager::AssertMagField()
751 {
752   // Make sure AliMagF is initialized and returns it.
753   // Run-loader must be initialized to get the correct magnetic field!
754   // Throws exception in case magnetic field is not available.
755   // Static utility for macros.
756
757   // !!!! This should be fixed ... get field also in some other way,
758   // not only via run-loader.
759
760   if (fgMagField == 0)
761   {
762     if (gAliEveEvent && gAliEveEvent->fRunLoader && gAliEveEvent->fRunLoader->GetAliRun())
763       fgMagField = gAliEveEvent->fRunLoader->GetAliRun()->Field();
764     else
765       fgMagField = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k5kG);
766   }
767   return fgMagField;
768 }
769
770 TGeoManager* AliEveEventManager::AssertGeometry()
771 {
772   // Make sure AliGeomManager is initialized and returns the
773   // corresponding TGeoManger.
774   // gGeoManager is set to the return value.
775   // Throws exception if geometry can not be loaded or if it is not
776   // available and the TGeoManager is locked.
777   // Static utility for macros.
778
779   static const TEveException kEH("AliEveEventManager::AssertGeometry ");
780
781   if (AliGeomManager::GetGeometry() == 0)
782   {
783     if (TGeoManager::IsLocked())
784       throw (kEH + "geometry is not loaded but TGeoManager is locked.");
785
786     gGeoManager = 0;
787     AliGeomManager::LoadGeometry();
788     if ( ! AliGeomManager::GetGeometry())
789     {
790       throw (kEH + "can not load geometry.");
791     }
792     if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
793     {
794       ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
795       // throw (kEH + "could not apply align objs.");
796     }
797     AliGeomManager::GetGeometry()->DefaultColors();
798   }
799
800   gGeoManager = AliGeomManager::GetGeometry();
801   return gGeoManager;
802 }
803
804
805 //------------------------------------------------------------------------------
806 // Autoloading of events
807 //------------------------------------------------------------------------------
808
809 void AliEveEventManager::SetAutoLoadTime(Float_t time)
810 {
811   // Set the auto-load time in seconds
812
813   fAutoLoadTime = time;
814 }
815
816 void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
817 {
818   // Set the automatic event loading mode
819
820   static const TEveException kEH("AliEveEventManager::SetAutoLoad ");
821
822   if (fAutoLoad == autoLoad)
823   {
824     Warning(kEH, "Setting autoload to the same value as before - %s. Ignoring.", fAutoLoad ? "true" : "false");
825     return;
826   }
827
828   fAutoLoad = autoLoad;
829   if (fAutoLoad)
830   {
831     StartAutoLoadTimer();
832   }
833   else
834   {
835     StopAutoLoadTimer();
836   }
837 }
838
839 void AliEveEventManager::StartAutoLoadTimer()
840 {
841   // Start the auto-load timer.
842
843   fAutoLoadTimer->SetTime((Long_t)(1000*fAutoLoadTime));
844   fAutoLoadTimer->Reset();
845   fAutoLoadTimer->TurnOn();
846   fAutoLoadTimerRunning = kTRUE;
847 }
848
849 void AliEveEventManager::StopAutoLoadTimer()
850 {
851   // Stop the auto-load timer.
852
853   fAutoLoadTimerRunning = kFALSE;
854   fAutoLoadTimer->TurnOff();
855 }
856
857 void AliEveEventManager::AutoLoadNextEvent()
858 {
859   // Called from auto-load timer, so it has to be public.
860   // Do NOT call it directly.
861
862   static const TEveException kEH("AliEveEventManager::AutoLoadNextEvent ");
863
864   if ( ! fAutoLoadTimerRunning || ! fAutoLoadTimer->HasTimedOut())
865   {
866     Warning(kEH, "Called unexpectedly - ignoring the call. Should ONLY be called from an internal timer.");
867     return;
868   }
869
870   StopAutoLoadTimer();
871   NextEvent();
872   if (fAutoLoad && !fExternalCtrl)
873     StartAutoLoadTimer();
874 }
875
876
877 //------------------------------------------------------------------------------
878 // Post event-loading functions
879 //------------------------------------------------------------------------------
880
881 void AliEveEventManager::AfterNewEventLoaded()
882 {
883   // Execute registered macros and commands.
884   // At the end emit NewEventLoaded signal.
885   //
886   // Virtual from TEveEventManager.
887
888   if (fExecutor)
889     fExecutor->ExecMacros();
890
891   TEveEventManager::AfterNewEventLoaded();
892
893   NewEventLoaded();
894 }
895
896 void AliEveEventManager::NewEventLoaded()
897 {
898   // Emit NewEventLoaded signal.
899
900   Emit("NewEventLoaded()");
901 }
902
903
904 //------------------------------------------------------------------------------
905 // Event info dumpers
906 //------------------------------------------------------------------------------
907
908 TString AliEveEventManager::GetEventInfoHorizontal() const
909 {
910   // Dumps the event-header contents in vertical formatting.
911
912   TString rawInfo, esdInfo;
913
914   if (!fRawReader)
915   {
916     rawInfo = "No raw-data event info is available!\n";
917   }
918   else
919   {
920     const UInt_t* attr = fRawReader->GetAttributes();
921     TTimeStamp ts(fRawReader->GetTimestamp());
922     rawInfo.Form("RAW event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
923                  "Trigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x  Timestamp: %s\n",
924                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
925                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
926                  fRawReader->GetClassMask(),
927                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
928                  attr[0],attr[1],attr[2], ts.AsString("s"));
929   }
930
931   if (!fESD)
932   {
933     esdInfo = "No ESD event info is available!";
934   }
935   else
936   {
937     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
938     TString firedtrclasses = fESD->GetFiredTriggerClasses();
939     TTimeStamp ts(fESD->GetTimeStamp());
940     esdInfo.Form("ESD event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
941                  "Active trigger classes: %s\nTrigger: %llx (%s)\nEvent# in file: %d  Timestamp: %s",
942                  fESD->GetRunNumber(),
943                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
944                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
945                  acttrclasses.Data(),
946                  fESD->GetTriggerMask(),firedtrclasses.Data(),
947                  fESD->GetEventNumberInFile(), ts.AsString("s"));
948   }
949
950   return rawInfo + esdInfo;
951 }
952
953 TString AliEveEventManager::GetEventInfoVertical() const
954 {
955   // Dumps the event-header contents in vertical formatting.
956
957   TString rawInfo, esdInfo;
958
959   if (!fRawReader)
960   {
961     rawInfo = "No raw-data event info is available!\n";
962   }
963   else
964   {
965     const UInt_t* attr = fRawReader->GetAttributes();
966     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",
967                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
968                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
969                  fRawReader->GetClassMask(),
970                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
971                  attr[0],attr[1],attr[2],
972                  fRawReader->GetTimestamp());
973   }
974
975   if (!fESD)
976   {
977     esdInfo = "No ESD event info is available!\n";
978   }
979   else
980   {
981     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
982     TString firedtrclasses = fESD->GetFiredTriggerClasses();
983     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",
984                  fESD->GetRunNumber(),
985                  acttrclasses.Data(),
986                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
987                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
988                  fESD->GetTriggerMask(),firedtrclasses.Data(),
989                  fESD->GetEventNumberInFile(),
990                  fESD->GetTimeStamp());
991   }
992
993   return rawInfo + "\n" + esdInfo;
994 }
995