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