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