First version of the new GUI in development. You can enable this UI with "alieve...
[u/mrichter/AliRoot.git] / EVE / EveBase / AliEveEventManager.cxx
1 // $Id$
2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4 /**************************************************************************
5  * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
7  * full copyright notice.                                                 *
8  **************************************************************************/
9
10 #include "AliEveEventManager.h"
11 #include "AliEveEventSelector.h"
12 #include "AliEveMacroExecutor.h"
13
14 #include <THashList.h>
15 #include <TEveElement.h>
16 #include <TEveManager.h>
17 #include <TEveViewer.h>
18
19 #include <AliLog.h>
20 #include <AliRunLoader.h>
21 #include <AliRun.h>
22 #include <AliESDRun.h>
23 #include <AliESDEvent.h>
24 #include <AliESDfriend.h>
25 #include <AliAODEvent.h>
26
27 #include <AliRecoParam.h>
28 #include <AliCentralTrigger.h>
29 #include <AliCDBEntry.h>
30 #include <AliTriggerClass.h>
31 #include <AliTriggerConfiguration.h>
32 #include <AliTriggerCluster.h>
33 #include <AliDetectorRecoParam.h>
34
35 #include <AliDAQ.h>
36 #include <AliRawEventHeaderBase.h>
37 #include <AliRawReaderRoot.h>
38 #include <AliRawReaderFile.h>
39 #include <AliRawReaderDate.h>
40 #include <AliMagF.h>
41 #include <AliCDBManager.h>
42 #include <AliCDBStorage.h>
43 #include <AliGRPObject.h>
44 #include <AliHeader.h>
45 #include <AliGeomManager.h>
46 #include <AliGRPManager.h>
47 #include <AliSysInfo.h>
48
49 #include <TFile.h>
50 #include <TTree.h>
51 #include <TGeoManager.h>
52 #include <TGeoGlobalMagField.h>
53 #include <TSystem.h>
54 #include <TTimeStamp.h>
55 #include <TPRegexp.h>
56 #include <TError.h>
57 #include <TEnv.h>
58 #include <TString.h>
59 #include <TMap.h>
60
61 //==============================================================================
62 //==============================================================================
63 // AliEveEventManager
64 //==============================================================================
65
66 //______________________________________________________________________________
67 //
68 // Provides interface for loading and navigating standard AliRoot data
69 // (AliRunLoader), ESD, AOD and RAW.
70 //
71 // ESDfriend is attached automatically, if the file is found.
72 //
73 // AODfriends are not attached automatically as there are several
74 // possible files involved. To have a specific AODfriend attached, call
75 // static method
76 //   AliEveEventManager::AddAODfriend("AliAOD.VertexingHF.root");
77 // before initializing the event-manager.
78 //
79 // Also provides interface to magnetic-field and geometry. Mostly
80 // intended as wrappers over standard AliRoot functionality for
81 // convenient use from visualizateion macros.
82 //
83 // There can be a single main event-manger, it is stored in private
84 // data member fgMaster and can be accessed via static member function
85 // GetMaster().
86 //
87 // For event overlaying and embedding one can instantiate additional
88 // event-managers via static method AddDependentManager(const TString& path).
89 // This interface is under development.
90
91 ClassImp(AliEveEventManager)
92
93 Bool_t AliEveEventManager::fgAssertRunLoader = kFALSE;
94 Bool_t AliEveEventManager::fgAssertESD       = kFALSE;
95 Bool_t AliEveEventManager::fgAssertAOD       = kFALSE;
96 Bool_t AliEveEventManager::fgAssertRaw       = kFALSE;
97
98 TString  AliEveEventManager::fgESDFileName("AliESDs.root");
99 TString  AliEveEventManager::fgESDfriendsFileName("AliESDfriends.root");
100 TString  AliEveEventManager::fgAODFileName("AliAOD.root");
101 TString  AliEveEventManager::fgGAlice("galice.root");
102 TString  AliEveEventManager::fgRawFileName("raw.root");
103 TString  AliEveEventManager::fgCdbUri;
104
105 TList*   AliEveEventManager::fgAODfriends = 0;
106
107 Bool_t   AliEveEventManager::fgRawFromStandardLoc = kFALSE;
108
109 Bool_t   AliEveEventManager::fgGRPLoaded    = kFALSE;
110 AliMagF* AliEveEventManager::fgMagField     = 0;
111 AliRecoParam* AliEveEventManager::fgRecoParam = 0;
112 Bool_t   AliEveEventManager::fgUniformField = kFALSE;
113
114 AliEveEventManager* AliEveEventManager::fgMaster  = 0;
115 AliEveEventManager* AliEveEventManager::fgCurrent = 0;
116
117 void AliEveEventManager::InitInternals()
118 {
119     // Initialize internal members.
120
121     static const TEveException kEH("AliEveEventManager::InitInternals ");
122
123     if (fgCurrent != 0)
124     {
125         throw(kEH + "Dependent event-managers should be created via static method AddDependentManager().");
126     }
127
128     if (fgMaster == 0)
129     {
130         fgMaster = this;
131     }
132
133     fgCurrent = this;
134
135     fAutoLoadTimer = new TTimer;
136     fAutoLoadTimer->Connect("Timeout()", "AliEveEventManager", this, "AutoLoadNextEvent()");
137     fAutoLoadTimer->Connect("Timeout()", "AliEveEventManager", this, "Timeout()");
138
139     fExecutor = new AliEveMacroExecutor;
140
141     fTransients = new TEveElementList("Transients", "Transient per-event elements.");
142     fTransients->IncDenyDestroy();
143     gEve->AddToListTree(fTransients, kFALSE);
144
145     fTransientLists = new TEveElementList("Transient Lists", "Containers of transient elements.");
146     fTransientLists->IncDenyDestroy();
147     gEve->AddToListTree(fTransientLists, kFALSE);
148
149     fPEventSelector = new AliEveEventSelector(this);
150
151     fGlobal = new TMap; fGlobal->SetOwnerKeyValue();
152 }
153
154 AliEveEventManager::AliEveEventManager(const TString& name) :
155     TEveEventManager(name),
156
157     fPath      ( ), fEventId (-1),
158     fRunLoader (0),
159     fESDFile   (0), fESDTree (0), fESD (0),
160     fESDfriend (0), fESDfriendExists(kFALSE),
161     fAODFile   (0), fAODTree (0), fAOD (0),
162     fRawReader (0), fEventInfo(),
163     fAutoLoad  (kFALSE), fAutoLoadTime (5.),     fAutoLoadTimer(0),
164     fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
165     fGlobal    (0), fGlobalReplace (kTRUE), fGlobalUpdate (kTRUE),
166     fExecutor    (0), fTransients(0), fTransientLists(0),
167     fPEventSelector(0),
168     fSubManagers (0),
169     fAutoLoadTimerRunning(kFALSE)
170 {
171     // Default constructor.
172
173     InitInternals();
174 }
175
176 AliEveEventManager::AliEveEventManager(const TString& name, const TString& path, Int_t ev) :
177     TEveEventManager(name, path),
178
179     fPath   (path), fEventId(-1),
180     fRunLoader (0),
181     fESDFile   (0), fESDTree (0), fESD (0),
182     fESDfriend (0), fESDfriendExists(kFALSE),
183     fAODFile   (0), fAODTree (0), fAOD (0),
184     fRawReader (0), fEventInfo(),
185     fAutoLoad  (kFALSE), fAutoLoadTime (5),      fAutoLoadTimer(0),
186     fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
187     fGlobal    (0), fGlobalReplace (kTRUE), fGlobalUpdate (kTRUE),
188     fExecutor    (0), fTransients(0), fTransientLists(0),
189     fPEventSelector(0),
190     fSubManagers (0),
191     fAutoLoadTimerRunning(kFALSE)
192 {
193     // Constructor with event-directory URL and event-id.
194
195     InitInternals();
196
197     Open();
198     if (ev >= 0)
199     {
200         GotoEvent(ev);
201     }
202 }
203
204 AliEveEventManager::~AliEveEventManager()
205 {
206     // Destructor.
207     fAutoLoadTimer->Stop();
208     fAutoLoadTimer->Disconnect("Timeout");
209
210     delete fSubManagers;
211
212     if (fIsOpen)
213     {
214         Close();
215     }
216
217     fTransients->DecDenyDestroy();
218     fTransients->Destroy();
219
220     fTransientLists->DecDenyDestroy();
221     fTransientLists->Destroy();
222
223     //delete fExecutor;
224 }
225
226 /******************************************************************************/
227
228 void AliEveEventManager::SetESDFileName(const TString& esd)
229 {
230     // Set file-name for opening ESD, default "AliESDs.root".
231
232     if ( ! esd.IsNull()) fgESDFileName = esd;
233 }
234
235 void AliEveEventManager::SetAODFileName(const TString& aod)
236 {
237     // Set file-name for opening AOD, default "AliAOD.root".
238
239     if ( ! aod.IsNull()) fgAODFileName = aod;
240 }
241
242 void AliEveEventManager::AddAODfriend(const TString& friendFileName)
243 {
244     // Add new AOD friend file-name to be attached when opening AOD.
245     // This should include '.root', as in 'AliAOD.VertexingHF.root'.
246
247     if (fgAODfriends == 0)
248     {
249         fgAODfriends = new TList;
250         fgAODfriends->SetOwner(kTRUE);
251     }
252     if (fgAODfriends->FindObject(friendFileName) == 0)
253     {
254         fgAODfriends->Add(new TObjString(friendFileName));
255     }
256 }
257
258 void AliEveEventManager::SetRawFileName(const TString& raw)
259 {
260     // Set file-name for opening of raw-data, default "raw.root"
261     if ( ! raw.IsNull()) fgRawFileName = raw;
262 }
263
264 void AliEveEventManager::SetCdbUri(const TString& cdb)
265 {
266     // Set path to CDB, there is no default.
267
268     if ( ! cdb.IsNull()) fgCdbUri = cdb;
269 }
270
271 void AliEveEventManager::SetAssertElements(Bool_t assertRunloader, Bool_t assertEsd,
272                                            Bool_t assertAod, Bool_t assertRaw)
273 {
274     // Set global flags that detrmine which parts of the event-data must
275     // be present when the event is opened.
276
277     fgAssertRunLoader = assertRunloader;
278     fgAssertESD = assertEsd;
279     fgAssertAOD = assertAod;
280     fgAssertRaw = assertRaw;
281 }
282
283 void AliEveEventManager::SearchRawForCentralReconstruction()
284 {
285     // Enable searching of raw data in standard location. The path passed to
286     // Open() is expected to point to a centrally reconstructed run, e.g.:
287     // "alien:///alice/data/2009/LHC09c/000101134/ESDs/pass1/09000101134018.10".
288
289     fgRawFromStandardLoc = kTRUE;
290 }
291
292 /******************************************************************************/
293
294 void AliEveEventManager::Open()
295 {
296     // Open event-data from URL specified in fPath.
297     // Attempts to create AliRunLoader() and to open ESD with ESDfriends.
298     // Warning is reported if run-loader or ESD is not found.
299     // Global data-members fgAssertRunLoader and fgAssertESD can be set
300     // to throw exceptions instead.
301
302     static const TEveException kEH("AliEveEventManager::Open ");
303
304     if (fExternalCtrl)
305     {
306         throw (kEH + "Event-loop is under external control.");
307     }
308     if (fIsOpen)
309     {
310         throw (kEH + "Event-files already opened.");
311     }
312
313     gSystem->ExpandPathName(fPath);
314     // The following magick is required for ESDfriends to be loaded properly
315     // from non-current directory.
316     if (fPath.IsNull() || fPath == ".")
317     {
318         fPath = gSystem->WorkingDirectory();
319     }
320     else if ( ! fPath.BeginsWith("file:/"))
321     {
322         TUrl    url(fPath, kTRUE);
323         TString protocol(url.GetProtocol());
324         if (protocol == "file" && fPath[0] != '/')
325             fPath = Form("%s/%s", gSystem->WorkingDirectory(), fPath.Data());
326     }
327
328     Int_t runNo = -1;
329
330     // Open ESD and ESDfriends
331
332     TString esdPath(Form("%s", fgESDFileName.Data()));
333     if (fgESDFileName.EndsWith(".zip")) esdPath.Form("%s#AliESDs.root",fgESDFileName.Data());
334     if ((fESDFile = TFile::Open(esdPath)))
335     {
336         fESD = new AliESDEvent();
337         fESDTree = (TTree*) fESDFile->Get("esdTree");
338         if (fESDTree != 0)
339         {
340             // Check if ESDfriends exists and attach the branch.
341             // We use TFile::Open() instead of gSystem->AccessPathName
342             // as it seems to work better when attachine alieve to a
343             // running reconstruction process with auto-save on.
344             TString p(fgESDfriendsFileName);
345             if (fgESDfriendsFileName.EndsWith(".zip")) p.Form("%s#AliESDfriends.root",fgESDfriendsFileName.Data());
346             TFile *esdFriendFile = TFile::Open(p);
347             if (esdFriendFile)
348             {
349                 if (!esdFriendFile->IsZombie())
350                 {
351                     esdFriendFile->Close();
352                     fESDfriendExists = kTRUE;
353                     fESDTree->SetBranchStatus ("ESDfriend*", 1);
354                 }
355                 delete esdFriendFile;
356             }
357
358             fESD->ReadFromTree(fESDTree);
359             if (fESDfriendExists)
360             {
361                 fESDfriend = (AliESDfriend*) fESD->FindListObject("AliESDfriend");
362                 Info(kEH, "found and attached ESD friend.");
363             }
364             else
365             {
366                 Warning(kEH, "ESDfriend not found.");
367             }
368
369             if (fESDTree->GetEntry(0) <= 0)
370             {
371                 delete fESDFile; fESDFile = 0;
372                 delete fESD; fESD = 0;
373                 Warning(kEH, "failed getting the first entry from esdTree.");
374             }
375             else
376             {
377                 if (runNo < 0)
378                     runNo = fESD->GetESDRun()->GetRunNumber();
379             }
380         }
381         else // esdtree == 0
382         {
383             delete fESDFile; fESDFile = 0;
384             delete fESD; fESD = 0;
385             Warning(kEH, "failed getting the esdTree.");
386         }
387     }
388     else // esd not readable
389     {
390         Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
391     }
392     if (fESDTree == 0)
393     {
394         if (fgAssertESD)
395         {
396             throw (kEH + "ESD not initialized. Its precence was requested.");
397         } else {
398             Warning(kEH, "ESD not initialized.");
399         }
400     }
401
402     // Open AOD and registered friends
403
404     TString aodPath(Form("%s", fgAODFileName.Data()));
405     if (fgAODFileName.EndsWith(".zip")) aodPath.Form("%s#AliAOD.root",fgAODFileName.Data());
406     if ((fAODFile = TFile::Open(aodPath)))
407     {
408         fAOD = new AliAODEvent();
409         fAODTree = (TTree*) fAODFile->Get("aodTree");
410         if (fAODTree != 0)
411         {
412             // Check if AODfriends exist and attach them.
413             TIter       friends(fgAODfriends);
414             TObjString *name;
415             while ((name = (TObjString*) friends()) != 0)
416             {
417                 TString p(Form("%s/%s", fgAODFileName.Data(), name->GetName()));
418                 if (fgAODFileName.EndsWith(".zip")) p.Form("%s#%s",fgAODFileName.Data(),name->GetName());
419                 if (gSystem->AccessPathName(p, kReadPermission) == kFALSE)
420                 {
421                     fAODTree->AddFriend("aodTree", name->GetName());
422                 }
423             }
424
425             fAOD->ReadFromTree(fAODTree);
426
427             if (fAODTree->GetEntry(0) <= 0)
428             {
429                 delete fAODFile; fAODFile = 0;
430                 delete fAOD;     fAOD     = 0;
431                 Warning(kEH, "failed getting the first entry from addTree.");
432             }
433             else
434             {
435                 if (runNo < 0)
436                     runNo = fAOD->GetRunNumber();
437             }
438         }
439         else // aodtree == 0
440         {
441             delete fAODFile; fAODFile = 0;
442             delete fAOD;     fAOD     = 0;
443             Warning(kEH, "failed getting the aodTree.");
444         }
445     }
446     else // aod not readable
447     {
448         Warning(kEH, "can not read AOD file '%s'.", aodPath.Data());
449     }
450     if (fAODTree == 0)
451     {
452         if (fgAssertAOD)
453         {
454             throw (kEH + "AOD not initialized. Its precence was requested.");
455         } else {
456             Warning(kEH, "AOD not initialized.");
457         }
458     }
459
460     // Open RunLoader from galice.root
461
462     TString gaPath(Form("%s", fgGAlice.Data()));
463     if (fgGAlice.EndsWith(".zip")) gaPath.Form("%s#galice.root",fgGAlice.Data());
464     // If i use open directly, we get fatal.
465     // Is AccessPathName check ok for xrootd / alien? Yes, not for http.
466     // Seems not to work for alien anymore.
467     // Fixed in ROOT on 27.10.2009, rev 30888.
468     // To revert after we move to root-5.26.
469     TFile *gafile = TFile::Open(gaPath);
470     if (gafile)
471     {
472         gafile->Close();
473         delete gafile;
474         // if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
475         // {
476         fRunLoader = AliRunLoader::Open(gaPath, GetName());
477         if (fRunLoader)
478         {
479             TString alicePath = fPath + "/";
480             fRunLoader->SetDirName(alicePath);
481
482             if (fRunLoader->LoadgAlice() != 0)
483                 Warning(kEH, "failed loading gAlice via run-loader.");
484
485             if (fRunLoader->LoadHeader() == 0)
486             {
487                 if (runNo < 0)
488                     runNo = fRunLoader->GetHeader()->GetRun();
489             }
490             else
491             {
492                 Warning(kEH, "failed loading run-loader's header.");
493                 delete fRunLoader;
494                 fRunLoader = 0;
495             }
496         }
497         else // run-loader open failed
498         {
499             Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
500         }
501     }
502     else // galice not readable
503     {
504         Warning(kEH, "can not read '%s'.", gaPath.Data());
505     }
506     if (fRunLoader == 0)
507     {
508         if (fgAssertRunLoader)
509             throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
510         else
511             Warning(kEH, "Bootstraping of run-loader failed.");
512     }
513
514     // Open raw-data file
515
516     TString rawPath;
517     if (fgRawFromStandardLoc)
518     {
519         if (!fPath.BeginsWith("alien:"))
520             throw kEH + "Standard raw search requested, but the directory is not in AliEn.";
521         if (!fPath.Contains("/ESDs/"))
522             throw kEH + "Standard raw search requested, but does not contain 'ESDs' directory.";
523
524         TPMERegexp chunk("/([\\d\\.])+/?$");
525         Int_t nm = chunk.Match(fPath);
526         if (nm != 2)
527             throw kEH + "Standard raw search requested, but the path does not end with chunk-id directory.";
528
529         TPMERegexp esdstrip("/ESDs/.*");
530         rawPath = fPath;
531         esdstrip.Substitute(rawPath, "/raw/");
532         rawPath += chunk[0];
533         rawPath += ".root";
534
535         Info(kEH, "Standard raw search requested, using the following path:\n  %s\n", rawPath.Data());
536     }
537     else
538     {
539         rawPath.Form("%s", fgRawFileName.Data());
540     }
541     // If i use open directly, raw-reader reports an error but i have
542     // no way to detect it.
543     // Is this (AccessPathName check) ok for xrootd / alien? Yes, not for http.
544     AliLog::EType_t oldLogLevel = (AliLog::EType_t) AliLog::GetGlobalLogLevel();
545     if (fgAssertRaw == kFALSE)
546     {
547         AliLog::SetGlobalLogLevel(AliLog::kFatal);
548     }
549     if (gSystem->AccessPathName(rawPath, kReadPermission) == kFALSE)
550     {
551         fRawReader = AliRawReader::Create(rawPath);
552     }
553     else
554     {
555         fRawReader = AliRawReader::Create(fgRawFileName);
556     }
557     if (fgAssertRaw == kFALSE)
558     {
559         AliLog::SetGlobalLogLevel(oldLogLevel);
560     }
561
562     if (fRawReader == 0)
563     {
564         if (fgAssertRaw)
565         {
566             throw (kEH + "raw-data not initialized. Its precence was requested.");
567         }
568         else
569         {
570             Warning(kEH, "raw-data not initialized.");
571         }
572     }
573
574     if (runNo < 0)
575     {
576         if (fRawReader)
577         {
578             if ( ! fRawReader->NextEvent())
579             {
580                 throw (kEH + "can not go to first event in raw-reader to determine run-id.");
581             }
582             runNo = fRawReader->GetRunNumber();
583             Info(kEH, "Determining run-no from raw ... run=%d.", runNo);
584             fRawReader->RewindEvents();
585         }
586         else
587         {
588             throw (kEH + "unknown run number.");
589         }
590     }
591
592     // Initialize OCDB ... only in master event-manager
593
594     if (this == fgMaster)
595     {
596         AliCDBManager* cdb = AliCDBManager::Instance();
597         if (cdb->IsDefaultStorageSet() == kTRUE)
598         {
599             Warning(kEH, "CDB already set - using the old storage:\n  '%s'",
600                     cdb->GetDefaultStorage()->GetURI().Data());
601         }
602         else
603         {
604             if (fgCdbUri.IsNull())
605             {
606                 gEnv->SetValue("Root.Stacktrace", "no");
607                 Fatal("Open()", "OCDB path was not specified.");
608             }
609
610             // Handle some special cases for MC (should be in OCDBManager).
611             if (fgCdbUri == "mcideal://")
612                 cdb->SetDefaultStorage("MC", "Ideal");
613             else if (fgCdbUri == "mcresidual://")
614                 cdb->SetDefaultStorage("MC", "Residual");
615             else if (fgCdbUri == "mcfull://")
616                 cdb->SetDefaultStorage("MC", "Full");
617             else if (fgCdbUri == "local://") {
618                 fgCdbUri = "local://$ALICE_ROOT/OCDB";
619                 cdb->SetDefaultStorage(fgCdbUri);
620             } else
621                 cdb->SetDefaultStorage(fgCdbUri);
622
623             cdb->SetRun(runNo);
624
625             if (cdb->IsDefaultStorageSet() == kFALSE)
626                 throw kEH + "CDB initialization failed for '" + fgCdbUri + "'.";
627         }
628
629         if (fgCdbUri.BeginsWith("local://"))
630         {
631             TString grp     = "GRP/GRP/Data";
632             TString grppath = fPath + "/" + grp;
633             if (gSystem->AccessPathName(grppath, kReadPermission) == kFALSE)
634             {
635                 if (cdb->GetSpecificStorage(grp))
636                 {
637                     Warning(kEH, "Local GRP exists, but the specific storage is already set.");
638                 }
639                 else
640                 {
641                     Info(kEH, "Setting CDB specific-storage for GRP from event directory.");
642                     TString lpath("local://");
643                     lpath += fPath;
644                     cdb->SetSpecificStorage(grp, lpath);
645                 }
646             }
647         }
648     }
649
650     fIsOpen = kTRUE;
651 }
652
653 void AliEveEventManager::SetEvent(AliRunLoader *runLoader, AliRawReader *rawReader, AliESDEvent *esd, AliESDfriend *esdf)
654 {
655     // Set an event from an external source.
656     // The method is used in the online visualisation.
657     // AOD is not supported.
658
659     static const TEveException kEH("AliEveEventManager::SetEvent ");
660
661     if (fIsOpen)
662     {
663         Warning(kEH, "Event-files were open. Closing and switching to external control.");
664         Close();
665     }
666
667     fRunLoader = runLoader;
668     fRawReader = rawReader;
669     fESD       = esd;
670     fESDfriend = esdf;
671     fAOD       = 0;
672
673     fEventId++;
674     fHasEvent     = kTRUE;
675     fExternalCtrl = kTRUE;
676
677     SetTitle("Online event in memory");
678     SetName ("Online Event");
679     ElementChanged();
680
681     AfterNewEventLoaded();
682
683     if (fAutoLoad) StartAutoLoadTimer();
684 }
685
686 Int_t AliEveEventManager::GetMaxEventId(Bool_t refreshESD) const
687 {
688     // Returns maximum available event id.
689     // If under external control or event is not opened -1 is returned.
690     // If raw-data is the only data-source this can not be known
691     // and 10,000,000 is returned.
692     // If neither data-source is initialised an exception is thrown.
693     // If refresh_esd is true and ESD is the primary event-data source
694     // its header is re-read from disk.
695
696     static const TEveException kEH("AliEveEventManager::GetMaxEventId ");
697
698     if (fExternalCtrl || fIsOpen == kFALSE)
699     {
700         return -1;
701     }
702
703     if (fESDTree)
704     {
705         if (refreshESD)
706         {
707             fESDTree->Refresh();
708             fPEventSelector->Update();
709         }
710         return fESDTree->GetEntries() - 1;
711     }
712     else if (fAODTree)
713     {
714         return fAODTree->GetEntries() - 1;
715     }
716     else if (fRunLoader)
717     {
718         return fRunLoader->GetNumberOfEvents() - 1;
719     }
720     else if (fRawReader)
721     {
722         Int_t n = fRawReader->GetNumberOfEvents() - 1;
723         return n > -1 ? n : 10000000;
724     }
725     else
726     {
727         throw (kEH + "neither ESD, AOD, RunLoader nor Raw loaded.");
728     }
729 }
730
731 void AliEveEventManager::GotoEvent(Int_t event)
732 {
733     // Load data for specified event.
734     // If event is out of range an exception is thrown and old state
735     // is preserved.
736     // After successful loading of event, the virtual function
737     // AfterNewEventLoaded() is called. This executes commands that
738     // were registered via TEveEventManager::AddNewEventCommand().
739     //
740     // If event is negative, it is subtracted from the number of
741     // available events, thus passing -1 will load the last event.
742     // This is not supported when raw-data is the only data-source
743     // as the number of events is not known.
744
745     static const TEveException kEH("AliEveEventManager::GotoEvent ");
746
747     if (fAutoLoadTimerRunning)
748     {
749         throw (kEH + "Event auto-load timer is running.");
750     }
751     if (fExternalCtrl)
752     {
753         throw (kEH + "Event-loop is under external control.");
754     }
755     else if (!fIsOpen)
756     {
757         throw (kEH + "Event-files not opened.");
758     }
759
760     fEventInfo.Reset();
761
762     fHasEvent = kFALSE;
763
764     Int_t maxEvent = 0;
765     if (fESDTree)
766     {
767         if (event >= fESDTree->GetEntries())
768             fESDTree->Refresh();
769         maxEvent = fESDTree->GetEntries() - 1;
770         if (event < 0)
771             event = fESDTree->GetEntries() + event;
772     }
773     else if (fAODTree)
774     {
775         maxEvent = fAODTree->GetEntries() - 1;
776         if (event < 0)
777             event = fAODTree->GetEntries() + event;
778     }
779     else if (fRunLoader)
780     {
781         maxEvent = fRunLoader->GetNumberOfEvents() - 1;
782         if (event < 0)
783             event = fRunLoader->GetNumberOfEvents() + event;
784     }
785     else if (fRawReader)
786     {
787         maxEvent = fRawReader->GetNumberOfEvents() - 1;
788         if (maxEvent < 0)
789         {
790             maxEvent = 10000000;
791             if (event < 0) {
792                 Error(kEH, "current raw-data source does not support direct event access.");
793                 return;
794             }
795             Info(kEH, "number of events unknown for current raw-data source, setting max-event id to 10M.");
796         }
797         else
798         {
799             if (event < 0)
800                 event = fRawReader->GetNumberOfEvents() + event;
801         }
802     }
803     else
804     {
805         throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
806     }
807     if (event < 0 || event > maxEvent)
808     {
809         throw (kEH + Form("event %d not present, available range [%d, %d].",
810                           event, 0, maxEvent));
811     }
812
813     TString sysInfoHeader;
814     sysInfoHeader.Form("AliEveEventManager::GotoEvent(%d) - ", event);
815     AliSysInfo::AddStamp(sysInfoHeader + "Start");
816
817     TEveManager::TRedrawDisabler rd(gEve);
818     gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
819
820     // !!! MT this is somewhat brutal; at least optionally, one could be
821     // a bit gentler, checking for objs owning their external refs and having
822     // additinal parents.
823     gEve->GetViewers()->DeleteAnnotations();
824     fTransients->DestroyElements();
825     for (TEveElement::List_i i = fTransientLists->BeginChildren();
826          i != fTransientLists->EndChildren(); ++i)
827     {
828         (*i)->DestroyElements();
829     }
830     DestroyElements();
831
832     AliSysInfo::AddStamp(sysInfoHeader + "PostDestroy");
833
834     if (fESDTree) {
835         if (fESDTree->GetEntry(event) <= 0)
836             throw (kEH + "failed getting required event from ESD.");
837
838         if (fESDfriendExists)
839             fESD->SetESDfriend(fESDfriend);
840     }
841
842     if (fAODTree) {
843         if (fAODTree->GetEntry(event) <= 0)
844             throw (kEH + "failed getting required event from AOD.");
845     }
846
847     if (fRunLoader) {
848         if (fRunLoader->GetEvent(event) != 0)
849             throw (kEH + "failed getting required event.");
850     }
851
852     if (fRawReader)
853     {
854         // AliRawReader::GotoEvent(Int_t) works for AliRawReaderRoot/Chain.
855         if (fRawReader->GotoEvent(event) == kFALSE)
856         {
857             // Use fallback method - iteration with NextEvent().
858             Int_t rawEv = fEventId;
859             if (event < rawEv)
860             {
861                 fRawReader->RewindEvents();
862                 rawEv = -1;
863             }
864
865             while (rawEv < event)
866             {
867                 if ( ! fRawReader->NextEvent())
868                 {
869                     fRawReader->RewindEvents();
870                     fEventId = -1;
871                     throw (kEH + Form("Error going to next raw-event from event %d.", rawEv));
872                 }
873                 ++rawEv;
874             }
875             Warning(kEH, "Loaded raw-event %d with fallback method.\n", rawEv);
876         }
877     }
878
879     fHasEvent = kTRUE;
880     fEventId  = event;
881     if (this == fgMaster)
882     {
883         SetName(Form("Event %d", fEventId));
884         ElementChanged();
885     }
886
887     AliSysInfo::AddStamp(sysInfoHeader + "PostLoadEvent");
888
889     AfterNewEventLoaded();
890
891     AliSysInfo::AddStamp(sysInfoHeader + "PostUserActions");
892 }
893
894 void AliEveEventManager::Timeout()
895 {
896     Emit("Timeout()");
897 }
898
899 void AliEveEventManager::NextEvent()
900 {
901     // Loads next event.
902     // Does magick needed for online display when under external event control.
903
904     static const TEveException kEH("AliEveEventManager::NextEvent ");
905
906     if (fAutoLoadTimerRunning)
907     {
908         throw (kEH + "Event auto-load timer is running.");
909     }
910
911     if (fExternalCtrl)
912     {
913         // !!! This should really go somewhere else. It is done in GotoEvent(),
914         // so here we should do it in SetEvent().
915         DestroyElements();
916         gSystem->ExitLoop();
917
918     }
919     else if (fESDTree)
920     {
921         Int_t nextevent=0;
922         if (fPEventSelector->FindNext(nextevent))
923         {
924             GotoEvent(nextevent);
925         }
926     }
927     else if (fEventId < GetMaxEventId(kTRUE))
928     {
929         GotoEvent(fEventId + 1);
930     }
931 }
932
933 void AliEveEventManager::PrevEvent()
934 {
935     // Loads previous event.
936
937     static const TEveException kEH("AliEveEventManager::PrevEvent ");
938
939     if (fAutoLoadTimerRunning)
940     {
941         throw (kEH + "Event auto-load timer is running.");
942     }
943     if (fExternalCtrl)
944     {
945         throw (kEH + "Event-loop is under external control.");
946     }
947
948     if (fESDTree)
949     {
950         Int_t nextevent=0;
951         if (fPEventSelector->FindPrev(nextevent))
952         {
953             GotoEvent(nextevent);
954         }
955     }
956     else if (fEventId > 0)
957     {
958         GotoEvent(fEventId - 1);
959     }
960 }
961
962 void AliEveEventManager::Close()
963 {
964     // Close the event data-files and delete ESD, ESDfriend, run-loader
965     // and raw-reader.
966
967     static const TEveException kEH("AliEveEventManager::Close ");
968
969     if (!fIsOpen)
970     {
971         throw (kEH + "Event-files not opened.");
972     }
973
974     if (fAutoLoadTimerRunning)
975         StopAutoLoadTimer();
976
977     if (fESDTree) {
978         delete fESD;       fESD       = 0;
979         // delete fESDfriend; // friend tree is deleted with the tree
980         fESDfriend = 0;
981         fESDfriendExists = kFALSE;
982
983         delete fESDTree;   fESDTree = 0;
984         delete fESDFile;   fESDFile = 0;
985     }
986
987     if (fAODTree) {
988         delete fAOD;       fAOD       = 0;
989
990         delete fAODTree;   fAODTree = 0;
991         delete fAODFile;   fAODFile = 0;
992     }
993
994     if (fRunLoader) {
995         delete fRunLoader; fRunLoader = 0;
996     }
997
998     if (fRawReader) {
999         delete fRawReader; fRawReader = 0;
1000     }
1001
1002     fEventId  = -1;
1003     fIsOpen   = kFALSE;
1004     fHasEvent = kFALSE;
1005 }
1006
1007
1008 //------------------------------------------------------------------------------
1009 // Static convenience functions, mainly used from macros.
1010 //------------------------------------------------------------------------------
1011
1012 Int_t AliEveEventManager::CurrentEventId()
1013 {
1014     // Return current event-id.
1015
1016     static const TEveException kEH("AliEveEventManager::CurrentEventId ");
1017
1018     if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
1019         throw (kEH + "ALICE event not ready.");
1020     return fgCurrent->GetEventId();
1021 }
1022
1023 Bool_t AliEveEventManager::HasRunLoader()
1024 {
1025     // Check if AliRunLoader is initialized.
1026
1027     return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRunLoader;
1028 }
1029
1030 Bool_t AliEveEventManager::HasESD()
1031 {
1032     // Check if AliESDEvent is initialized.
1033
1034     return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESD;
1035 }
1036
1037 Bool_t AliEveEventManager::HasESDfriend()
1038 {
1039     // Check if AliESDfriend is initialized.
1040
1041     return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESDfriend;
1042 }
1043
1044 Bool_t AliEveEventManager::HasAOD()
1045 {
1046     // Check if AliESDEvent is initialized.
1047
1048     return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fAOD;
1049 }
1050
1051 Bool_t AliEveEventManager::HasRawReader()
1052 {
1053     // Check if raw-reader is initialized.
1054
1055     return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRawReader;
1056 }
1057
1058 AliRunLoader* AliEveEventManager::AssertRunLoader()
1059 {
1060     // Make sure AliRunLoader is initialized and return it.
1061     // Throws exception in case run-loader is not available.
1062     // Static utility for macros.
1063
1064     static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
1065
1066     if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
1067         throw (kEH + "ALICE event not ready.");
1068     if (fgCurrent->fRunLoader == 0)
1069         throw (kEH + "AliRunLoader not initialised.");
1070     return fgCurrent->fRunLoader;
1071 }
1072
1073 AliESDEvent* AliEveEventManager::AssertESD()
1074 {
1075     // Make sure AliESDEvent is initialized and return it.
1076     // Throws exception in case ESD is not available.
1077     // Static utility for macros.
1078
1079     static const TEveException kEH("AliEveEventManager::AssertESD ");
1080
1081     if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
1082         throw (kEH + "ALICE event not ready.");
1083     if (fgCurrent->fESD == 0)
1084         throw (kEH + "AliESD not initialised.");
1085     return fgCurrent->fESD;
1086 }
1087
1088 AliESDfriend* AliEveEventManager::AssertESDfriend()
1089 {
1090     // Make sure AliESDfriend is initialized and return it.
1091     // Throws exception in case ESDfriend-loader is not available.
1092     // Static utility for macros.
1093
1094     static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
1095
1096     if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
1097         throw (kEH + "ALICE event not ready.");
1098     if (fgCurrent->fESDfriend == 0)
1099         throw (kEH + "AliESDfriend not initialised.");
1100     return fgCurrent->fESDfriend;
1101 }
1102
1103 AliAODEvent* AliEveEventManager::AssertAOD()
1104 {
1105     // Make sure AliAODEvent is initialized and return it.
1106     // Throws exception in case AOD is not available.
1107     // Static utility for macros.
1108
1109     static const TEveException kEH("AliEveEventManager::AssertAOD ");
1110
1111     if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
1112         throw (kEH + "ALICE event not ready.");
1113     if (fgCurrent->fAOD == 0)
1114         throw (kEH + "AliAOD not initialised.");
1115     return fgCurrent->fAOD;
1116 }
1117
1118 AliRawReader* AliEveEventManager::AssertRawReader()
1119 {
1120     // Make sure raw-reader is initialized and return it.
1121
1122     static const TEveException kEH("AliEveEventManager::AssertRawReader ");
1123
1124     if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
1125         throw (kEH + "ALICE event not ready.");
1126     if (fgCurrent->fRawReader == 0)
1127         throw (kEH + "RawReader not ready.");
1128
1129     return fgCurrent->fRawReader;
1130 }
1131
1132 //==============================================================================
1133
1134 AliMagF* AliEveEventManager::AssertMagField()    
1135 {        
1136     // Make sure AliMagF is initialized and returns it.
1137     // Throws exception in case magnetic field is not available.
1138     // Static utility for macros.
1139
1140     static const TEveException kEH("AliEveEventManager::AssertMagField ");
1141
1142     if (fgMagField)
1143         return fgMagField;
1144
1145     if (TGeoGlobalMagField::Instance()->GetField())
1146     {
1147         fgMagField = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField());
1148         if (fgMagField == 0)
1149             throw kEH + "Global field set, but it is not AliMagF.";
1150         return fgMagField;
1151     }
1152
1153     if (!fgGRPLoaded)
1154     {
1155         InitGRP();
1156     }
1157
1158     if (TGeoGlobalMagField::Instance()->GetField())
1159     {
1160         fgMagField = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField());
1161         if (fgMagField == 0)
1162             throw kEH + "Global field set, but it is not AliMagF.";
1163     }
1164     else
1165     {
1166         throw kEH + "Could not initialize magnetic field.";
1167     }
1168
1169     return fgMagField;
1170 }
1171
1172 TGeoManager* AliEveEventManager::AssertGeometry()
1173 {
1174     // Make sure AliGeomManager is initialized and returns the
1175     // corresponding TGeoManger.
1176     // gGeoManager is set to the return value.
1177     // Throws exception if geometry can not be loaded or if it is not
1178     // available and the TGeoManager is locked.
1179     // Static utility for macros.
1180
1181     static const TEveException kEH("AliEveEventManager::AssertGeometry ");
1182
1183     if (AliGeomManager::GetGeometry() == 0)
1184     {
1185         if (TGeoManager::IsLocked())
1186             throw (kEH + "geometry is not loaded but TGeoManager is locked.");
1187
1188         gGeoManager = 0;
1189         AliGeomManager::LoadGeometry();
1190         if ( ! AliGeomManager::GetGeometry())
1191         {
1192             throw (kEH + "can not load geometry.");
1193         }
1194         if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
1195         {
1196             ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
1197             // throw (kEH + "could not apply align objs.");
1198         }
1199         AliGeomManager::GetGeometry()->DefaultColors();
1200     }
1201
1202     gGeoManager = AliGeomManager::GetGeometry();
1203     return gGeoManager;
1204 }
1205
1206 AliRecoParam* AliEveEventManager::AssertRecoParams()
1207 {
1208     if(!fgRecoParam)
1209         InitRecoParam();
1210
1211     return fgRecoParam;
1212 }
1213
1214 Bool_t AliEveEventManager::InitRecoParam()
1215 {
1216     // This is mostly a reap-off from reconstruction
1217     // The method accesses OCDB and retrieves all
1218     // the available reco-param objects from there.
1219
1220     fgRecoParam = new AliRecoParam;
1221     const Int_t  kNDetectors = 14;
1222
1223     static const TEveException kEH("AliEveEventManager::InitRecoParam ");
1224
1225     Bool_t isOK = kTRUE;
1226
1227     if (fgRecoParam->GetDetRecoParamArray(kNDetectors)) {
1228         ::Info(kEH, "Using custom GRP reconstruction parameters");
1229     }
1230     else {
1231         ::Info(kEH, "Loading GRP reconstruction parameter objects");
1232
1233         AliCDBPath path("GRP","Calib","RecoParam");
1234         AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
1235         if(!entry){
1236             ::Warning(kEH, "Couldn't find GRP RecoParam entry in OCDB");
1237             isOK = kFALSE;
1238         }
1239         else {
1240             TObject *recoParamObj = entry->GetObject();
1241             if (dynamic_cast<TObjArray*>(recoParamObj)) {
1242                 // GRP has a normal TobjArray of AliDetectorRecoParam objects
1243                 // Registering them in AliRecoParam
1244                 fgRecoParam->AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
1245             }
1246             else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
1247                 // GRP has only onse set of reco parameters
1248                 // Registering it in AliRecoParam
1249                 ::Info(kEH, "Single set of GRP reconstruction parameters found");
1250                 dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
1251                 fgRecoParam->AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
1252             }
1253             else {
1254                 ::Error(kEH, "No valid GRP RecoParam object found in the OCDB");
1255                 isOK = kFALSE;
1256             }
1257             entry->SetOwner(0);
1258         }
1259     }
1260
1261     const char* fgkDetectorName[kNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE" };
1262
1263
1264     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
1265
1266         if (fgRecoParam->GetDetRecoParamArray(iDet)) {
1267             ::Info(kEH, Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
1268             continue;
1269         }
1270
1271         ::Info(kEH, Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
1272
1273         AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
1274         AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
1275         if(!entry){
1276             ::Warning(kEH, Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
1277             isOK = kFALSE;
1278         }
1279         else {
1280             TObject *recoParamObj = entry->GetObject();
1281             if (dynamic_cast<TObjArray*>(recoParamObj)) {
1282                 // The detector has a normal TobjArray of AliDetectorRecoParam objects
1283                 // Registering them in AliRecoParam
1284                 fgRecoParam->AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
1285             }
1286             else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
1287                 // The detector has only onse set of reco parameters
1288                 // Registering it in AliRecoParam
1289                 ::Info(kEH, Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
1290                 dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
1291                 fgRecoParam->AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
1292             }
1293             else {
1294                 ::Error(kEH, Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
1295                 isOK = kFALSE;
1296             }
1297             entry->SetOwner(0);
1298
1299         }
1300     }
1301
1302     if(!isOK) {
1303         delete fgRecoParam;
1304         fgRecoParam = 0;
1305     }
1306
1307     return isOK;
1308 }
1309
1310
1311 //------------------------------------------------------------------------------
1312
1313 AliEveEventManager* AliEveEventManager::AddDependentManager(const TString& name, const TString& path)
1314 {
1315     // Create and attach a dependent event-manager.
1316     // It is not added into eve list tree.
1317
1318     static const TEveException kEH("AliEveEventManager::AddDependentManager ");
1319
1320     if (fgMaster == 0)
1321         throw(kEH + "Master event-manager must be instantiated first.");
1322
1323     if (fgMaster->fSubManagers == 0)
1324     {
1325         fgMaster->fSubManagers = new TList;
1326         fgMaster->fSubManagers->SetOwner(kTRUE);
1327     }
1328
1329     AliEveEventManager* new_mgr = 0;
1330     fgCurrent = 0;
1331     try
1332     {
1333         new_mgr = new AliEveEventManager(name, path, fgMaster->fEventId);
1334         fgMaster->fSubManagers->Add(new_mgr);
1335     }
1336     catch (TEveException& exc)
1337     {
1338         ::Error(kEH, "Creation of new event-manager failed: '%s'.", exc.Data());
1339     }
1340     fgCurrent = fgMaster;
1341
1342     return new_mgr;
1343 }
1344
1345 AliEveEventManager* AliEveEventManager::GetDependentManager(const TString& name)
1346 {
1347     // Get a dependant manager by name.
1348     // This will not change the current manager, use helper class
1349     // AliEveEventManager::CurrentChanger for that.
1350
1351     static const TEveException kEH("AliEveEventManager::GetDependentManager ");
1352
1353     if (fgMaster == 0)
1354         throw(kEH + "Master event-manager must be instantiated first.");
1355
1356     if (fgMaster->fSubManagers == 0)
1357         return 0;
1358
1359     return dynamic_cast<AliEveEventManager*>(fgMaster->fSubManagers->FindObject(name));
1360 }
1361
1362 AliEveEventManager* AliEveEventManager::GetMaster()
1363 {
1364     // Get master event-manager.
1365
1366     return fgMaster;
1367 }
1368
1369 AliEveEventManager* AliEveEventManager::GetCurrent()
1370 {
1371     // Get current event-manager.
1372
1373     return fgCurrent;
1374 }
1375
1376 void AliEveEventManager::RegisterTransient(TEveElement* element)
1377 {
1378     GetCurrent()->fTransients->AddElement(element);
1379 }
1380
1381 void AliEveEventManager::RegisterTransientList(TEveElement* element)
1382 {
1383     GetCurrent()->fTransientLists->AddElement(element);
1384 }
1385
1386 //------------------------------------------------------------------------------
1387 // Autoloading of events
1388 //------------------------------------------------------------------------------
1389
1390 void AliEveEventManager::SetAutoLoadTime(Float_t time)
1391 {
1392     // Set the auto-load time in seconds
1393
1394     fAutoLoadTime = time;
1395 }
1396
1397 void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
1398 {
1399     // Set the automatic event loading mode
1400
1401     static const TEveException kEH("AliEveEventManager::SetAutoLoad ");
1402
1403     if (fAutoLoad == autoLoad)
1404     {
1405         Warning(kEH, "Setting autoload to the same value as before - %s. Ignoring.", fAutoLoad ? "true" : "false");
1406         return;
1407     }
1408
1409     fAutoLoad = autoLoad;
1410     if (fAutoLoad)
1411     {
1412         StartAutoLoadTimer();
1413     }
1414     else
1415     {
1416         StopAutoLoadTimer();
1417     }
1418 }
1419
1420 void AliEveEventManager::SetTrigSel(Int_t trig)
1421 {
1422     static const TEveException kEH("AliEveEventManager::SetTrigSel ");
1423
1424     if (!fRawReader)
1425     {
1426         Warning(kEH, "No Raw-reader exists. Ignoring the call.");
1427         return;
1428     }
1429     else
1430     {
1431         ULong64_t trigMask = 0;
1432         if (trig >= 0) trigMask = (1ull << trig);
1433         Info(kEH,"Trigger selection: 0x%llx",trigMask);
1434         fRawReader->SelectEvents(-1,trigMask,NULL);
1435     }
1436 }
1437
1438 void AliEveEventManager::StartAutoLoadTimer()
1439 {
1440     // Start the auto-load timer.
1441
1442     fAutoLoadTimer->SetTime((Long_t)(1000*fAutoLoadTime));
1443     fAutoLoadTimer->Reset();
1444     fAutoLoadTimer->TurnOn();
1445     fAutoLoadTimerRunning = kTRUE;
1446 }
1447
1448 void AliEveEventManager::StopAutoLoadTimer()
1449 {
1450     // Stop the auto-load timer.
1451
1452     fAutoLoadTimerRunning = kFALSE;
1453     fAutoLoadTimer->TurnOff();
1454 }
1455
1456 void AliEveEventManager::AutoLoadNextEvent()
1457 {
1458     // Called from auto-load timer, so it has to be public.
1459     // Do NOT call it directly.
1460
1461     static const TEveException kEH("AliEveEventManager::AutoLoadNextEvent ");
1462
1463     if ( ! fAutoLoadTimerRunning || ! fAutoLoadTimer->HasTimedOut())
1464     {
1465         Warning(kEH, "Called unexpectedly - ignoring the call. Should ONLY be called from an internal timer.");
1466         return;
1467     }
1468
1469     StopAutoLoadTimer();
1470     NextEvent();
1471     if (fAutoLoad && !fExternalCtrl)
1472         StartAutoLoadTimer();
1473 }
1474
1475 //------------------------------------------------------------------------------
1476 // Post event-loading functions
1477 //------------------------------------------------------------------------------
1478
1479 void AliEveEventManager::AfterNewEventLoaded()
1480 {
1481     // Execute registered macros and commands.
1482     // At the end emit NewEventLoaded signal.
1483     //
1484     // Virtual from TEveEventManager.
1485
1486     static const TEveException kEH("AliEveEventManager::AfterNewEventLoaded ");
1487
1488     NewEventDataLoaded();
1489
1490     if (fExecutor)
1491         fExecutor->ExecMacros();
1492
1493     TEveEventManager::AfterNewEventLoaded();
1494
1495     NewEventLoaded();
1496
1497     if (this == fgMaster && fSubManagers != 0)
1498     {
1499         TIter next(fSubManagers);
1500         while ((fgCurrent = dynamic_cast<AliEveEventManager*>(next())) != 0)
1501         {
1502             gEve->SetCurrentEvent(fgCurrent);
1503             try
1504             {
1505                 fgCurrent->GotoEvent(fEventId);
1506             }
1507             catch (TEveException& exc)
1508             {
1509                 // !!! Should somehow tag / disable / remove it?
1510                 Error(kEH, "Getting event %d for sub-event-manager '%s' failed: '%s'.",
1511                       fEventId, fgCurrent->GetName(), exc.Data());
1512             }
1513         }
1514         fgCurrent = fgMaster;
1515         gEve->SetCurrentEvent(fgMaster);
1516     }
1517 }
1518
1519 void AliEveEventManager::NewEventDataLoaded()
1520 {
1521     // Emit NewEventDataLoaded signal.
1522
1523     Emit("NewEventDataLoaded()");
1524 }
1525
1526 void AliEveEventManager::NewEventLoaded()
1527 {
1528     // Emit NewEventLoaded signal.
1529
1530     Emit("NewEventLoaded()");
1531 }
1532
1533
1534 //------------------------------------------------------------------------------
1535 // Event info dumpers
1536 //------------------------------------------------------------------------------
1537
1538 const AliEventInfo* AliEveEventManager::GetEventInfo() 
1539 {
1540     // Fill the event info object
1541
1542     AliCentralTrigger *aCTP = NULL;
1543     if (fRawReader) {
1544         fEventInfo.SetEventType(fRawReader->GetType());
1545
1546         ULong64_t mask = fRawReader->GetClassMask();
1547         fEventInfo.SetTriggerMask(mask);
1548         UInt_t clmask = fRawReader->GetDetectorPattern()[0];
1549         fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
1550
1551         aCTP = new AliCentralTrigger();
1552         TString configstr("");
1553         if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
1554             AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
1555             delete aCTP;
1556             return 0;
1557         }
1558         aCTP->SetClassMask(mask);
1559         aCTP->SetClusterMask(clmask);
1560
1561         if (fRunLoader) {
1562             AliCentralTrigger* rlCTP = fRunLoader->GetTrigger();
1563             if (rlCTP) {
1564                 rlCTP->SetClassMask(mask);
1565                 rlCTP->SetClusterMask(clmask);
1566             }
1567         }
1568     }
1569     else {
1570         fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
1571
1572         if (fRunLoader && (!fRunLoader->LoadTrigger())) {
1573             aCTP = fRunLoader->GetTrigger();
1574             fEventInfo.SetTriggerMask(aCTP->GetClassMask());
1575             // get inputs from actp - just get
1576             AliESDHeader* esdheader = fESD->GetHeader();
1577             esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
1578             esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
1579             esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
1580             fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
1581         }
1582         else {
1583             AliWarning("No trigger can be loaded! The trigger information will not be used!");
1584             return 0;
1585         }
1586     }
1587
1588     AliTriggerConfiguration *config = aCTP->GetConfiguration();
1589     if (!config) {
1590         AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
1591         if (fRawReader) delete aCTP;
1592         return 0;
1593     }
1594
1595     TString declTriggerClasses;
1596
1597     // Load trigger aliases and declare the trigger classes included in aliases
1598     AliCDBEntry * entry = AliCDBManager::Instance()->Get("GRP/CTP/Aliases");
1599     if (entry) {
1600         THashList * lst = dynamic_cast<THashList*>(entry->GetObject());
1601         if (lst) {
1602             lst->Sort(kSortDescending); // to avoid problems with substrings
1603             if (fRawReader) fRawReader->LoadTriggerAlias(lst);
1604             // Now declare all the triggers present in the aliases
1605             TIter iter(lst);
1606             TNamed *nmd = 0;
1607             while((nmd = dynamic_cast<TNamed*>(iter.Next()))){
1608                 declTriggerClasses += " ";
1609                 declTriggerClasses += nmd->GetName();
1610             }
1611         }
1612         else {
1613             AliError("Cannot cast the object with trigger aliases to THashList!");
1614         }
1615     }
1616     else {
1617         AliError("No OCDB entry for the trigger aliases!");
1618     }
1619
1620     // Load trigger classes for this run
1621     UChar_t clustmask = 0;
1622     TString trclasses;
1623     ULong64_t trmask = fEventInfo.GetTriggerMask();
1624     const TObjArray& classesArray = config->GetClasses();
1625     Int_t nclasses = classesArray.GetEntriesFast();
1626     for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
1627         AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
1628         if (trclass && trclass->GetMask()>0) {
1629             Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
1630             if (fESD) fESD->SetTriggerClass(trclass->GetName(),trindex);
1631             if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
1632             if (trmask & (1ull << trindex)) {
1633                 trclasses += " ";
1634                 trclasses += trclass->GetName();
1635                 trclasses += " ";
1636                 clustmask |= trclass->GetCluster()->GetClusterMask();
1637             }
1638         }
1639     }
1640     fEventInfo.SetTriggerClasses(trclasses);
1641
1642     if (!aCTP->CheckTriggeredDetectors()) {
1643         if (fRawReader) delete aCTP;
1644         return 0;
1645     }
1646
1647     if (fRawReader) delete aCTP;
1648
1649     // everything went ok, return pointer
1650     return (&fEventInfo);
1651 }
1652
1653
1654 TString AliEveEventManager::GetEventInfoHorizontal() const
1655 {
1656     // Dumps the event-header contents in vertical formatting.
1657
1658     TString rawInfo, esdInfo;
1659
1660     if (!fRawReader)
1661     {
1662         rawInfo = "No raw-data event info is available!\n";
1663     }
1664     else
1665     {
1666         const UInt_t* attr = fRawReader->GetAttributes();
1667         TTimeStamp ts(fRawReader->GetTimestamp());
1668         rawInfo.Form("RAW event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1669                      "Trigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x  Timestamp: %s\n",
1670                      fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1671                      fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1672                      fRawReader->GetClassMask(),
1673                      *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1674                      attr[0],attr[1],attr[2], ts.AsString("s"));
1675     }
1676
1677     if (!fESD)
1678     {
1679         esdInfo = "No ESD event info is available!";
1680     }
1681     else
1682     {
1683         TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1684         TString firedtrclasses = fESD->GetFiredTriggerClasses();
1685         TTimeStamp ts(fESD->GetTimeStamp());
1686         esdInfo.Form("ESD event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1687                      "Active trigger classes: %s\nTrigger: %llx (%s)\nEvent# in file: %d  Timestamp: %s, MagField: %.2e",
1688                      fESD->GetRunNumber(),
1689                      fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1690                      fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1691                      acttrclasses.Data(),
1692                      fESD->GetTriggerMask(),firedtrclasses.Data(),
1693                      fESD->GetEventNumberInFile(), ts.AsString("s"), fESD->GetMagneticField());
1694     }
1695
1696     return rawInfo + esdInfo;
1697 }
1698
1699 TString AliEveEventManager::GetEventInfoVertical() const
1700 {
1701     // Dumps the event-header contents in vertical formatting.
1702
1703     TString rawInfo, esdInfo;
1704
1705     if (!fRawReader)
1706     {
1707         rawInfo = "No raw-data event info is available!\n";
1708     }
1709     else
1710     {
1711         const UInt_t* attr = fRawReader->GetAttributes();
1712         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",
1713                      fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1714                      fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1715                      fRawReader->GetClassMask(),
1716                      *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1717                      attr[0],attr[1],attr[2],
1718                      fRawReader->GetTimestamp());
1719     }
1720
1721     if (!fESD)
1722     {
1723         esdInfo = "No ESD event info is available!\n";
1724     }
1725     else
1726     {
1727         TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1728         TString firedtrclasses = fESD->GetFiredTriggerClasses();
1729         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",
1730                      fESD->GetRunNumber(),
1731                      acttrclasses.Data(),
1732                      fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1733                      fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1734                      fESD->GetTriggerMask(),firedtrclasses.Data(),
1735                      fESD->GetEventNumberInFile(),
1736                      fESD->GetTimeStamp());
1737     }
1738
1739     return rawInfo + "\n" + esdInfo;
1740 }
1741
1742
1743 //==============================================================================
1744 // Reading of GRP and MagneticField.
1745 // This is a reap-off from reconstruction ... should really be a common
1746 // code to do this somewhere in STEER.
1747 //==============================================================================
1748
1749 Bool_t AliEveEventManager::InitGRP()
1750 {
1751     //------------------------------------
1752     // Initialization of the GRP entry
1753     //------------------------------------
1754
1755     static const TEveException kEH("AliEveEventManager::InitGRP ");
1756
1757     AliGRPManager grpMgr;
1758     if (!grpMgr.ReadGRPEntry()) {
1759         return kFALSE;
1760     }
1761     fgGRPLoaded = kTRUE;
1762     if (!grpMgr.SetMagField()) {
1763         throw kEH + "Setting of field failed!";
1764     }
1765
1766     //*** Get the diamond profiles from OCDB
1767     // Eventually useful.
1768
1769     /*
1770     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1771     if (entry) {
1772     fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());
1773     } else {
1774     ::Error(kEH, "No SPD diamond profile found in OCDB!");
1775     }
1776
1777     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1778     if (entry) {
1779     fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());
1780     } else {
1781     ::Error(kEH, "No diamond profile found in OCDB!");
1782     }
1783
1784     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1785     if (entry) {
1786     fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());
1787     } else {
1788     ::Error(kEH, "No TPC diamond profile found in OCDB!");
1789     }
1790   */
1791
1792     return kTRUE;
1793
1794
1795 //------------------------------------
1796 // Global variables management
1797 //------------------------------------
1798
1799 Bool_t AliEveEventManager::InsertGlobal(const TString& tag, TEveElement* model)
1800 {
1801     // Insert a new visualization-parameter database entry with the default
1802     return InsertGlobal(tag, model, fGlobalReplace, fGlobalUpdate);
1803 }
1804
1805 Bool_t AliEveEventManager::InsertGlobal(const TString& tag, TEveElement* model,
1806                                         Bool_t replace, Bool_t update)
1807 {
1808     TPair* pair = (TPair*) fGlobal->FindObject(tag);
1809     if (pair)
1810     {
1811         if (replace)
1812         {
1813             model->IncDenyDestroy();
1814             model->SetRnrChildren(kFALSE);
1815
1816             TEveElement* old_model = dynamic_cast<TEveElement*>(pair->Value());
1817             if(!old_model) AliFatal("old_model == 0, dynamic cast failed\n");
1818             while (old_model->HasChildren())
1819             {
1820                 TEveElement *el = old_model->FirstChild();
1821                 el->SetVizModel(model);
1822                 if (update)
1823                 {
1824                     el->CopyVizParams(model);
1825                     el->PropagateVizParamsToProjecteds();
1826                 }
1827             }
1828             old_model->DecDenyDestroy();
1829
1830             pair->SetValue(dynamic_cast<TObject*>(model));
1831             return kTRUE;
1832         }
1833         else
1834         {
1835             return kFALSE;
1836         }
1837     }
1838     else
1839     {
1840         model->IncDenyDestroy();
1841         model->SetRnrChildren(kFALSE);
1842         fGlobal->Add(new TObjString(tag), dynamic_cast<TObject*>(model));
1843         return kTRUE;
1844     }
1845 }
1846
1847 TEveElement* AliEveEventManager::FindGlobal(const TString& tag)
1848 {
1849     return dynamic_cast<TEveElement*>(fGlobal->GetValue(tag));
1850 }