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