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