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