AliEveMacro
[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 "AliEveMacroExecutor.h"
12 #include <TEveManager.h>
13
14 #include <AliRunLoader.h>
15 #include <AliRun.h>
16 #include <AliESDRun.h>
17 #include <AliESDEvent.h>
18 #include <AliESDfriend.h>
19 #include <AliAODEvent.h>
20
21 #include <AliDAQ.h>
22 #include <AliRawEventHeaderBase.h>
23 #include <AliRawReaderRoot.h>
24 #include <AliRawReaderFile.h>
25 #include <AliRawReaderDate.h>
26 #include <AliMagF.h>
27 #include <AliCDBManager.h>
28 #include <AliCDBStorage.h>
29 #include <AliHeader.h>
30 #include <AliGeomManager.h>
31
32 #include <TFile.h>
33 #include <TTree.h>
34 #include <TGeoManager.h>
35 #include <TSystem.h>
36 #include <TTimeStamp.h>
37
38 //==============================================================================
39 //==============================================================================
40 // AliEveEventManager
41 //==============================================================================
42
43 //______________________________________________________________________________
44 //
45 // Provides interface for loading and navigating standard AliRoot data
46 // (AliRunLoader), ESD, AOD and RAW.
47 //
48 // ESDfriend is attached automatically, if the file is found.
49 //
50 // AODfriends are not attached automatically as there are several
51 // possible files involved. To have a specific AODfriend attached, call
52 // static method
53 //   AliEveEventManager::AddAODfriend("AliAOD.VertexingHF.root");
54 // before initializing the event-manager.
55 //
56 // Also provides interface to magnetic-field and geometry. Mostly
57 // intended as wrappers over standard AliRoot functionality for
58 // convenient use from visualizateion macros.
59 //
60 // There can be a single main event-manger, it is stored in private
61 // data member fgMaster and can be accessed via static member function
62 // GetMaster().
63 //
64 // For event overlaying and embedding one can instantiate additional
65 // event-managers via static method AddDependentManager(const TString& path).
66 // This interface is under development.
67
68 ClassImp(AliEveEventManager)
69
70 Bool_t AliEveEventManager::fgAssertRunLoader = kFALSE;
71 Bool_t AliEveEventManager::fgAssertESD       = kFALSE;
72 Bool_t AliEveEventManager::fgAssertAOD       = kFALSE;
73 Bool_t AliEveEventManager::fgAssertRaw       = kFALSE;
74
75 TString  AliEveEventManager::fgESDFileName("AliESDs.root");
76 TString  AliEveEventManager::fgAODFileName("AliAOD.root");
77 TString  AliEveEventManager::fgRawFileName("raw.root");
78 TString  AliEveEventManager::fgCdbUri("local://$ALICE_ROOT/OCDB");
79
80 TList*   AliEveEventManager::fgAODfriends = 0;
81
82 AliEveEventManager* AliEveEventManager::fgMaster  = 0;
83 AliEveEventManager* AliEveEventManager::fgCurrent = 0;
84
85 void AliEveEventManager::InitInternals()
86 {
87   // Initialize internal members.
88
89   static const TEveException kEH("AliEveEventManager::InitInternals ");
90
91   if (fgCurrent != 0)
92   {
93     throw(kEH + "Dependent event-managers should be created via static method AddDependentManager().");
94   }
95
96   if (fgMaster == 0)
97   {
98     fgMaster = this;
99   }
100
101   fgCurrent = this;
102
103   fAutoLoadTimer = new TTimer;
104   fAutoLoadTimer->Connect("Timeout()", "AliEveEventManager", this, "AutoLoadNextEvent()");
105
106   fExecutor = new AliEveMacroExecutor;
107
108   fTransients = new TEveElementList("Transients", "Transient per-event elements.");
109   fTransients->IncDenyDestroy();
110   gEve->AddToListTree(fTransients, kTRUE);
111 }
112
113 AliEveEventManager::AliEveEventManager(const TString& name) :
114   TEveEventManager(name),
115
116   fPath      ( ), fEventId (-1),
117   fRunLoader (0),
118   fESDFile   (0), fESDTree (0), fESD (0),
119   fESDfriend (0), fESDfriendExists(kFALSE),
120   fAODFile   (0), fAODTree (0), fAOD (0),
121   fRawReader (0),
122   fAutoLoad  (kFALSE), fAutoLoadTime (5.),     fAutoLoadTimer(0),
123   fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
124   fSelectOnTriggerType(kFALSE), fTriggerType(""),
125   fExecutor    (0), fTransients(0),
126   fSubManagers (0),
127   fAutoLoadTimerRunning(kFALSE)
128 {
129   // Default constructor.
130
131   InitInternals();
132 }
133
134 AliEveEventManager::AliEveEventManager(const TString& name, const TString& path, Int_t ev) :
135   TEveEventManager(name, path),
136
137   fPath   (path), fEventId(-1),
138   fRunLoader (0),
139   fESDFile   (0), fESDTree (0), fESD (0),
140   fESDfriend (0), fESDfriendExists(kFALSE),
141   fAODFile   (0), fAODTree (0), fAOD (0),
142   fRawReader (0),
143   fAutoLoad  (kFALSE), fAutoLoadTime (5),      fAutoLoadTimer(0),
144   fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
145   fSelectOnTriggerType(kFALSE), fTriggerType(""),
146   fExecutor    (0), fTransients(0),
147   fSubManagers (0),
148   fAutoLoadTimerRunning(kFALSE)
149 {
150   // Constructor with event-directory URL and event-id.
151
152   InitInternals();
153
154   Open();
155   if (ev >= 0)
156   {
157     GotoEvent(ev);
158   }
159 }
160
161 AliEveEventManager::~AliEveEventManager()
162 {
163   // Destructor.
164
165   delete fSubManagers;
166
167   if (fIsOpen)
168   {
169     Close();
170   }
171
172   fTransients->DecDenyDestroy();
173   fTransients->Destroy();
174 }
175
176 /******************************************************************************/
177
178 void AliEveEventManager::SetESDFileName(const TString& esd)
179 {
180   // Set file-name for opening ESD, default "AliESDs.root".
181
182   if ( ! esd.IsNull()) fgESDFileName = esd;
183 }
184
185 void AliEveEventManager::SetAODFileName(const TString& aod)
186 {
187   // Set file-name for opening AOD, default "AliAOD.root".
188
189   if ( ! aod.IsNull()) fgAODFileName = aod;
190 }
191
192 void AliEveEventManager::AddAODfriend(const TString& friendFileName)
193 {
194   // Add new AOD friend file-name to be attached when opening AOD.
195   // This should include '.root', as in 'AliAOD.VertexingHF.root'.
196
197   if (fgAODfriends == 0)
198   {
199     fgAODfriends = new TList;
200     fgAODfriends->SetOwner(kTRUE);
201   }
202   fgAODfriends->Add(new TObjString(friendFileName));
203 }
204
205 void AliEveEventManager::SetRawFileName(const TString& raw)
206 {
207   // Set file-name for opening of raw-data, default "raw.root"
208   if ( ! raw.IsNull()) fgRawFileName = raw;
209 }
210
211 void AliEveEventManager::SetCdbUri(const TString& cdb)
212 {
213   // Set path to CDB, default "local://$ALICE_ROOT/OCDB".
214
215   if ( ! cdb.IsNull()) fgCdbUri = cdb;
216 }
217
218 void AliEveEventManager::SetAssertElements(Bool_t assertRunloader, Bool_t assertEsd,
219                                            Bool_t assertAod, Bool_t assertRaw)
220 {
221   // Set global flags that detrmine which parts of the event-data must
222   // be present when the event is opened.
223
224   fgAssertRunLoader = assertRunloader;
225   fgAssertESD = assertEsd;
226   fgAssertAOD = assertAod;
227   fgAssertRaw = assertRaw;
228 }
229
230 /******************************************************************************/
231
232 void AliEveEventManager::Open()
233 {
234   // Open event-data from URL specified in fPath.
235   // Attempts to create AliRunLoader() and to open ESD with ESDfriends.
236   // Warning is reported if run-loader or ESD is not found.
237   // Global data-members fgAssertRunLoader and fgAssertESD can be set
238   // to throw exceptions instead.
239
240   static const TEveException kEH("AliEveEventManager::Open ");
241
242   if (fExternalCtrl)
243   {
244     throw (kEH + "Event-loop is under external control.");
245   }
246   if (fIsOpen)
247   {
248     throw (kEH + "Event-files already opened.");
249   }
250
251   gSystem->ExpandPathName(fPath);
252   // The following magick is required for ESDfriends to be loaded properly
253   // from non-current directory.
254   if (fPath.IsNull() || fPath == ".")
255   {
256     fPath = gSystem->WorkingDirectory();
257   }
258   else if ( ! fPath.BeginsWith("file:/"))
259   {
260     TUrl    url(fPath, kTRUE);
261     TString protocol(url.GetProtocol());
262     if (protocol == "file" && fPath[0] != '/')
263       fPath = Form("%s/%s", gSystem->WorkingDirectory(), fPath.Data());
264   }
265
266   Int_t runNo = -1;
267
268   // Open ESD and ESDfriends
269
270   TString esdPath(Form("%s/%s", fPath.Data(), fgESDFileName.Data()));
271   if ((fESDFile = TFile::Open(esdPath)))
272   {
273     fESD = new AliESDEvent();
274     fESDTree = (TTree*) fESDFile->Get("esdTree");
275     if (fESDTree != 0)
276     {
277       // Check if ESDfriends exists and attach the branch.
278       // We use TFile::Open() instead of gSystem->AccessPathName
279       // as it seems to work better when attachine alieve to a
280       // running reconstruction process with auto-save on.
281       // There was also a problem with TTree::Refresh() - it didn't
282       // save the friend branch on a separate file, fixed in 5.22.2 -
283       // so we might want to try the old way again soon.
284       TString p(Form("%s/AliESDfriends.root", fPath.Data()));
285       TFile *esdFriendFile = TFile::Open(p);
286       if (esdFriendFile)
287       {
288         if (!esdFriendFile->IsZombie())
289         {
290           esdFriendFile->Close();
291           fESDfriendExists = kTRUE;
292           fESDTree->SetBranchStatus ("ESDfriend*", 1);
293         }
294         delete esdFriendFile;
295       }
296
297       fESD->ReadFromTree(fESDTree);
298       if (fESDfriendExists)
299       {
300         fESDfriend = (AliESDfriend*) fESD->FindListObject("AliESDfriend");
301         Info(kEH, "found and attached ESD friend.");
302       }
303       else
304       {
305         Warning(kEH, "ESDfriend not found.");
306       }
307
308       if (fESDTree->GetEntry(0) <= 0)
309       {
310         delete fESDFile; fESDFile = 0;
311         delete fESD; fESD = 0;
312         Warning(kEH, "failed getting the first entry from esdTree.");
313       }
314       else
315       {
316         if (runNo < 0)
317           runNo = fESD->GetESDRun()->GetRunNumber();
318       }
319     }
320     else // esdtree == 0
321     {
322       delete fESDFile; fESDFile = 0;
323       delete fESD; fESD = 0;
324       Warning(kEH, "failed getting the esdTree.");
325     }
326   }
327   else // esd not readable
328   {
329     Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
330   }
331   if (fESDTree == 0)
332   {
333     if (fgAssertESD)
334     {
335       throw (kEH + "ESD not initialized. Its precence was requested.");
336     } else {
337       Warning(kEH, "ESD not initialized.");
338     }
339   }
340
341   // Open AOD and registered friends
342
343   TString aodPath(Form("%s/%s", fPath.Data(), fgAODFileName.Data()));
344   if ((fAODFile = TFile::Open(aodPath)))
345   {
346     fAOD = new AliAODEvent();
347     fAODTree = (TTree*) fAODFile->Get("aodTree");
348     if (fAODTree != 0)
349     {
350       // Check if AODfriends exist and attach them.
351       TIter       friends(fgAODfriends);
352       TObjString *name;
353       while ((name = (TObjString*) friends()) != 0)
354       {
355         TString p(Form("%s/%s", fPath.Data(), name->GetName()));
356         if (gSystem->AccessPathName(p, kReadPermission) == kFALSE)
357         {
358           fAODTree->AddFriend("aodTree", name->GetName());
359         }
360       }
361
362       fAOD->ReadFromTree(fAODTree);
363
364       if (fAODTree->GetEntry(0) <= 0)
365       {
366         delete fAODFile; fAODFile = 0;
367         delete fAOD;     fAOD     = 0;
368         Warning(kEH, "failed getting the first entry from addTree.");
369       }
370       else
371       {
372         if (runNo < 0)
373           runNo = fAOD->GetRunNumber();
374       }
375     }
376     else // aodtree == 0
377     {
378       delete fAODFile; fAODFile = 0;
379       delete fAOD;     fAOD     = 0;
380       Warning(kEH, "failed getting the aodTree.");
381     }
382   }
383   else // aod not readable
384   {
385     Warning(kEH, "can not read AOD file '%s'.", aodPath.Data());
386   }
387   if (fAODTree == 0)
388   {
389     if (fgAssertAOD)
390     {
391       throw (kEH + "AOD not initialized. Its precence was requested.");
392     } else {
393       Warning(kEH, "AOD not initialized.");
394     }
395   }
396
397   // Open RunLoader from galice.root
398
399   TString gaPath(Form("%s/galice.root", fPath.Data()));
400   // If i use open directly, we get fatal.
401   // Is AccessPathName check ok for xrootd / alien? Yes, not for http.
402   if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
403   {
404     fRunLoader = AliRunLoader::Open(gaPath, GetName());
405     if (fRunLoader)
406     {
407       TString alicePath = fPath + "/";
408       fRunLoader->SetDirName(alicePath);
409
410       if (fRunLoader->LoadgAlice() != 0)
411         Warning(kEH, "failed loading gAlice via run-loader.");
412
413       if (fRunLoader->LoadHeader() == 0)
414       {
415         if (runNo < 0)
416           runNo = fRunLoader->GetHeader()->GetRun();
417       }
418       else
419       {
420         Warning(kEH, "failed loading run-loader's header.");
421         delete fRunLoader;
422         fRunLoader = 0;
423       }
424     }
425     else // run-loader open failed
426     {
427       Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
428     }
429   }
430   else // galice not readable
431   {
432     Warning(kEH, "can not read '%s'.", gaPath.Data());
433   }
434   if (fRunLoader == 0)
435   {
436     if (fgAssertRunLoader)
437       throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
438     else
439       Warning(kEH, "Bootstraping of run-loader failed.");
440   }
441
442   // Open raw-data file
443
444   TString rawPath(Form("%s/%s", fPath.Data(), fgRawFileName.Data()));
445   // If i use open directly, raw-reader reports an error but i have
446   // no way to detect it.
447   // Is this (AccessPathName check) ok for xrootd / alien? Yes, not for http.
448   AliLog::EType_t oldLogLevel = (AliLog::EType_t) AliLog::GetGlobalLogLevel();
449   if (fgAssertRaw == kFALSE)
450   {
451     AliLog::SetGlobalLogLevel(AliLog::kFatal);
452   }
453   if (gSystem->AccessPathName(rawPath, kReadPermission) == kFALSE)
454   {
455     fRawReader = AliRawReader::Create(rawPath);
456   }
457   else
458   {
459     fRawReader = AliRawReader::Create(fgRawFileName);
460   }
461   if (fgAssertRaw == kFALSE)
462   {
463     AliLog::SetGlobalLogLevel(oldLogLevel);
464   }
465
466   if (fRawReader == 0)
467   {
468     if (fgAssertRaw)
469     {
470       throw (kEH + "raw-data not initialized. Its precence was requested.");
471     } else {
472       Warning(kEH, "raw-data not initialized.");
473     }
474   }
475
476   if (runNo < 0)
477   {
478     if (fRawReader)
479     {
480       fRawReader->NextEvent();
481       runNo = fRawReader->GetRunNumber();
482       Info(kEH, "Determining run-no from raw ... run=%d.", runNo);
483       fRawReader->RewindEvents();
484     } else {
485       throw (kEH + "unknown run number.");
486     }
487   }
488
489   // Initialize OCDB ... only in master event-manager
490
491   if (this == fgMaster)
492   {
493     AliCDBManager* cdb = AliCDBManager::Instance();
494     if (cdb->IsDefaultStorageSet() == kTRUE)
495     {
496       Warning(kEH, "CDB already set - using the old storage:\n  '%s'",
497               cdb->GetDefaultStorage()->GetURI().Data());
498     }
499     else
500     {
501       cdb->SetDefaultStorage(fgCdbUri);
502       if (cdb->IsDefaultStorageSet() == kFALSE)
503         throw (kEH + "CDB initialization failed.");
504     }
505     cdb->SetRun(runNo);
506   }
507
508   fIsOpen = kTRUE;
509 }
510
511 void AliEveEventManager::SetEvent(AliRunLoader *runLoader, AliRawReader *rawReader, AliESDEvent *esd, AliESDfriend *esdf)
512 {
513   // Set an event from an external source.
514   // The method is used in the online visualisation.
515   // AOD is not supported.
516
517   static const TEveException kEH("AliEveEventManager::SetEvent ");
518
519   if (fIsOpen)
520   {
521     Warning(kEH, "Event-files were open. Closing and switching to external control.");
522     Close();
523   }
524
525   fRunLoader = runLoader;
526   fRawReader = rawReader;
527   fESD       = esd;
528   fESDfriend = esdf;
529   fAOD       = 0;
530
531   fEventId++;
532   fHasEvent     = kTRUE;
533   fExternalCtrl = kTRUE;
534
535   SetTitle("Online event in memory");
536   SetName ("Online Event");
537   ElementChanged();
538
539   AfterNewEventLoaded();
540
541   if (fAutoLoad) StartAutoLoadTimer();
542 }
543
544 Int_t AliEveEventManager::GetMaxEventId(Bool_t /*refreshESD*/) const
545 {
546   // Returns maximum available event id.
547   // If under external control or event is not opened -1 is returned.
548   // If raw-data is the only data-source this can not be known
549   // and 10,000,000 is returned.
550   // If neither data-source is initialised an exception is thrown.
551   // If refresh_esd is true and ESD is the primary event-data source
552   // its header is re-read from disk.
553
554   static const TEveException kEH("AliEveEventManager::GetMaxEventId ");
555
556   if (fExternalCtrl || fIsOpen == kFALSE)
557   {
558     return -1;
559   }
560
561   if (fESDTree)
562   {
563     // Refresh crashes with root-5.21.1-alice.
564     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
565     // when we move to a newer root.
566     // if (refreshESD)
567     //   fESDTree->Refresh();
568     return fESDTree->GetEntries() - 1;
569   }
570   else if (fAODTree)
571   {
572     return fAODTree->GetEntries() - 1;
573   }
574   else if (fRunLoader)
575   {
576     return fRunLoader->GetNumberOfEvents() - 1;
577   }
578   else if (fRawReader)
579   {
580     Int_t n = fRawReader->GetNumberOfEvents() - 1;
581     return n > -1 ? n : 10000000;
582   }
583   else
584   {
585     throw (kEH + "neither ESD, AOD, RunLoader nor Raw loaded.");
586   }
587 }
588
589 void AliEveEventManager::GotoEvent(Int_t event)
590 {
591   // Load data for specified event.
592   // If event is out of range an exception is thrown and old state
593   // is preserved.
594   // After successful loading of event, the virtual function
595   // AfterNewEventLoaded() is called. This executes commands that
596   // were registered via TEveEventManager::AddNewEventCommand().
597   //
598   // If event is negative, it is subtracted from the number of
599   // available events, thus passing -1 will load the last event.
600   // This is not supported when raw-data is the only data-source
601   // as the number of events is not known.
602
603   static const TEveException kEH("AliEveEventManager::GotoEvent ");
604
605   if (fAutoLoadTimerRunning)
606   {
607     throw (kEH + "Event auto-load timer is running.");
608   }
609   if (fExternalCtrl)
610   {
611     throw (kEH + "Event-loop is under external control.");
612   }
613   else if (!fIsOpen)
614   {
615     throw (kEH + "Event-files not opened.");
616   }
617
618   fHasEvent = kFALSE;
619
620   Int_t maxEvent = 0;
621   if (fESDTree)
622   {
623     // Refresh crashes with root-5.21.1-alice.
624     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
625     // when we move to a newer root.
626     // fESDTree->Refresh();
627     maxEvent = fESDTree->GetEntries() - 1;
628     if (event < 0)
629       event = fESDTree->GetEntries() + event;
630   }
631   else if (fAODTree)
632   {
633     maxEvent = fAODTree->GetEntries() - 1;
634     if (event < 0)
635       event = fAODTree->GetEntries() + event;
636   }
637   else if (fRunLoader)
638   {
639     maxEvent = fRunLoader->GetNumberOfEvents() - 1;
640     if (event < 0)
641       event = fRunLoader->GetNumberOfEvents() + event;
642   }
643   else if (fRawReader)
644   {
645     maxEvent = fRawReader->GetNumberOfEvents() - 1;
646     if (maxEvent < 0)
647     {
648       maxEvent = 10000000;
649       if (event < 0) {
650         Error(kEH, "current raw-data source does not support direct event access.");
651         return;
652       }
653       Info(kEH, "number of events unknown for current raw-data source, setting max-event id to 10M.");
654     }
655     else
656     {
657       if (event < 0)
658         event = fRawReader->GetNumberOfEvents() + event;
659     }
660   }
661   else
662   {
663     throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
664   }
665   if (event < 0 || event > maxEvent)
666   {
667     throw (kEH + Form("event %d not present, available range [%d, %d].",
668                       event, 0, maxEvent));
669   }
670
671   TEveManager::TRedrawDisabler rd(gEve);
672   gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
673
674   // !!! MT this is somewhat brutal; at least optionally, one could be
675   // a bit gentler, checking for objs owning their external refs and having
676   // additinal parents.
677   fTransients->DestroyElements();
678   DestroyElements();
679
680   if (fESDTree) {
681     if (fESDTree->GetEntry(event) <= 0)
682       throw (kEH + "failed getting required event from ESD.");
683
684     if (fESDfriendExists)
685       fESD->SetESDfriend(fESDfriend);
686   }
687
688   if (fAODTree) {
689     if (fAODTree->GetEntry(event) <= 0)
690       throw (kEH + "failed getting required event from AOD.");
691   }
692
693   if (fRunLoader) {
694     if (fRunLoader->GetEvent(event) != 0)
695       throw (kEH + "failed getting required event.");
696   }
697
698   if (fRawReader)
699   {
700     // AliRawReader::GotoEvent(Int_t) works for AliRawReaderRoot/Chain.
701     if (fRawReader->GotoEvent(event) == kFALSE)
702     {
703       // Use fallback method - iteration with NextEvent().
704       Int_t rawEv = fEventId;
705       if (event < rawEv)
706       {
707         fRawReader->RewindEvents();
708         rawEv = -1;
709       }
710
711       while (rawEv < event)
712       {
713         if ( ! fRawReader->NextEvent())
714         {
715           fRawReader->RewindEvents();
716           fEventId = -1;
717           throw (kEH + Form("Error going to next raw-event from event %d.", rawEv));
718         }
719         ++rawEv;
720       }
721       Warning(kEH, "Loaded raw-event %d with fallback method.\n", rawEv);
722     }
723   }
724
725   fHasEvent = kTRUE;
726   fEventId  = event;
727   if (this == fgMaster)
728   {
729     SetName(Form("Event %d", fEventId));
730     ElementChanged();
731   }
732
733   AfterNewEventLoaded();
734 }
735
736 void AliEveEventManager::NextEvent()
737 {
738   // Loads next event.
739   // Does magick needed for online display when under external event control.
740
741   static const TEveException kEH("AliEveEventManager::NextEvent ");
742
743   if (fAutoLoadTimerRunning)
744   {
745     throw (kEH + "Event auto-load timer is running.");
746   }
747
748   if (fExternalCtrl)
749   {
750     // !!! This should really go somewhere else. It is done in GotoEvent(),
751     // so here we should do it in SetEvent().
752     DestroyElements();
753
754     gSystem->ExitLoop();
755   }
756   else
757   {
758     Int_t nexteventbytrigger=0;
759     if (fSelectOnTriggerType)
760     {
761       if (FindNextByTrigger(nexteventbytrigger)) //if not found do nothing
762         GotoEvent(nexteventbytrigger);
763     }
764     else if (fEventId < GetMaxEventId(kTRUE))
765       GotoEvent(fEventId + 1);
766     else
767       GotoEvent(0);
768   }
769 }
770
771 void AliEveEventManager::PrevEvent()
772 {
773   // Loads previous event.
774
775   static const TEveException kEH("AliEveEventManager::PrevEvent ");
776
777   if (fAutoLoadTimerRunning)
778   {
779     throw (kEH + "Event auto-load timer is running.");
780   }
781   if (fExternalCtrl)
782   {
783     throw (kEH + "Event-loop is under external control.");
784   }
785   Int_t nexteventbytrigger=0;
786   if (fSelectOnTriggerType)
787   {
788     if (FindPrevByTrigger(nexteventbytrigger))
789       GotoEvent(nexteventbytrigger);
790   }
791   else
792     GotoEvent(fEventId - 1);
793 }
794
795 void AliEveEventManager::Close()
796 {
797   // Close the event data-files and delete ESD, ESDfriend, run-loader
798   // and raw-reader.
799
800   static const TEveException kEH("AliEveEventManager::Close ");
801
802   if (!fIsOpen)
803   {
804     throw (kEH + "Event-files not opened.");
805   }
806
807   if (fAutoLoadTimerRunning)
808     StopAutoLoadTimer();
809
810   if (fESDTree) {
811     delete fESD;       fESD       = 0;
812     delete fESDfriend; fESDfriend = 0;
813     fESDfriendExists = kFALSE;
814
815     delete fESDTree;   fESDTree = 0;
816     delete fESDFile;   fESDFile = 0;
817   }
818
819   if (fAODTree) {
820     delete fAOD;       fAOD       = 0;
821
822     delete fAODTree;   fAODTree = 0;
823     delete fAODFile;   fAODFile = 0;
824   }
825
826   if (fRunLoader) {
827     delete fRunLoader; fRunLoader = 0;
828   }
829
830   if (fRawReader) {
831     delete fRawReader; fRawReader = 0;
832   }
833
834   fEventId  = -1;
835   fIsOpen   = kFALSE;
836   fHasEvent = kFALSE;
837 }
838
839
840 //------------------------------------------------------------------------------
841 // Static convenience functions, mainly used from macros.
842 //------------------------------------------------------------------------------
843
844 Bool_t AliEveEventManager::HasRunLoader()
845 {
846   // Check if AliRunLoader is initialized.
847
848   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRunLoader;
849 }
850
851 Bool_t AliEveEventManager::HasESD()
852 {
853   // Check if AliESDEvent is initialized.
854
855   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESD;
856 }
857
858 Bool_t AliEveEventManager::HasESDfriend()
859 {
860   // Check if AliESDfriend is initialized.
861
862   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESDfriend;
863 }
864
865 Bool_t AliEveEventManager::HasAOD()
866 {
867   // Check if AliESDEvent is initialized.
868
869   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fAOD;
870 }
871
872 Bool_t AliEveEventManager::HasRawReader()
873 {
874   // Check if raw-reader is initialized.
875
876   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRawReader;
877 }
878
879 AliRunLoader* AliEveEventManager::AssertRunLoader()
880 {
881   // Make sure AliRunLoader is initialized and return it.
882   // Throws exception in case run-loader is not available.
883   // Static utility for macros.
884
885   static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
886
887   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
888     throw (kEH + "ALICE event not ready.");
889   if (fgCurrent->fRunLoader == 0)
890     throw (kEH + "AliRunLoader not initialised.");
891   return fgCurrent->fRunLoader;
892 }
893
894 AliESDEvent* AliEveEventManager::AssertESD()
895 {
896   // Make sure AliESDEvent is initialized and return it.
897   // Throws exception in case ESD is not available.
898   // Static utility for macros.
899
900   static const TEveException kEH("AliEveEventManager::AssertESD ");
901
902   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
903     throw (kEH + "ALICE event not ready.");
904   if (fgCurrent->fESD == 0)
905     throw (kEH + "AliESD not initialised.");
906   return fgCurrent->fESD;
907 }
908
909 AliESDfriend* AliEveEventManager::AssertESDfriend()
910 {
911   // Make sure AliESDfriend is initialized and return it.
912   // Throws exception in case ESDfriend-loader is not available.
913   // Static utility for macros.
914
915   static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
916
917   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
918     throw (kEH + "ALICE event not ready.");
919   if (fgCurrent->fESDfriend == 0)
920     throw (kEH + "AliESDfriend not initialised.");
921   return fgCurrent->fESDfriend;
922 }
923
924 AliAODEvent* AliEveEventManager::AssertAOD()
925 {
926   // Make sure AliAODEvent is initialized and return it.
927   // Throws exception in case AOD is not available.
928   // Static utility for macros.
929
930   static const TEveException kEH("AliEveEventManager::AssertAOD ");
931
932   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
933     throw (kEH + "ALICE event not ready.");
934   if (fgCurrent->fAOD == 0)
935     throw (kEH + "AliAOD not initialised.");
936   return fgCurrent->fAOD;
937 }
938
939 AliRawReader* AliEveEventManager::AssertRawReader()
940 {
941   // Make sure raw-reader is initialized and return it.
942
943   static const TEveException kEH("AliEveEventManager::AssertRawReader ");
944
945   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
946     throw (kEH + "ALICE event not ready.");
947   if (fgCurrent->fRawReader == 0)
948     throw (kEH + "RawReader not ready.");
949
950   return fgCurrent->fRawReader;
951 }
952
953
954 TGeoManager* AliEveEventManager::AssertGeometry()
955 {
956   // Make sure AliGeomManager is initialized and returns the
957   // corresponding TGeoManger.
958   // gGeoManager is set to the return value.
959   // Throws exception if geometry can not be loaded or if it is not
960   // available and the TGeoManager is locked.
961   // Static utility for macros.
962
963   static const TEveException kEH("AliEveEventManager::AssertGeometry ");
964
965   if (AliGeomManager::GetGeometry() == 0)
966   {
967     if (TGeoManager::IsLocked())
968       throw (kEH + "geometry is not loaded but TGeoManager is locked.");
969
970     gGeoManager = 0;
971     AliGeomManager::LoadGeometry();
972     if ( ! AliGeomManager::GetGeometry())
973     {
974       throw (kEH + "can not load geometry.");
975     }
976     if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
977     {
978       ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
979       // throw (kEH + "could not apply align objs.");
980     }
981     AliGeomManager::GetGeometry()->DefaultColors();
982   }
983
984   gGeoManager = AliGeomManager::GetGeometry();
985   return gGeoManager;
986 }
987
988 //------------------------------------------------------------------------------
989
990 AliEveEventManager* AliEveEventManager::AddDependentManager(const TString& name, const TString& path)
991 {
992   // Create and attach a dependent event-manager.
993   // It is not added into eve list tree.
994
995   static const TEveException kEH("AliEveEventManager::AddDependentManager ");
996
997   if (fgMaster == 0)
998     throw(kEH + "Master event-manager must be instantiated first.");
999
1000   if (fgMaster->fSubManagers == 0)
1001   {
1002     fgMaster->fSubManagers = new TList;
1003     fgMaster->fSubManagers->SetOwner(kTRUE);
1004   }
1005
1006   AliEveEventManager* new_mgr = 0;
1007   fgCurrent = 0;
1008   try
1009   {
1010     new_mgr = new AliEveEventManager(name, path, fgMaster->fEventId);
1011     fgMaster->fSubManagers->Add(new_mgr);
1012   }
1013   catch (TEveException& exc)
1014   {
1015     ::Error(kEH, "Creation of new event-manager failed: '%s'.", exc.Data());
1016   }
1017   fgCurrent = fgMaster;
1018
1019   return new_mgr;
1020 }
1021
1022 AliEveEventManager* AliEveEventManager::GetDependentManager(const TString& name)
1023 {
1024   // Get a dependant manager by name.
1025   // This will not change the current manager, use helper class
1026   // AliEveEventManager::CurrentChanger for that.
1027
1028   static const TEveException kEH("AliEveEventManager::GetDependentManager ");
1029
1030   if (fgMaster == 0)
1031     throw(kEH + "Master event-manager must be instantiated first.");
1032
1033   if (fgMaster->fSubManagers == 0)
1034     return 0;
1035
1036   return dynamic_cast<AliEveEventManager*>(fgMaster->fSubManagers->FindObject(name));
1037 }
1038
1039 AliEveEventManager* AliEveEventManager::GetMaster()
1040 {
1041   // Get master event-manager.
1042
1043   return fgMaster;
1044 }
1045
1046 AliEveEventManager* AliEveEventManager::GetCurrent()
1047 {
1048   // Get current event-manager.
1049
1050   return fgCurrent;
1051 }
1052
1053 void AliEveEventManager::RegisterTransient(TEveElement* element)
1054 {
1055   GetCurrent()->fTransients->AddElement(element);
1056 }
1057
1058 //------------------------------------------------------------------------------
1059 // Autoloading of events
1060 //------------------------------------------------------------------------------
1061
1062 void AliEveEventManager::SetAutoLoadTime(Float_t time)
1063 {
1064   // Set the auto-load time in seconds
1065
1066   fAutoLoadTime = time;
1067 }
1068
1069 void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
1070 {
1071   // Set the automatic event loading mode
1072
1073   static const TEveException kEH("AliEveEventManager::SetAutoLoad ");
1074
1075   if (fAutoLoad == autoLoad)
1076   {
1077     Warning(kEH, "Setting autoload to the same value as before - %s. Ignoring.", fAutoLoad ? "true" : "false");
1078     return;
1079   }
1080
1081   fAutoLoad = autoLoad;
1082   if (fAutoLoad)
1083   {
1084     StartAutoLoadTimer();
1085   }
1086   else
1087   {
1088     StopAutoLoadTimer();
1089   }
1090 }
1091
1092 void AliEveEventManager::StartAutoLoadTimer()
1093 {
1094   // Start the auto-load timer.
1095
1096   fAutoLoadTimer->SetTime((Long_t)(1000*fAutoLoadTime));
1097   fAutoLoadTimer->Reset();
1098   fAutoLoadTimer->TurnOn();
1099   fAutoLoadTimerRunning = kTRUE;
1100 }
1101
1102 void AliEveEventManager::StopAutoLoadTimer()
1103 {
1104   // Stop the auto-load timer.
1105
1106   fAutoLoadTimerRunning = kFALSE;
1107   fAutoLoadTimer->TurnOff();
1108 }
1109
1110 void AliEveEventManager::AutoLoadNextEvent()
1111 {
1112   // Called from auto-load timer, so it has to be public.
1113   // Do NOT call it directly.
1114
1115   static const TEveException kEH("AliEveEventManager::AutoLoadNextEvent ");
1116
1117   if ( ! fAutoLoadTimerRunning || ! fAutoLoadTimer->HasTimedOut())
1118   {
1119     Warning(kEH, "Called unexpectedly - ignoring the call. Should ONLY be called from an internal timer.");
1120     return;
1121   }
1122
1123   StopAutoLoadTimer();
1124   NextEvent();
1125   if (fAutoLoad && !fExternalCtrl)
1126     StartAutoLoadTimer();
1127 }
1128
1129
1130 //------------------------------------------------------------------------------
1131 // Event selection by trigger
1132 //------------------------------------------------------------------------------
1133
1134 Bool_t AliEveEventManager::FindNextByTrigger(Int_t& event)
1135 {
1136   // Find next event that matches the trigger.
1137   // If a matching event is not found, we loop around and eventually
1138   // end up at the same event.
1139
1140   static const TEveException kEH("AliEveEventManager::FindNextByTrigger ");
1141
1142   if (!fESDTree) return kFALSE;
1143   TString firedtrclasses;
1144   for (Int_t i = fEventId+1; i<GetMaxEventId(kTRUE)+1; i++)
1145   {
1146     if (fESDTree->GetEntry(i) <= 0)
1147       throw (kEH + "failed getting required event from ESD.");
1148     firedtrclasses = fESD->GetFiredTriggerClasses();
1149     if (firedtrclasses.Contains(fTriggerType))
1150     {
1151       event=i;
1152       return kTRUE;
1153     }
1154   }
1155   for (Int_t i = 0; i<fEventId+1; i++)
1156   {
1157     if (fESDTree->GetEntry(i) <= 0)
1158       throw (kEH + "failed getting required event from ESD.");
1159     firedtrclasses = fESD->GetFiredTriggerClasses();
1160     if (firedtrclasses.Contains(fTriggerType))
1161     {
1162       event=i;
1163       return kTRUE;
1164     }
1165   }
1166   return kFALSE;
1167 }
1168
1169 Bool_t AliEveEventManager::FindPrevByTrigger(Int_t& event)
1170 {
1171   // Find previous event that matches the trigger.
1172
1173   static const TEveException kEH("AliEveEventManager::FindPrevByTrigger ");
1174
1175   if (!fESDTree) return kFALSE;
1176   TString firedtrclasses;
1177   for (Int_t i = fEventId-1; i>=0; i--)
1178   {
1179     if (fESDTree->GetEntry(i) <= 0)
1180       throw (kEH + "failed getting required event from ESD.");
1181     firedtrclasses = fESD->GetFiredTriggerClasses();
1182     if (firedtrclasses.Contains(fTriggerType))
1183     {
1184       event=i;
1185       return kTRUE;
1186     }
1187   }
1188   for (Int_t i = GetMaxEventId(kTRUE); i>fEventId-1; i--)
1189   {
1190     if (fESDTree->GetEntry(i) <= 0)
1191       throw (kEH + "failed getting required event from ESD.");
1192     firedtrclasses = fESD->GetFiredTriggerClasses();
1193     if (firedtrclasses.Contains(fTriggerType))
1194     {
1195       event=i;
1196       return kTRUE;
1197     }
1198   }
1199   return kFALSE;
1200 }
1201
1202
1203 //------------------------------------------------------------------------------
1204 // Post event-loading functions
1205 //------------------------------------------------------------------------------
1206
1207 void AliEveEventManager::AfterNewEventLoaded()
1208 {
1209   // Execute registered macros and commands.
1210   // At the end emit NewEventLoaded signal.
1211   //
1212   // Virtual from TEveEventManager.
1213
1214   static const TEveException kEH("AliEveEventManager::AfterNewEventLoaded ");
1215
1216   if (fExecutor)
1217     fExecutor->ExecMacros();
1218
1219   TEveEventManager::AfterNewEventLoaded();
1220
1221   NewEventLoaded();
1222
1223   if (this == fgMaster && fSubManagers != 0)
1224   {
1225     TIter next(fSubManagers);
1226     while ((fgCurrent = dynamic_cast<AliEveEventManager*>(next())) != 0)
1227     {
1228       gEve->SetCurrentEvent(fgCurrent);
1229       try
1230       {
1231         fgCurrent->GotoEvent(fEventId);
1232       }
1233       catch (TEveException& exc)
1234       {
1235         // !!! Should somehow tag / disable / remove it?
1236         Error(kEH, "Getting event %d for sub-event-manager '%s' failed: '%s'.",
1237               fEventId, fgCurrent->GetName(), exc.Data());
1238       }
1239     }
1240     fgCurrent = fgMaster;
1241     gEve->SetCurrentEvent(fgMaster);
1242   }
1243 }
1244
1245 void AliEveEventManager::NewEventLoaded()
1246 {
1247   // Emit NewEventLoaded signal.
1248
1249   Emit("NewEventLoaded()");
1250 }
1251
1252
1253 //------------------------------------------------------------------------------
1254 // Event info dumpers
1255 //------------------------------------------------------------------------------
1256
1257 TString AliEveEventManager::GetEventInfoHorizontal() const
1258 {
1259   // Dumps the event-header contents in vertical formatting.
1260
1261   TString rawInfo, esdInfo;
1262
1263   if (!fRawReader)
1264   {
1265     rawInfo = "No raw-data event info is available!\n";
1266   }
1267   else
1268   {
1269     const UInt_t* attr = fRawReader->GetAttributes();
1270     TTimeStamp ts(fRawReader->GetTimestamp());
1271     rawInfo.Form("RAW event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1272                  "Trigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x  Timestamp: %s\n",
1273                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1274                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1275                  fRawReader->GetClassMask(),
1276                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1277                  attr[0],attr[1],attr[2], ts.AsString("s"));
1278   }
1279
1280   if (!fESD)
1281   {
1282     esdInfo = "No ESD event info is available!";
1283   }
1284   else
1285   {
1286     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1287     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1288     TTimeStamp ts(fESD->GetTimeStamp());
1289     esdInfo.Form("ESD event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1290                  "Active trigger classes: %s\nTrigger: %llx (%s)\nEvent# in file: %d  Timestamp: %s, MagField: %.2e",
1291                  fESD->GetRunNumber(),
1292                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1293                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1294                  acttrclasses.Data(),
1295                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1296                  fESD->GetEventNumberInFile(), ts.AsString("s"), fESD->GetMagneticField());
1297   }
1298
1299   return rawInfo + esdInfo;
1300 }
1301
1302 TString AliEveEventManager::GetEventInfoVertical() const
1303 {
1304   // Dumps the event-header contents in vertical formatting.
1305
1306   TString rawInfo, esdInfo;
1307
1308   if (!fRawReader)
1309   {
1310     rawInfo = "No raw-data event info is available!\n";
1311   }
1312   else
1313   {
1314     const UInt_t* attr = fRawReader->GetAttributes();
1315     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",
1316                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1317                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1318                  fRawReader->GetClassMask(),
1319                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1320                  attr[0],attr[1],attr[2],
1321                  fRawReader->GetTimestamp());
1322   }
1323
1324   if (!fESD)
1325   {
1326     esdInfo = "No ESD event info is available!\n";
1327   }
1328   else
1329   {
1330     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1331     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1332     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",
1333                  fESD->GetRunNumber(),
1334                  acttrclasses.Data(),
1335                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1336                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1337                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1338                  fESD->GetEventNumberInFile(),
1339                  fESD->GetTimeStamp());
1340   }
1341
1342   return rawInfo + "\n" + esdInfo;
1343 }