Usage of the new GRP-manager code in AliEVE event manager (M+C)
[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 "AliEveEventSelector.h"
12 #include "AliEveMacroExecutor.h"
13 #include <TEveManager.h>
14 #include <TEveViewer.h>
15
16 #include <AliRunLoader.h>
17 #include <AliRun.h>
18 #include <AliESDRun.h>
19 #include <AliESDEvent.h>
20 #include <AliESDfriend.h>
21 #include <AliAODEvent.h>
22
23 #include <AliDAQ.h>
24 #include <AliRawEventHeaderBase.h>
25 #include <AliRawReaderRoot.h>
26 #include <AliRawReaderFile.h>
27 #include <AliRawReaderDate.h>
28 #include <AliMagF.h>
29 #include <AliCDBManager.h>
30 #include <AliCDBStorage.h>
31 #include <AliGRPObject.h>
32 #include <AliHeader.h>
33 #include <AliGeomManager.h>
34 #include <AliGRPManager.h>
35
36 #include <TFile.h>
37 #include <TTree.h>
38 #include <TGeoManager.h>
39 #include <TGeoGlobalMagField.h>
40 #include <TSystem.h>
41 #include <TTimeStamp.h>
42 #include <TPRegexp.h>
43 #include <TError.h>
44
45 //==============================================================================
46 //==============================================================================
47 // AliEveEventManager
48 //==============================================================================
49
50 //______________________________________________________________________________
51 //
52 // Provides interface for loading and navigating standard AliRoot data
53 // (AliRunLoader), ESD, AOD and RAW.
54 //
55 // ESDfriend is attached automatically, if the file is found.
56 //
57 // AODfriends are not attached automatically as there are several
58 // possible files involved. To have a specific AODfriend attached, call
59 // static method
60 //   AliEveEventManager::AddAODfriend("AliAOD.VertexingHF.root");
61 // before initializing the event-manager.
62 //
63 // Also provides interface to magnetic-field and geometry. Mostly
64 // intended as wrappers over standard AliRoot functionality for
65 // convenient use from visualizateion macros.
66 //
67 // There can be a single main event-manger, it is stored in private
68 // data member fgMaster and can be accessed via static member function
69 // GetMaster().
70 //
71 // For event overlaying and embedding one can instantiate additional
72 // event-managers via static method AddDependentManager(const TString& path).
73 // This interface is under development.
74
75 ClassImp(AliEveEventManager)
76
77 Bool_t AliEveEventManager::fgAssertRunLoader = kFALSE;
78 Bool_t AliEveEventManager::fgAssertESD       = kFALSE;
79 Bool_t AliEveEventManager::fgAssertAOD       = kFALSE;
80 Bool_t AliEveEventManager::fgAssertRaw       = kFALSE;
81
82 TString  AliEveEventManager::fgESDFileName("AliESDs.root");
83 TString  AliEveEventManager::fgAODFileName("AliAOD.root");
84 TString  AliEveEventManager::fgRawFileName("raw.root");
85 TString  AliEveEventManager::fgCdbUri("local://$ALICE_ROOT/OCDB");
86
87 TList*   AliEveEventManager::fgAODfriends = 0;
88
89 Bool_t        AliEveEventManager::fgGRPLoaded    = kFALSE;
90 AliMagF*      AliEveEventManager::fgMagField     = 0;
91 Bool_t        AliEveEventManager::fgUniformField = kFALSE;
92
93 AliEveEventManager* AliEveEventManager::fgMaster  = 0;
94 AliEveEventManager* AliEveEventManager::fgCurrent = 0;
95
96 void AliEveEventManager::InitInternals()
97 {
98   // Initialize internal members.
99
100   static const TEveException kEH("AliEveEventManager::InitInternals ");
101
102   if (fgCurrent != 0)
103   {
104     throw(kEH + "Dependent event-managers should be created via static method AddDependentManager().");
105   }
106
107   if (fgMaster == 0)
108   {
109     fgMaster = this;
110   }
111
112   fgCurrent = this;
113
114   fAutoLoadTimer = new TTimer;
115   fAutoLoadTimer->Connect("Timeout()", "AliEveEventManager", this, "AutoLoadNextEvent()");
116
117   fExecutor = new AliEveMacroExecutor;
118
119   fTransients = new TEveElementList("Transients", "Transient per-event elements.");
120   fTransients->IncDenyDestroy();
121   gEve->AddToListTree(fTransients, kFALSE);
122
123   fTransientLists = new TEveElementList("Transient Lists", "Containers of transient elements.");
124   fTransientLists->IncDenyDestroy();
125   gEve->AddToListTree(fTransientLists, kFALSE);
126
127   fPEventSelector = new AliEveEventSelector(this);
128 }
129
130 AliEveEventManager::AliEveEventManager(const TString& name) :
131   TEveEventManager(name),
132
133   fPath      ( ), fEventId (-1),
134   fRunLoader (0),
135   fESDFile   (0), fESDTree (0), fESD (0),
136   fESDfriend (0), fESDfriendExists(kFALSE),
137   fAODFile   (0), fAODTree (0), fAOD (0),
138   fRawReader (0),
139   fAutoLoad  (kFALSE), fAutoLoadTime (5.),     fAutoLoadTimer(0),
140   fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
141   fExecutor    (0), fTransients(0), fTransientLists(0),
142   fPEventSelector(0),
143   fSubManagers (0),
144   fAutoLoadTimerRunning(kFALSE)
145 {
146   // Default constructor.
147
148   InitInternals();
149 }
150
151 AliEveEventManager::AliEveEventManager(const TString& name, const TString& path, Int_t ev) :
152   TEveEventManager(name, path),
153
154   fPath   (path), fEventId(-1),
155   fRunLoader (0),
156   fESDFile   (0), fESDTree (0), fESD (0),
157   fESDfriend (0), fESDfriendExists(kFALSE),
158   fAODFile   (0), fAODTree (0), fAOD (0),
159   fRawReader (0),
160   fAutoLoad  (kFALSE), fAutoLoadTime (5),      fAutoLoadTimer(0),
161   fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
162   fExecutor    (0), fTransients(0), fTransientLists(0),
163   fPEventSelector(0),
164   fSubManagers (0),
165   fAutoLoadTimerRunning(kFALSE)
166 {
167   // Constructor with event-directory URL and event-id.
168
169   InitInternals();
170
171   Open();
172   if (ev >= 0)
173   {
174     GotoEvent(ev);
175   }
176 }
177
178 AliEveEventManager::~AliEveEventManager()
179 {
180   // Destructor.
181
182   delete fSubManagers;
183
184   if (fIsOpen)
185   {
186     Close();
187   }
188
189   fTransients->DecDenyDestroy();
190   fTransients->Destroy();
191
192   fTransientLists->DecDenyDestroy();
193   fTransientLists->Destroy();
194 }
195
196 /******************************************************************************/
197
198 void AliEveEventManager::SetESDFileName(const TString& esd)
199 {
200   // Set file-name for opening ESD, default "AliESDs.root".
201
202   if ( ! esd.IsNull()) fgESDFileName = esd;
203 }
204
205 void AliEveEventManager::SetAODFileName(const TString& aod)
206 {
207   // Set file-name for opening AOD, default "AliAOD.root".
208
209   if ( ! aod.IsNull()) fgAODFileName = aod;
210 }
211
212 void AliEveEventManager::AddAODfriend(const TString& friendFileName)
213 {
214   // Add new AOD friend file-name to be attached when opening AOD.
215   // This should include '.root', as in 'AliAOD.VertexingHF.root'.
216
217   if (fgAODfriends == 0)
218   {
219     fgAODfriends = new TList;
220     fgAODfriends->SetOwner(kTRUE);
221   }
222   if (fgAODfriends->FindObject(friendFileName) == 0)
223   {
224     fgAODfriends->Add(new TObjString(friendFileName));
225   }
226 }
227
228 void AliEveEventManager::SetRawFileName(const TString& raw)
229 {
230   // Set file-name for opening of raw-data, default "raw.root"
231   if ( ! raw.IsNull()) fgRawFileName = raw;
232 }
233
234 void AliEveEventManager::SetCdbUri(const TString& cdb)
235 {
236   // Set path to CDB, default "local://$ALICE_ROOT/OCDB".
237
238   if ( ! cdb.IsNull()) fgCdbUri = cdb;
239 }
240
241 void AliEveEventManager::SetAssertElements(Bool_t assertRunloader, Bool_t assertEsd,
242                                            Bool_t assertAod, Bool_t assertRaw)
243 {
244   // Set global flags that detrmine which parts of the event-data must
245   // be present when the event is opened.
246
247   fgAssertRunLoader = assertRunloader;
248   fgAssertESD = assertEsd;
249   fgAssertAOD = assertAod;
250   fgAssertRaw = assertRaw;
251 }
252
253 /******************************************************************************/
254
255 void AliEveEventManager::Open()
256 {
257   // Open event-data from URL specified in fPath.
258   // Attempts to create AliRunLoader() and to open ESD with ESDfriends.
259   // Warning is reported if run-loader or ESD is not found.
260   // Global data-members fgAssertRunLoader and fgAssertESD can be set
261   // to throw exceptions instead.
262
263   static const TEveException kEH("AliEveEventManager::Open ");
264
265   if (fExternalCtrl)
266   {
267     throw (kEH + "Event-loop is under external control.");
268   }
269   if (fIsOpen)
270   {
271     throw (kEH + "Event-files already opened.");
272   }
273
274   gSystem->ExpandPathName(fPath);
275   // The following magick is required for ESDfriends to be loaded properly
276   // from non-current directory.
277   if (fPath.IsNull() || fPath == ".")
278   {
279     fPath = gSystem->WorkingDirectory();
280   }
281   else if ( ! fPath.BeginsWith("file:/"))
282   {
283     TUrl    url(fPath, kTRUE);
284     TString protocol(url.GetProtocol());
285     if (protocol == "file" && fPath[0] != '/')
286       fPath = Form("%s/%s", gSystem->WorkingDirectory(), fPath.Data());
287   }
288
289   Int_t runNo = -1;
290
291   // Open ESD and ESDfriends
292
293   TString esdPath(Form("%s/%s", fPath.Data(), fgESDFileName.Data()));
294   if ((fESDFile = TFile::Open(esdPath)))
295   {
296     fESD = new AliESDEvent();
297     fESDTree = (TTree*) fESDFile->Get("esdTree");
298     if (fESDTree != 0)
299     {
300       // Check if ESDfriends exists and attach the branch.
301       // We use TFile::Open() instead of gSystem->AccessPathName
302       // as it seems to work better when attachine alieve to a
303       // running reconstruction process with auto-save on.
304       // There was also a problem with TTree::Refresh() - it didn't
305       // save the friend branch on a separate file, fixed in 5.22.2 -
306       // so we might want to try the old way again soon.
307       TString p(Form("%s/AliESDfriends.root", fPath.Data()));
308       TFile *esdFriendFile = TFile::Open(p);
309       if (esdFriendFile)
310       {
311         if (!esdFriendFile->IsZombie())
312         {
313           esdFriendFile->Close();
314           fESDfriendExists = kTRUE;
315           fESDTree->SetBranchStatus ("ESDfriend*", 1);
316         }
317         delete esdFriendFile;
318       }
319
320       fESD->ReadFromTree(fESDTree);
321       if (fESDfriendExists)
322       {
323         fESDfriend = (AliESDfriend*) fESD->FindListObject("AliESDfriend");
324         Info(kEH, "found and attached ESD friend.");
325       }
326       else
327       {
328         Warning(kEH, "ESDfriend not found.");
329       }
330
331       if (fESDTree->GetEntry(0) <= 0)
332       {
333         delete fESDFile; fESDFile = 0;
334         delete fESD; fESD = 0;
335         Warning(kEH, "failed getting the first entry from esdTree.");
336       }
337       else
338       {
339         if (runNo < 0)
340           runNo = fESD->GetESDRun()->GetRunNumber();
341       }
342     }
343     else // esdtree == 0
344     {
345       delete fESDFile; fESDFile = 0;
346       delete fESD; fESD = 0;
347       Warning(kEH, "failed getting the esdTree.");
348     }
349   }
350   else // esd not readable
351   {
352     Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
353   }
354   if (fESDTree == 0)
355   {
356     if (fgAssertESD)
357     {
358       throw (kEH + "ESD not initialized. Its precence was requested.");
359     } else {
360       Warning(kEH, "ESD not initialized.");
361     }
362   }
363
364   // Open AOD and registered friends
365
366   TString aodPath(Form("%s/%s", fPath.Data(), fgAODFileName.Data()));
367   if ((fAODFile = TFile::Open(aodPath)))
368   {
369     fAOD = new AliAODEvent();
370     fAODTree = (TTree*) fAODFile->Get("aodTree");
371     if (fAODTree != 0)
372     {
373       // Check if AODfriends exist and attach them.
374       TIter       friends(fgAODfriends);
375       TObjString *name;
376       while ((name = (TObjString*) friends()) != 0)
377       {
378         TString p(Form("%s/%s", fPath.Data(), name->GetName()));
379         if (gSystem->AccessPathName(p, kReadPermission) == kFALSE)
380         {
381           fAODTree->AddFriend("aodTree", name->GetName());
382         }
383       }
384
385       fAOD->ReadFromTree(fAODTree);
386
387       if (fAODTree->GetEntry(0) <= 0)
388       {
389         delete fAODFile; fAODFile = 0;
390         delete fAOD;     fAOD     = 0;
391         Warning(kEH, "failed getting the first entry from addTree.");
392       }
393       else
394       {
395         if (runNo < 0)
396           runNo = fAOD->GetRunNumber();
397       }
398     }
399     else // aodtree == 0
400     {
401       delete fAODFile; fAODFile = 0;
402       delete fAOD;     fAOD     = 0;
403       Warning(kEH, "failed getting the aodTree.");
404     }
405   }
406   else // aod not readable
407   {
408     Warning(kEH, "can not read AOD file '%s'.", aodPath.Data());
409   }
410   if (fAODTree == 0)
411   {
412     if (fgAssertAOD)
413     {
414       throw (kEH + "AOD not initialized. Its precence was requested.");
415     } else {
416       Warning(kEH, "AOD not initialized.");
417     }
418   }
419
420   // Open RunLoader from galice.root
421
422   TString gaPath(Form("%s/galice.root", fPath.Data()));
423   // If i use open directly, we get fatal.
424   // Is AccessPathName check ok for xrootd / alien? Yes, not for http.
425   if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
426   {
427     fRunLoader = AliRunLoader::Open(gaPath, GetName());
428     if (fRunLoader)
429     {
430       TString alicePath = fPath + "/";
431       fRunLoader->SetDirName(alicePath);
432
433       if (fRunLoader->LoadgAlice() != 0)
434         Warning(kEH, "failed loading gAlice via run-loader.");
435
436       if (fRunLoader->LoadHeader() == 0)
437       {
438         if (runNo < 0)
439           runNo = fRunLoader->GetHeader()->GetRun();
440       }
441       else
442       {
443         Warning(kEH, "failed loading run-loader's header.");
444         delete fRunLoader;
445         fRunLoader = 0;
446       }
447     }
448     else // run-loader open failed
449     {
450       Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
451     }
452   }
453   else // galice not readable
454   {
455     Warning(kEH, "can not read '%s'.", gaPath.Data());
456   }
457   if (fRunLoader == 0)
458   {
459     if (fgAssertRunLoader)
460       throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
461     else
462       Warning(kEH, "Bootstraping of run-loader failed.");
463   }
464
465   // Open raw-data file
466
467   TString rawPath(Form("%s/%s", fPath.Data(), fgRawFileName.Data()));
468   // If i use open directly, raw-reader reports an error but i have
469   // no way to detect it.
470   // Is this (AccessPathName check) ok for xrootd / alien? Yes, not for http.
471   AliLog::EType_t oldLogLevel = (AliLog::EType_t) AliLog::GetGlobalLogLevel();
472   if (fgAssertRaw == kFALSE)
473   {
474     AliLog::SetGlobalLogLevel(AliLog::kFatal);
475   }
476   if (gSystem->AccessPathName(rawPath, kReadPermission) == kFALSE)
477   {
478     fRawReader = AliRawReader::Create(rawPath);
479   }
480   else
481   {
482     fRawReader = AliRawReader::Create(fgRawFileName);
483   }
484   if (fgAssertRaw == kFALSE)
485   {
486     AliLog::SetGlobalLogLevel(oldLogLevel);
487   }
488
489   if (fRawReader == 0)
490   {
491     if (fgAssertRaw)
492     {
493       throw (kEH + "raw-data not initialized. Its precence was requested.");
494     } else {
495       Warning(kEH, "raw-data not initialized.");
496     }
497   }
498
499   if (runNo < 0)
500   {
501     if (fRawReader)
502     {
503       fRawReader->NextEvent();
504       runNo = fRawReader->GetRunNumber();
505       Info(kEH, "Determining run-no from raw ... run=%d.", runNo);
506       fRawReader->RewindEvents();
507     } else {
508       throw (kEH + "unknown run number.");
509     }
510   }
511
512   // Initialize OCDB ... only in master event-manager
513
514   if (this == fgMaster)
515   {
516     AliCDBManager* cdb = AliCDBManager::Instance();
517     if (cdb->IsDefaultStorageSet() == kTRUE)
518     {
519       Warning(kEH, "CDB already set - using the old storage:\n  '%s'",
520               cdb->GetDefaultStorage()->GetURI().Data());
521     }
522     else
523     {
524       cdb->SetDefaultStorage(fgCdbUri);
525       if (cdb->IsDefaultStorageSet() == kFALSE)
526         throw (kEH + "CDB initialization failed.");
527     }
528     cdb->SetRun(runNo);
529   }
530
531   fIsOpen = kTRUE;
532 }
533
534 void AliEveEventManager::SetEvent(AliRunLoader *runLoader, AliRawReader *rawReader, AliESDEvent *esd, AliESDfriend *esdf)
535 {
536   // Set an event from an external source.
537   // The method is used in the online visualisation.
538   // AOD is not supported.
539
540   static const TEveException kEH("AliEveEventManager::SetEvent ");
541
542   if (fIsOpen)
543   {
544     Warning(kEH, "Event-files were open. Closing and switching to external control.");
545     Close();
546   }
547
548   fRunLoader = runLoader;
549   fRawReader = rawReader;
550   fESD       = esd;
551   fESDfriend = esdf;
552   fAOD       = 0;
553
554   fEventId++;
555   fHasEvent     = kTRUE;
556   fExternalCtrl = kTRUE;
557
558   SetTitle("Online event in memory");
559   SetName ("Online Event");
560   ElementChanged();
561
562   AfterNewEventLoaded();
563
564   if (fAutoLoad) StartAutoLoadTimer();
565 }
566
567 Int_t AliEveEventManager::GetMaxEventId(Bool_t /*refreshESD*/) const
568 {
569   // Returns maximum available event id.
570   // If under external control or event is not opened -1 is returned.
571   // If raw-data is the only data-source this can not be known
572   // and 10,000,000 is returned.
573   // If neither data-source is initialised an exception is thrown.
574   // If refresh_esd is true and ESD is the primary event-data source
575   // its header is re-read from disk.
576
577   static const TEveException kEH("AliEveEventManager::GetMaxEventId ");
578
579   if (fExternalCtrl || fIsOpen == kFALSE)
580   {
581     return -1;
582   }
583
584   if (fESDTree)
585   {
586     // Refresh crashes with root-5.21.1-alice.
587     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
588     // when we move to a newer root.
589     // if (refreshESD)
590     //   fESDTree->Refresh();
591     return fESDTree->GetEntries() - 1;
592   }
593   else if (fAODTree)
594   {
595     return fAODTree->GetEntries() - 1;
596   }
597   else if (fRunLoader)
598   {
599     return fRunLoader->GetNumberOfEvents() - 1;
600   }
601   else if (fRawReader)
602   {
603     Int_t n = fRawReader->GetNumberOfEvents() - 1;
604     return n > -1 ? n : 10000000;
605   }
606   else
607   {
608     throw (kEH + "neither ESD, AOD, RunLoader nor Raw loaded.");
609   }
610 }
611
612 void AliEveEventManager::GotoEvent(Int_t event)
613 {
614   // Load data for specified event.
615   // If event is out of range an exception is thrown and old state
616   // is preserved.
617   // After successful loading of event, the virtual function
618   // AfterNewEventLoaded() is called. This executes commands that
619   // were registered via TEveEventManager::AddNewEventCommand().
620   //
621   // If event is negative, it is subtracted from the number of
622   // available events, thus passing -1 will load the last event.
623   // This is not supported when raw-data is the only data-source
624   // as the number of events is not known.
625
626   static const TEveException kEH("AliEveEventManager::GotoEvent ");
627
628   if (fAutoLoadTimerRunning)
629   {
630     throw (kEH + "Event auto-load timer is running.");
631   }
632   if (fExternalCtrl)
633   {
634     throw (kEH + "Event-loop is under external control.");
635   }
636   else if (!fIsOpen)
637   {
638     throw (kEH + "Event-files not opened.");
639   }
640
641   fHasEvent = kFALSE;
642
643   Int_t maxEvent = 0;
644   if (fESDTree)
645   {
646     // Refresh crashes with root-5.21.1-alice.
647     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
648     // when we move to a newer root.
649     // fESDTree->Refresh();
650     maxEvent = fESDTree->GetEntries() - 1;
651     if (event < 0)
652       event = fESDTree->GetEntries() + event;
653   }
654   else if (fAODTree)
655   {
656     maxEvent = fAODTree->GetEntries() - 1;
657     if (event < 0)
658       event = fAODTree->GetEntries() + event;
659   }
660   else if (fRunLoader)
661   {
662     maxEvent = fRunLoader->GetNumberOfEvents() - 1;
663     if (event < 0)
664       event = fRunLoader->GetNumberOfEvents() + event;
665   }
666   else if (fRawReader)
667   {
668     maxEvent = fRawReader->GetNumberOfEvents() - 1;
669     if (maxEvent < 0)
670     {
671       maxEvent = 10000000;
672       if (event < 0) {
673         Error(kEH, "current raw-data source does not support direct event access.");
674         return;
675       }
676       Info(kEH, "number of events unknown for current raw-data source, setting max-event id to 10M.");
677     }
678     else
679     {
680       if (event < 0)
681         event = fRawReader->GetNumberOfEvents() + event;
682     }
683   }
684   else
685   {
686     throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
687   }
688   if (event < 0 || event > maxEvent)
689   {
690     throw (kEH + Form("event %d not present, available range [%d, %d].",
691                       event, 0, maxEvent));
692   }
693
694   TEveManager::TRedrawDisabler rd(gEve);
695   gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
696
697   // !!! MT this is somewhat brutal; at least optionally, one could be
698   // a bit gentler, checking for objs owning their external refs and having
699   // additinal parents.
700   gEve->GetViewers()->DeleteAnnotations();
701   fTransients->DestroyElements();
702   for (TEveElement::List_i i = fTransientLists->BeginChildren();
703        i != fTransientLists->EndChildren(); ++i)
704   {
705     (*i)->DestroyElements();
706   }
707   DestroyElements();
708
709   if (fESDTree) {
710     if (fESDTree->GetEntry(event) <= 0)
711       throw (kEH + "failed getting required event from ESD.");
712
713     if (fESDfriendExists)
714       fESD->SetESDfriend(fESDfriend);
715   }
716
717   if (fAODTree) {
718     if (fAODTree->GetEntry(event) <= 0)
719       throw (kEH + "failed getting required event from AOD.");
720   }
721
722   if (fRunLoader) {
723     if (fRunLoader->GetEvent(event) != 0)
724       throw (kEH + "failed getting required event.");
725   }
726
727   if (fRawReader)
728   {
729     // AliRawReader::GotoEvent(Int_t) works for AliRawReaderRoot/Chain.
730     if (fRawReader->GotoEvent(event) == kFALSE)
731     {
732       // Use fallback method - iteration with NextEvent().
733       Int_t rawEv = fEventId;
734       if (event < rawEv)
735       {
736         fRawReader->RewindEvents();
737         rawEv = -1;
738       }
739
740       while (rawEv < event)
741       {
742         if ( ! fRawReader->NextEvent())
743         {
744           fRawReader->RewindEvents();
745           fEventId = -1;
746           throw (kEH + Form("Error going to next raw-event from event %d.", rawEv));
747         }
748         ++rawEv;
749       }
750       Warning(kEH, "Loaded raw-event %d with fallback method.\n", rawEv);
751     }
752   }
753
754   fHasEvent = kTRUE;
755   fEventId  = event;
756   if (this == fgMaster)
757   {
758     SetName(Form("Event %d", fEventId));
759     ElementChanged();
760   }
761
762   AfterNewEventLoaded();
763 }
764
765 void AliEveEventManager::NextEvent()
766 {
767   // Loads next event.
768   // Does magick needed for online display when under external event control.
769
770   static const TEveException kEH("AliEveEventManager::NextEvent ");
771
772   if (fAutoLoadTimerRunning)
773   {
774     throw (kEH + "Event auto-load timer is running.");
775   }
776
777   if (fExternalCtrl)
778   {
779     // !!! This should really go somewhere else. It is done in GotoEvent(),
780     // so here we should do it in SetEvent().
781     DestroyElements();
782
783     gSystem->ExitLoop();
784   }
785   else
786   {
787     Int_t nextevent=0;
788     if (fPEventSelector->FindNext(nextevent))
789     {
790       GotoEvent(nextevent);
791     }
792   }
793 }
794
795 void AliEveEventManager::PrevEvent()
796 {
797   // Loads previous event.
798
799   static const TEveException kEH("AliEveEventManager::PrevEvent ");
800
801   if (fAutoLoadTimerRunning)
802   {
803     throw (kEH + "Event auto-load timer is running.");
804   }
805   if (fExternalCtrl)
806   {
807     throw (kEH + "Event-loop is under external control.");
808   }
809   Int_t nextevent=0;
810   if (fPEventSelector->FindPrev(nextevent))
811   {
812     GotoEvent(nextevent);
813   }
814 }
815
816 void AliEveEventManager::Close()
817 {
818   // Close the event data-files and delete ESD, ESDfriend, run-loader
819   // and raw-reader.
820
821   static const TEveException kEH("AliEveEventManager::Close ");
822
823   if (!fIsOpen)
824   {
825     throw (kEH + "Event-files not opened.");
826   }
827
828   if (fAutoLoadTimerRunning)
829     StopAutoLoadTimer();
830
831   if (fESDTree) {
832     delete fESD;       fESD       = 0;
833     delete fESDfriend; fESDfriend = 0;
834     fESDfriendExists = kFALSE;
835
836     delete fESDTree;   fESDTree = 0;
837     delete fESDFile;   fESDFile = 0;
838   }
839
840   if (fAODTree) {
841     delete fAOD;       fAOD       = 0;
842
843     delete fAODTree;   fAODTree = 0;
844     delete fAODFile;   fAODFile = 0;
845   }
846
847   if (fRunLoader) {
848     delete fRunLoader; fRunLoader = 0;
849   }
850
851   if (fRawReader) {
852     delete fRawReader; fRawReader = 0;
853   }
854
855   fEventId  = -1;
856   fIsOpen   = kFALSE;
857   fHasEvent = kFALSE;
858 }
859
860
861 //------------------------------------------------------------------------------
862 // Static convenience functions, mainly used from macros.
863 //------------------------------------------------------------------------------
864
865 Bool_t AliEveEventManager::HasRunLoader()
866 {
867   // Check if AliRunLoader is initialized.
868
869   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRunLoader;
870 }
871
872 Bool_t AliEveEventManager::HasESD()
873 {
874   // Check if AliESDEvent is initialized.
875
876   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESD;
877 }
878
879 Bool_t AliEveEventManager::HasESDfriend()
880 {
881   // Check if AliESDfriend is initialized.
882
883   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESDfriend;
884 }
885
886 Bool_t AliEveEventManager::HasAOD()
887 {
888   // Check if AliESDEvent is initialized.
889
890   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fAOD;
891 }
892
893 Bool_t AliEveEventManager::HasRawReader()
894 {
895   // Check if raw-reader is initialized.
896
897   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRawReader;
898 }
899
900 AliRunLoader* AliEveEventManager::AssertRunLoader()
901 {
902   // Make sure AliRunLoader is initialized and return it.
903   // Throws exception in case run-loader is not available.
904   // Static utility for macros.
905
906   static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
907
908   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
909     throw (kEH + "ALICE event not ready.");
910   if (fgCurrent->fRunLoader == 0)
911     throw (kEH + "AliRunLoader not initialised.");
912   return fgCurrent->fRunLoader;
913 }
914
915 AliESDEvent* AliEveEventManager::AssertESD()
916 {
917   // Make sure AliESDEvent is initialized and return it.
918   // Throws exception in case ESD is not available.
919   // Static utility for macros.
920
921   static const TEveException kEH("AliEveEventManager::AssertESD ");
922
923   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
924     throw (kEH + "ALICE event not ready.");
925   if (fgCurrent->fESD == 0)
926     throw (kEH + "AliESD not initialised.");
927   return fgCurrent->fESD;
928 }
929
930 AliESDfriend* AliEveEventManager::AssertESDfriend()
931 {
932   // Make sure AliESDfriend is initialized and return it.
933   // Throws exception in case ESDfriend-loader is not available.
934   // Static utility for macros.
935
936   static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
937
938   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
939     throw (kEH + "ALICE event not ready.");
940   if (fgCurrent->fESDfriend == 0)
941     throw (kEH + "AliESDfriend not initialised.");
942   return fgCurrent->fESDfriend;
943 }
944
945 AliAODEvent* AliEveEventManager::AssertAOD()
946 {
947   // Make sure AliAODEvent is initialized and return it.
948   // Throws exception in case AOD is not available.
949   // Static utility for macros.
950
951   static const TEveException kEH("AliEveEventManager::AssertAOD ");
952
953   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
954     throw (kEH + "ALICE event not ready.");
955   if (fgCurrent->fAOD == 0)
956     throw (kEH + "AliAOD not initialised.");
957   return fgCurrent->fAOD;
958 }
959
960 AliRawReader* AliEveEventManager::AssertRawReader()
961 {
962   // Make sure raw-reader is initialized and return it.
963
964   static const TEveException kEH("AliEveEventManager::AssertRawReader ");
965
966   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
967     throw (kEH + "ALICE event not ready.");
968   if (fgCurrent->fRawReader == 0)
969     throw (kEH + "RawReader not ready.");
970
971   return fgCurrent->fRawReader;
972 }
973
974 //==============================================================================
975
976 AliMagF* AliEveEventManager::AssertMagField()    
977 {        
978   // Make sure AliMagF is initialized and returns it.    
979   // Throws exception in case magnetic field is not available.   
980   // Static utility for macros.          
981
982   static const TEveException kEH("AliEveEventManager::AssertMagField ");         
983                  
984   if (fgMagField)
985     return fgMagField;
986
987   if (!fgGRPLoaded)
988   {
989     InitGRP();
990   }
991
992   if (TGeoGlobalMagField::Instance())
993   {
994     fgMagField = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField());
995     if (fgMagField == 0)
996       throw kEH + "Global field set, but it is not AliMagF.";
997   }
998   else
999   {
1000     throw kEH + "Could not initialize magnetic field.";
1001   }
1002
1003   return fgMagField;     
1004 }
1005
1006 TGeoManager* AliEveEventManager::AssertGeometry()
1007 {
1008   // Make sure AliGeomManager is initialized and returns the
1009   // corresponding TGeoManger.
1010   // gGeoManager is set to the return value.
1011   // Throws exception if geometry can not be loaded or if it is not
1012   // available and the TGeoManager is locked.
1013   // Static utility for macros.
1014
1015   static const TEveException kEH("AliEveEventManager::AssertGeometry ");
1016
1017   if (AliGeomManager::GetGeometry() == 0)
1018   {
1019     if (TGeoManager::IsLocked())
1020       throw (kEH + "geometry is not loaded but TGeoManager is locked.");
1021
1022     gGeoManager = 0;
1023     AliGeomManager::LoadGeometry();
1024     if ( ! AliGeomManager::GetGeometry())
1025     {
1026       throw (kEH + "can not load geometry.");
1027     }
1028     if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
1029     {
1030       ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
1031       // throw (kEH + "could not apply align objs.");
1032     }
1033     AliGeomManager::GetGeometry()->DefaultColors();
1034   }
1035
1036   gGeoManager = AliGeomManager::GetGeometry();
1037   return gGeoManager;
1038 }
1039
1040 //------------------------------------------------------------------------------
1041
1042 AliEveEventManager* AliEveEventManager::AddDependentManager(const TString& name, const TString& path)
1043 {
1044   // Create and attach a dependent event-manager.
1045   // It is not added into eve list tree.
1046
1047   static const TEveException kEH("AliEveEventManager::AddDependentManager ");
1048
1049   if (fgMaster == 0)
1050     throw(kEH + "Master event-manager must be instantiated first.");
1051
1052   if (fgMaster->fSubManagers == 0)
1053   {
1054     fgMaster->fSubManagers = new TList;
1055     fgMaster->fSubManagers->SetOwner(kTRUE);
1056   }
1057
1058   AliEveEventManager* new_mgr = 0;
1059   fgCurrent = 0;
1060   try
1061   {
1062     new_mgr = new AliEveEventManager(name, path, fgMaster->fEventId);
1063     fgMaster->fSubManagers->Add(new_mgr);
1064   }
1065   catch (TEveException& exc)
1066   {
1067     ::Error(kEH, "Creation of new event-manager failed: '%s'.", exc.Data());
1068   }
1069   fgCurrent = fgMaster;
1070
1071   return new_mgr;
1072 }
1073
1074 AliEveEventManager* AliEveEventManager::GetDependentManager(const TString& name)
1075 {
1076   // Get a dependant manager by name.
1077   // This will not change the current manager, use helper class
1078   // AliEveEventManager::CurrentChanger for that.
1079
1080   static const TEveException kEH("AliEveEventManager::GetDependentManager ");
1081
1082   if (fgMaster == 0)
1083     throw(kEH + "Master event-manager must be instantiated first.");
1084
1085   if (fgMaster->fSubManagers == 0)
1086     return 0;
1087
1088   return dynamic_cast<AliEveEventManager*>(fgMaster->fSubManagers->FindObject(name));
1089 }
1090
1091 AliEveEventManager* AliEveEventManager::GetMaster()
1092 {
1093   // Get master event-manager.
1094
1095   return fgMaster;
1096 }
1097
1098 AliEveEventManager* AliEveEventManager::GetCurrent()
1099 {
1100   // Get current event-manager.
1101
1102   return fgCurrent;
1103 }
1104
1105 void AliEveEventManager::RegisterTransient(TEveElement* element)
1106 {
1107   GetCurrent()->fTransients->AddElement(element);
1108 }
1109
1110 void AliEveEventManager::RegisterTransientList(TEveElement* element)
1111 {
1112   GetCurrent()->fTransientLists->AddElement(element);
1113 }
1114
1115 //------------------------------------------------------------------------------
1116 // Autoloading of events
1117 //------------------------------------------------------------------------------
1118
1119 void AliEveEventManager::SetAutoLoadTime(Float_t time)
1120 {
1121   // Set the auto-load time in seconds
1122
1123   fAutoLoadTime = time;
1124 }
1125
1126 void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
1127 {
1128   // Set the automatic event loading mode
1129
1130   static const TEveException kEH("AliEveEventManager::SetAutoLoad ");
1131
1132   if (fAutoLoad == autoLoad)
1133   {
1134     Warning(kEH, "Setting autoload to the same value as before - %s. Ignoring.", fAutoLoad ? "true" : "false");
1135     return;
1136   }
1137
1138   fAutoLoad = autoLoad;
1139   if (fAutoLoad)
1140   {
1141     StartAutoLoadTimer();
1142   }
1143   else
1144   {
1145     StopAutoLoadTimer();
1146   }
1147 }
1148
1149 void AliEveEventManager::StartAutoLoadTimer()
1150 {
1151   // Start the auto-load timer.
1152
1153   fAutoLoadTimer->SetTime((Long_t)(1000*fAutoLoadTime));
1154   fAutoLoadTimer->Reset();
1155   fAutoLoadTimer->TurnOn();
1156   fAutoLoadTimerRunning = kTRUE;
1157 }
1158
1159 void AliEveEventManager::StopAutoLoadTimer()
1160 {
1161   // Stop the auto-load timer.
1162
1163   fAutoLoadTimerRunning = kFALSE;
1164   fAutoLoadTimer->TurnOff();
1165 }
1166
1167 void AliEveEventManager::AutoLoadNextEvent()
1168 {
1169   // Called from auto-load timer, so it has to be public.
1170   // Do NOT call it directly.
1171
1172   static const TEveException kEH("AliEveEventManager::AutoLoadNextEvent ");
1173
1174   if ( ! fAutoLoadTimerRunning || ! fAutoLoadTimer->HasTimedOut())
1175   {
1176     Warning(kEH, "Called unexpectedly - ignoring the call. Should ONLY be called from an internal timer.");
1177     return;
1178   }
1179
1180   StopAutoLoadTimer();
1181   NextEvent();
1182   if (fAutoLoad && !fExternalCtrl)
1183     StartAutoLoadTimer();
1184 }
1185
1186 //------------------------------------------------------------------------------
1187 // Post event-loading functions
1188 //------------------------------------------------------------------------------
1189
1190 void AliEveEventManager::AfterNewEventLoaded()
1191 {
1192   // Execute registered macros and commands.
1193   // At the end emit NewEventLoaded signal.
1194   //
1195   // Virtual from TEveEventManager.
1196
1197   static const TEveException kEH("AliEveEventManager::AfterNewEventLoaded ");
1198
1199   if (fExecutor)
1200     fExecutor->ExecMacros();
1201
1202   TEveEventManager::AfterNewEventLoaded();
1203
1204   NewEventLoaded();
1205
1206   if (this == fgMaster && fSubManagers != 0)
1207   {
1208     TIter next(fSubManagers);
1209     while ((fgCurrent = dynamic_cast<AliEveEventManager*>(next())) != 0)
1210     {
1211       gEve->SetCurrentEvent(fgCurrent);
1212       try
1213       {
1214         fgCurrent->GotoEvent(fEventId);
1215       }
1216       catch (TEveException& exc)
1217       {
1218         // !!! Should somehow tag / disable / remove it?
1219         Error(kEH, "Getting event %d for sub-event-manager '%s' failed: '%s'.",
1220               fEventId, fgCurrent->GetName(), exc.Data());
1221       }
1222     }
1223     fgCurrent = fgMaster;
1224     gEve->SetCurrentEvent(fgMaster);
1225   }
1226 }
1227
1228 void AliEveEventManager::NewEventLoaded()
1229 {
1230   // Emit NewEventLoaded signal.
1231
1232   Emit("NewEventLoaded()");
1233 }
1234
1235
1236 //------------------------------------------------------------------------------
1237 // Event info dumpers
1238 //------------------------------------------------------------------------------
1239
1240 TString AliEveEventManager::GetEventInfoHorizontal() const
1241 {
1242   // Dumps the event-header contents in vertical formatting.
1243
1244   TString rawInfo, esdInfo;
1245
1246   if (!fRawReader)
1247   {
1248     rawInfo = "No raw-data event info is available!\n";
1249   }
1250   else
1251   {
1252     const UInt_t* attr = fRawReader->GetAttributes();
1253     TTimeStamp ts(fRawReader->GetTimestamp());
1254     rawInfo.Form("RAW event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1255                  "Trigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x  Timestamp: %s\n",
1256                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1257                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1258                  fRawReader->GetClassMask(),
1259                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1260                  attr[0],attr[1],attr[2], ts.AsString("s"));
1261   }
1262
1263   if (!fESD)
1264   {
1265     esdInfo = "No ESD event info is available!";
1266   }
1267   else
1268   {
1269     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1270     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1271     TTimeStamp ts(fESD->GetTimeStamp());
1272     esdInfo.Form("ESD event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1273                  "Active trigger classes: %s\nTrigger: %llx (%s)\nEvent# in file: %d  Timestamp: %s, MagField: %.2e",
1274                  fESD->GetRunNumber(),
1275                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1276                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1277                  acttrclasses.Data(),
1278                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1279                  fESD->GetEventNumberInFile(), ts.AsString("s"), fESD->GetMagneticField());
1280   }
1281
1282   return rawInfo + esdInfo;
1283 }
1284
1285 TString AliEveEventManager::GetEventInfoVertical() const
1286 {
1287   // Dumps the event-header contents in vertical formatting.
1288
1289   TString rawInfo, esdInfo;
1290
1291   if (!fRawReader)
1292   {
1293     rawInfo = "No raw-data event info is available!\n";
1294   }
1295   else
1296   {
1297     const UInt_t* attr = fRawReader->GetAttributes();
1298     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",
1299                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1300                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1301                  fRawReader->GetClassMask(),
1302                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1303                  attr[0],attr[1],attr[2],
1304                  fRawReader->GetTimestamp());
1305   }
1306
1307   if (!fESD)
1308   {
1309     esdInfo = "No ESD event info is available!\n";
1310   }
1311   else
1312   {
1313     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1314     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1315     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",
1316                  fESD->GetRunNumber(),
1317                  acttrclasses.Data(),
1318                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1319                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1320                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1321                  fESD->GetEventNumberInFile(),
1322                  fESD->GetTimeStamp());
1323   }
1324
1325   return rawInfo + "\n" + esdInfo;
1326 }
1327
1328
1329 //==============================================================================
1330 // Reading of GRP and MagneticField.
1331 // This is a reap-off from reconstruction ... should really be a common
1332 // code to do this somewhere in STEER.
1333 //==============================================================================
1334
1335 Bool_t AliEveEventManager::InitGRP()
1336 {
1337   //------------------------------------
1338   // Initialization of the GRP entry 
1339   //------------------------------------
1340
1341   static const TEveException kEH("AliEveEventManager::InitGRP ");
1342
1343   AliGRPManager grpMgr;
1344   if (!grpMgr.ReadGRPEntry()) {
1345     return kFALSE;
1346   }
1347   fgGRPLoaded = kTRUE;
1348   if (!grpMgr.SetMagField()) {
1349     throw kEH + "Setting of field failed!";
1350   }
1351
1352   //*** Get the diamond profiles from OCDB
1353   // Eventually useful.
1354
1355   /*
1356     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1357     if (entry) {
1358     fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1359     } else {
1360     ::Error(kEH, "No SPD diamond profile found in OCDB!");
1361     }
1362
1363     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1364     if (entry) {
1365     fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1366     } else {
1367     ::Error(kEH, "No diamond profile found in OCDB!");
1368     }
1369
1370     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1371     if (entry) {
1372     fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1373     } else {
1374     ::Error(kEH, "No TPC diamond profile found in OCDB!");
1375     }
1376   */
1377
1378   return kTRUE;
1379