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