AliEveEventManager
[u/mrichter/AliRoot.git] / EVE / EveBase / AliEveEventManager.cxx
1 // $Id$
2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4 /**************************************************************************
5  * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
7  * full copyright notice.                                                 *
8  **************************************************************************/
9
10 #include "AliEveEventManager.h"
11 #include "AliEveMacroExecutor.h"
12 #include <TEveManager.h>
13
14 #include <AliRunLoader.h>
15 #include <AliRun.h>
16 #include <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(const TString& name) :
97   TEveEventManager(name),
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& name, const TString& path, Int_t ev) :
117   TEveEventManager(name, path),
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   delete fSubManagers;
147
148   if (fIsOpen)
149   {
150     Close();
151   }
152 }
153
154 /******************************************************************************/
155
156 void AliEveEventManager::SetESDFileName(const TString& esd)
157 {
158   // Set file-name for opening ESD, default "AliESDs.root".
159
160   if ( ! esd.IsNull()) fgESDFileName = esd;
161 }
162
163 void AliEveEventManager::SetRawFileName(const TString& raw)
164 {
165   // Set file-name for opening of raw-data, default "raw.root"
166   if ( ! raw.IsNull()) fgRawFileName = raw;
167 }
168
169 void AliEveEventManager::SetCdbUri(const TString& cdb)
170 {
171   // Set path to CDB, default "local://$ALICE_ROOT".
172
173   if ( ! cdb.IsNull()) fgCdbUri = cdb;
174 }
175
176 void AliEveEventManager::SetAssertElements(Bool_t assertRunloader,
177                                            Bool_t assertEsd,
178                                            Bool_t assertRaw)
179 {
180   // Set global flags that detrmine which parts of the event-data must
181   // be present when the event is opened.
182
183   fgAssertRunLoader = assertRunloader;
184   fgAssertESD = assertEsd;
185   fgAssertRaw = assertRaw;
186 }
187
188 /******************************************************************************/
189
190 void AliEveEventManager::Open()
191 {
192   // Open event-data from URL specified in fPath.
193   // Attempts to create AliRunLoader() and to open ESD with ESDfriends.
194   // Warning is reported if run-loader or ESD is not found.
195   // Global data-members fgAssertRunLoader and fgAssertESD can be set
196   // to throw exceptions instead.
197
198   static const TEveException kEH("AliEveEventManager::Open ");
199
200   if (fExternalCtrl)
201   {
202     throw (kEH + "Event-loop is under external control.");
203   }
204   if (fIsOpen)
205   {
206     throw (kEH + "Event-files already opened.");
207   }
208
209   gSystem->ExpandPathName(fPath);
210   // The following magick is required for ESDfriends to be loaded properly
211   // from non-current directory.
212   if (fPath.IsNull() || fPath == ".")
213   {
214     fPath = gSystem->WorkingDirectory();
215   }
216   else if ( ! fPath.BeginsWith("file:/"))
217   {
218     TUrl    url(fPath, kTRUE);
219     TString protocol(url.GetProtocol());
220     if (protocol == "file" && fPath[0] != '/')
221       fPath = Form("%s/%s", gSystem->WorkingDirectory(), fPath.Data());
222   }
223
224   Int_t runNo = -1;
225
226   // Open ESD and ESDfriends
227
228   TString esdPath(Form("%s/%s", fPath.Data(), fgESDFileName.Data()));
229   if ((fESDFile = TFile::Open(esdPath)))
230   {
231     fESD = new AliESDEvent();
232     fESDTree = (TTree*) fESDFile->Get("esdTree");
233     if (fESDTree != 0)
234     {
235       // Check if ESDfriends exists and attach the branch.
236       // We use TFile::Open() instead of gSystem->AccessPathName
237       // as it seems to work better when attachine alieve to a
238       // running reconstruction process with auto-save on.
239       // There was also a problem with TTree::Refresh() - it didn't
240       // save the friend branch on a separate file, fixed in 5.22.2 -
241       // so we might want to try the old way again soon.
242       TString p(Form("%s/AliESDfriends.root", fPath.Data()));
243       TFile *esdFriendFile = TFile::Open(p);
244       if (esdFriendFile)
245       {
246         if (!esdFriendFile->IsZombie())
247         {
248           esdFriendFile->Close();
249           fESDfriendExists = kTRUE;
250           fESDTree->SetBranchStatus ("ESDfriend*", 1);
251         }
252         delete esdFriendFile;
253       }
254
255       fESD->ReadFromTree(fESDTree);
256       if (fESDfriendExists)
257       {
258         fESDfriend = (AliESDfriend*) fESD->FindListObject("AliESDfriend");
259         Info(kEH, "found and attached ESD friend.");
260       }
261       else
262       {
263         Warning(kEH, "ESDfriend not found.");
264       }
265
266       if (fESDTree->GetEntry(0) <= 0)
267       {
268         delete fESDFile; fESDFile = 0;
269         delete fESD; fESD = 0;
270         Warning(kEH, "failed getting the first entry from esdTree.");
271       }
272       else
273       {
274         if (runNo < 0)
275           runNo = fESD->GetESDRun()->GetRunNumber();
276       }
277     }
278     else // esdtree == 0
279     {
280       delete fESDFile; fESDFile = 0;
281       delete fESD; fESD = 0;
282       Warning(kEH, "failed getting the esdTree.");
283     }
284   }
285   else // esd not readable
286   {
287     Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
288   }
289   if (fESDTree == 0)
290   {
291     if (fgAssertESD)
292     {
293       throw (kEH + "ESD not initialized. Its precence was requested.");
294     } else {
295       Warning(kEH, "ESD not initialized.");
296     }
297   }
298
299   // Open RunLoader from galice.root
300
301   TString gaPath(Form("%s/galice.root", fPath.Data()));
302   // If i use open directly, we get fatal.
303   // Is AccessPathName check ok for xrootd / alien? Yes, not for http.
304   if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
305   {
306     fRunLoader = AliRunLoader::Open(gaPath, GetName());
307     if (fRunLoader)
308     {
309       TString alicePath = fPath + "/";
310       fRunLoader->SetDirName(alicePath);
311
312       if (fRunLoader->LoadgAlice() != 0)
313         Warning(kEH, "failed loading gAlice via run-loader.");
314
315       if (fRunLoader->LoadHeader() == 0)
316       {
317         if (runNo < 0)
318           runNo = fRunLoader->GetHeader()->GetRun();
319       }
320       else
321       {
322         Warning(kEH, "failed loading run-loader's header.");
323         delete fRunLoader;
324         fRunLoader = 0;
325       }
326     }
327     else // run-loader open failed
328     {
329       Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
330     }
331   }
332   else // galice not readable
333   {
334     Warning(kEH, "can not read '%s'.", gaPath.Data());
335   }
336   if (fRunLoader == 0)
337   {
338     if (fgAssertRunLoader)
339       throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
340     else
341       Warning(kEH, "Bootstraping of run-loader failed.");
342   }
343
344   // Open raw-data file
345
346   TString rawPath(Form("%s/%s", fPath.Data(), fgRawFileName.Data()));
347   // If i use open directly, raw-reader reports an error but i have
348   // no way to detect it.
349   // Is this (AccessPathName check) ok for xrootd / alien? Yes, not for http.
350   AliLog::EType_t oldLogLevel = (AliLog::EType_t) AliLog::GetGlobalLogLevel();
351   if (fgAssertRaw == kFALSE)
352   {
353     AliLog::SetGlobalLogLevel(AliLog::kFatal);
354   }
355   if (gSystem->AccessPathName(rawPath, kReadPermission) == kFALSE)
356   {
357     fRawReader = AliRawReader::Create(rawPath);
358   }
359   else
360   {
361     fRawReader = AliRawReader::Create(fgRawFileName);
362   }
363   if (fgAssertRaw == kFALSE)
364   {
365     AliLog::SetGlobalLogLevel(oldLogLevel);
366   }
367
368   if (fRawReader == 0)
369   {
370     if (fgAssertRaw)
371     {
372       throw (kEH + "raw-data not initialized. Its precence was requested.");
373     } else {
374       Warning(kEH, "raw-data not initialized.");
375     }
376   }
377
378   if (runNo < 0)
379   {
380     if (fRawReader)
381     {
382       fRawReader->NextEvent();
383       runNo = fRawReader->GetRunNumber();
384       Info(kEH, "Determining run-no from raw ... run=%d.", runNo);
385       fRawReader->RewindEvents();
386     } else {
387       throw (kEH + "unknown run number.");
388     }
389   }
390
391   if (this == fgMaster)
392   {
393     AliCDBManager* cdb = AliCDBManager::Instance();
394     if (cdb->IsDefaultStorageSet() == kTRUE)
395     {
396       Warning(kEH, "CDB already set - using the old storage:\n  '%s'",
397               cdb->GetDefaultStorage()->GetURI().Data());
398     }
399     else
400     {
401       cdb->SetDefaultStorage(fgCdbUri);
402       if (cdb->IsDefaultStorageSet() == kFALSE)
403         throw (kEH + "CDB initialization failed.");
404     }
405     cdb->SetRun(runNo);
406   }
407
408   fIsOpen = kTRUE;
409 }
410
411 void AliEveEventManager::SetEvent(AliRunLoader *runLoader, AliRawReader *rawReader, AliESDEvent *esd)
412 {
413   // Set an event from an external source
414   // The method is used in the online visualisation
415
416   static const TEveException kEH("AliEveEventManager::SetEvent ");
417
418   if (fIsOpen)
419   {
420     Warning(kEH, "Event-files were open. Closing and switching to external control.");
421     Close();
422   }
423
424   fRunLoader = runLoader;
425   fRawReader = rawReader;
426   fESD       = esd;
427
428   fEventId++;
429   fHasEvent     = kTRUE;
430   fExternalCtrl = kTRUE;
431
432   SetTitle("Online event in memory");
433   SetName ("Online Event");
434   ElementChanged();
435
436   AfterNewEventLoaded();
437
438   if (fAutoLoad) StartAutoLoadTimer();
439 }
440
441 Int_t AliEveEventManager::GetMaxEventId(Bool_t /*refreshESD*/) const
442 {
443   // Returns maximum available event id.
444   // If under external control or event is not opened -1 is returned.
445   // If raw-data is the only data-source this can not be known
446   // and 10,000,000 is returned.
447   // If neither data-source is initialised an exception is thrown.
448   // If refresh_esd is true and ESD is the primary event-data source
449   // its header is re-read from disk.
450
451   static const TEveException kEH("AliEveEventManager::GetMaxEventId ");
452
453   if (fExternalCtrl || fIsOpen == kFALSE)
454   {
455     return -1;
456   }
457
458   if (fESDTree)
459   {
460     // Refresh crashes with root-5.21.1-alice.
461     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
462     // when we move to a newer root.
463     // if (refreshESD)
464     //   fESDTree->Refresh();
465     return fESDTree->GetEntries() - 1;
466   }
467   else if (fRunLoader)
468   {
469     return fRunLoader->GetNumberOfEvents() - 1;
470   }
471   else if (fRawReader)
472   {
473     Int_t n = fRawReader->GetNumberOfEvents() - 1;
474     return n > -1 ? n : 10000000;
475   }
476   else
477   {
478     throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
479   }
480 }
481
482 void AliEveEventManager::GotoEvent(Int_t event)
483 {
484   // Load data for specified event.
485   // If event is out of range an exception is thrown and old state
486   // is preserved.
487   // After successful loading of event, the virtual function
488   // AfterNewEventLoaded() is called. This executes commands that
489   // were registered via TEveEventManager::AddNewEventCommand().
490   //
491   // If event is negative, it is subtracted from the number of
492   // available events, thus passing -1 will load the last event.
493   // This is not supported when raw-data is the only data-source
494   // as the number of events is not known.
495
496   static const TEveException kEH("AliEveEventManager::GotoEvent ");
497
498   if (fAutoLoadTimerRunning)
499   {
500     throw (kEH + "Event auto-load timer is running.");
501   }
502   if (fExternalCtrl)
503   {
504     throw (kEH + "Event-loop is under external control.");
505   }
506   else if (!fIsOpen)
507   {
508     throw (kEH + "Event-files not opened.");
509   }
510
511   fHasEvent = kFALSE;
512
513   Int_t maxEvent = 0;
514   if (fESDTree)
515   {
516     // Refresh crashes with root-5.21.1-alice.
517     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
518     // when we move to a newer root.
519     // fESDTree->Refresh();
520     maxEvent = fESDTree->GetEntries() - 1;
521     if (event < 0)
522       event = fESDTree->GetEntries() + event;
523   }
524   else if (fRunLoader)
525   {
526     maxEvent = fRunLoader->GetNumberOfEvents() - 1;
527     if (event < 0)
528       event = fRunLoader->GetNumberOfEvents() + event;
529   }
530   else if (fRawReader)
531   {
532     maxEvent = fRawReader->GetNumberOfEvents() - 1;
533     if (maxEvent < 0)
534     {
535       maxEvent = 10000000;
536       if (event < 0) {
537         Error(kEH, "current raw-data source does not support direct event access.");
538         return;
539       }
540       Info(kEH, "number of events unknown for current raw-data source, setting max-event id to 10M.");
541     }
542     else
543     {
544       if (event < 0)
545         event = fRawReader->GetNumberOfEvents() + event;
546     }
547   }
548   else
549   {
550     throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
551   }
552   if (event < 0 || event > maxEvent)
553   {
554     throw (kEH + Form("event %d not present, available range [%d, %d].",
555                       event, 0, maxEvent));
556   }
557
558   TEveManager::TRedrawDisabler rd(gEve);
559   gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
560
561   // !!! MT this is somewhat brutal; at least optionally, one could be
562   // a bit gentler, checking for objs owning their external refs and having
563   // additinal parents.
564   DestroyElements();
565
566   if (fESDTree) {
567     if (fESDTree->GetEntry(event) <= 0)
568       throw (kEH + "failed getting required event from ESD.");
569
570     if (fESDfriendExists)
571       fESD->SetESDfriend(fESDfriend);
572   }
573
574   if (fRunLoader) {
575     if (fRunLoader->GetEvent(event) != 0)
576       throw (kEH + "failed getting required event.");
577   }
578
579   if (fRawReader)
580   {
581     // AliRawReader::GotoEvent(Int_t) works for AliRawReaderRoot/Chain.
582     if (fRawReader->GotoEvent(event) == kFALSE)
583     {
584       // Use fallback method - iteration with NextEvent().
585       Int_t rawEv = fEventId;
586       if (event < rawEv)
587       {
588         fRawReader->RewindEvents();
589         rawEv = -1;
590       }
591
592       while (rawEv < event)
593       {
594         if ( ! fRawReader->NextEvent())
595         {
596           fRawReader->RewindEvents();
597           fEventId = -1;
598           throw (kEH + Form("Error going to next raw-event from event %d.", rawEv));
599         }
600         ++rawEv;
601       }
602       Warning(kEH, "Loaded raw-event %d with fallback method.\n", rawEv);
603     }
604   }
605
606   fHasEvent = kTRUE;
607   fEventId  = event;
608   if (this == fgMaster)
609   {
610     SetName(Form("Event %d", fEventId));
611     ElementChanged();
612   }
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 AliEveEventManager* AliEveEventManager::AddDependentManager(const TString& name, const TString& path)
870 {
871   // Create and attach a dependent event-manager.
872   // It is not added into eve list tree.
873
874   static const TEveException kEH("AliEveEventManager::AddDependentManager ");
875
876   if (fgMaster == 0)
877     throw(kEH + "Master event-manager must be instantiated first.");
878
879   if (fgMaster->fSubManagers == 0)
880   {
881     fgMaster->fSubManagers = new TList;
882     fgMaster->fSubManagers->SetOwner(kTRUE);
883   }
884
885   AliEveEventManager* new_mgr = 0;
886   fgCurrent = 0;
887   try
888   {
889     new_mgr = new AliEveEventManager(name, path, fgMaster->fEventId);
890     fgMaster->fSubManagers->Add(new_mgr);
891   }
892   catch (TEveException& exc)
893   {
894     ::Error(kEH, "Creation of new event-manager failed: '%s'.", exc.Data());
895   }
896   fgCurrent = fgMaster;
897
898   return new_mgr;
899 }
900
901 AliEveEventManager* AliEveEventManager::GetDependentManager(const TString& name)
902 {
903   // Get a dependant manager by name.
904   // This will not change the current manager, use helper class
905   // AliEveEventManager::CurrentChanger for that.
906
907   static const TEveException kEH("AliEveEventManager::GetDependentManager ");
908
909   if (fgMaster == 0)
910     throw(kEH + "Master event-manager must be instantiated first.");
911
912   if (fgMaster->fSubManagers == 0)
913     return 0;
914
915   return dynamic_cast<AliEveEventManager*>(fgMaster->fSubManagers->FindObject(name));
916 }
917
918 AliEveEventManager* AliEveEventManager::GetMaster()
919 {
920   // Get master event-manager.
921
922   return fgMaster;
923 }
924
925 AliEveEventManager* AliEveEventManager::GetCurrent()
926 {
927   // Get current event-manager.
928
929   return fgCurrent;
930 }
931
932 //------------------------------------------------------------------------------
933 // Autoloading of events
934 //------------------------------------------------------------------------------
935
936 void AliEveEventManager::SetAutoLoadTime(Float_t time)
937 {
938   // Set the auto-load time in seconds
939
940   fAutoLoadTime = time;
941 }
942
943 void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
944 {
945   // Set the automatic event loading mode
946
947   static const TEveException kEH("AliEveEventManager::SetAutoLoad ");
948
949   if (fAutoLoad == autoLoad)
950   {
951     Warning(kEH, "Setting autoload to the same value as before - %s. Ignoring.", fAutoLoad ? "true" : "false");
952     return;
953   }
954
955   fAutoLoad = autoLoad;
956   if (fAutoLoad)
957   {
958     StartAutoLoadTimer();
959   }
960   else
961   {
962     StopAutoLoadTimer();
963   }
964 }
965
966 void AliEveEventManager::StartAutoLoadTimer()
967 {
968   // Start the auto-load timer.
969
970   fAutoLoadTimer->SetTime((Long_t)(1000*fAutoLoadTime));
971   fAutoLoadTimer->Reset();
972   fAutoLoadTimer->TurnOn();
973   fAutoLoadTimerRunning = kTRUE;
974 }
975
976 void AliEveEventManager::StopAutoLoadTimer()
977 {
978   // Stop the auto-load timer.
979
980   fAutoLoadTimerRunning = kFALSE;
981   fAutoLoadTimer->TurnOff();
982 }
983
984 void AliEveEventManager::AutoLoadNextEvent()
985 {
986   // Called from auto-load timer, so it has to be public.
987   // Do NOT call it directly.
988
989   static const TEveException kEH("AliEveEventManager::AutoLoadNextEvent ");
990
991   if ( ! fAutoLoadTimerRunning || ! fAutoLoadTimer->HasTimedOut())
992   {
993     Warning(kEH, "Called unexpectedly - ignoring the call. Should ONLY be called from an internal timer.");
994     return;
995   }
996
997   StopAutoLoadTimer();
998   NextEvent();
999   if (fAutoLoad && !fExternalCtrl)
1000     StartAutoLoadTimer();
1001 }
1002
1003
1004 //------------------------------------------------------------------------------
1005 // Event selection by trigger
1006 //------------------------------------------------------------------------------
1007
1008 Bool_t AliEveEventManager::FindNextByTrigger(Int_t& event)
1009 {
1010   // Find next event that matches the trigger.
1011   // If a matching event is not found, we loop around and eventually
1012   // end up at the same event.
1013
1014   static const TEveException kEH("AliEveEventManager::FindNextByTrigger ");
1015
1016   if (!fESDTree) return kFALSE;
1017   TString firedtrclasses;
1018   for (Int_t i = fEventId+1; i<GetMaxEventId(kTRUE)+1; i++)
1019   {
1020     if (fESDTree->GetEntry(i) <= 0)
1021       throw (kEH + "failed getting required event from ESD.");
1022     firedtrclasses = fESD->GetFiredTriggerClasses();
1023     if (firedtrclasses.Contains(fTriggerType))
1024     {
1025       event=i;
1026       return kTRUE;
1027     }
1028   }
1029   for (Int_t i = 0; i<fEventId+1; i++)
1030   {
1031     if (fESDTree->GetEntry(i) <= 0)
1032       throw (kEH + "failed getting required event from ESD.");
1033     firedtrclasses = fESD->GetFiredTriggerClasses();
1034     if (firedtrclasses.Contains(fTriggerType))
1035     {
1036       event=i;
1037       return kTRUE;
1038     }
1039   }
1040   return kFALSE;
1041 }
1042
1043 Bool_t AliEveEventManager::FindPrevByTrigger(Int_t& event)
1044 {
1045   // Find previous event that matches the trigger.
1046
1047   static const TEveException kEH("AliEveEventManager::FindPrevByTrigger ");
1048
1049   if (!fESDTree) return kFALSE;
1050   TString firedtrclasses;
1051   for (Int_t i = fEventId-1; i>=0; i--)
1052   {
1053     if (fESDTree->GetEntry(i) <= 0)
1054       throw (kEH + "failed getting required event from ESD.");
1055     firedtrclasses = fESD->GetFiredTriggerClasses();
1056     if (firedtrclasses.Contains(fTriggerType))
1057     {
1058       event=i;
1059       return kTRUE;
1060     }
1061   }
1062   for (Int_t i = GetMaxEventId(kTRUE); i>fEventId-1; i--)
1063   {
1064     if (fESDTree->GetEntry(i) <= 0)
1065       throw (kEH + "failed getting required event from ESD.");
1066     firedtrclasses = fESD->GetFiredTriggerClasses();
1067     if (firedtrclasses.Contains(fTriggerType))
1068     {
1069       event=i;
1070       return kTRUE;
1071     }
1072   }
1073   return kFALSE;
1074 }
1075
1076
1077 //------------------------------------------------------------------------------
1078 // Post event-loading functions
1079 //------------------------------------------------------------------------------
1080
1081 void AliEveEventManager::AfterNewEventLoaded()
1082 {
1083   // Execute registered macros and commands.
1084   // At the end emit NewEventLoaded signal.
1085   //
1086   // Virtual from TEveEventManager.
1087
1088   static const TEveException kEH("AliEveEventManager::AfterNewEventLoaded ");
1089
1090   if (fExecutor)
1091     fExecutor->ExecMacros();
1092
1093   TEveEventManager::AfterNewEventLoaded();
1094
1095   NewEventLoaded();
1096
1097   if (this == fgMaster && fSubManagers != 0)
1098   {
1099     TIter next(fSubManagers);
1100     while ((fgCurrent = dynamic_cast<AliEveEventManager*>(next())) != 0)
1101     {
1102       // gEve->SetCurrentEvent(fgCurrent);
1103       try
1104       {
1105         fgCurrent->GotoEvent(fEventId);
1106       }
1107       catch (TEveException& exc)
1108       {
1109         // !!! Should somehow tag / disable / remove it?
1110         Error(kEH, "Getting event %d for sub-event-manager '%s' failed: '%s'.",
1111               fEventId, fgCurrent->GetName(), exc.Data());
1112       }
1113     }
1114     fgCurrent = fgMaster;
1115     // gEve->SetCurrentEvent(fgMaster);
1116   }
1117 }
1118
1119 void AliEveEventManager::NewEventLoaded()
1120 {
1121   // Emit NewEventLoaded signal.
1122
1123   Emit("NewEventLoaded()");
1124 }
1125
1126
1127 //------------------------------------------------------------------------------
1128 // Event info dumpers
1129 //------------------------------------------------------------------------------
1130
1131 TString AliEveEventManager::GetEventInfoHorizontal() const
1132 {
1133   // Dumps the event-header contents in vertical formatting.
1134
1135   TString rawInfo, esdInfo;
1136
1137   if (!fRawReader)
1138   {
1139     rawInfo = "No raw-data event info is available!\n";
1140   }
1141   else
1142   {
1143     const UInt_t* attr = fRawReader->GetAttributes();
1144     TTimeStamp ts(fRawReader->GetTimestamp());
1145     rawInfo.Form("RAW event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1146                  "Trigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x  Timestamp: %s\n",
1147                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1148                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1149                  fRawReader->GetClassMask(),
1150                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1151                  attr[0],attr[1],attr[2], ts.AsString("s"));
1152   }
1153
1154   if (!fESD)
1155   {
1156     esdInfo = "No ESD event info is available!";
1157   }
1158   else
1159   {
1160     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1161     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1162     TTimeStamp ts(fESD->GetTimeStamp());
1163     esdInfo.Form("ESD event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1164                  "Active trigger classes: %s\nTrigger: %llx (%s)\nEvent# in file: %d  Timestamp: %s, MagField: %.2e",
1165                  fESD->GetRunNumber(),
1166                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1167                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1168                  acttrclasses.Data(),
1169                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1170                  fESD->GetEventNumberInFile(), ts.AsString("s"), fESD->GetMagneticField());
1171   }
1172
1173   return rawInfo + esdInfo;
1174 }
1175
1176 TString AliEveEventManager::GetEventInfoVertical() const
1177 {
1178   // Dumps the event-header contents in vertical formatting.
1179
1180   TString rawInfo, esdInfo;
1181
1182   if (!fRawReader)
1183   {
1184     rawInfo = "No raw-data event info is available!\n";
1185   }
1186   else
1187   {
1188     const UInt_t* attr = fRawReader->GetAttributes();
1189     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",
1190                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1191                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1192                  fRawReader->GetClassMask(),
1193                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1194                  attr[0],attr[1],attr[2],
1195                  fRawReader->GetTimestamp());
1196   }
1197
1198   if (!fESD)
1199   {
1200     esdInfo = "No ESD event info is available!\n";
1201   }
1202   else
1203   {
1204     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1205     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1206     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",
1207                  fESD->GetRunNumber(),
1208                  acttrclasses.Data(),
1209                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1210                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1211                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1212                  fESD->GetEventNumberInFile(),
1213                  fESD->GetTimeStamp());
1214   }
1215
1216   return rawInfo + "\n" + esdInfo;
1217 }