* AliEveEventManager - make sure each AOD friend is only registered
[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 #include <TEveViewer.h>
14
15 #include <AliRunLoader.h>
16 #include <AliRun.h>
17 #include <AliESDRun.h>
18 #include <AliESDEvent.h>
19 #include <AliESDfriend.h>
20 #include <AliAODEvent.h>
21
22 #include <AliDAQ.h>
23 #include <AliRawEventHeaderBase.h>
24 #include <AliRawReaderRoot.h>
25 #include <AliRawReaderFile.h>
26 #include <AliRawReaderDate.h>
27 #include <AliMagF.h>
28 #include <AliCDBManager.h>
29 #include <AliCDBStorage.h>
30 #include <AliCDBEntry.h>
31 #include <AliGRPObject.h>
32 #include <AliHeader.h>
33 #include <AliGeomManager.h>
34
35 #include <TFile.h>
36 #include <TTree.h>
37 #include <TGeoManager.h>
38 #include <TGeoGlobalMagField.h>
39 #include <TSystem.h>
40 #include <TTimeStamp.h>
41 #include <TPRegexp.h>
42 #include <TError.h>
43
44 //==============================================================================
45 //==============================================================================
46 // AliEveEventManager
47 //==============================================================================
48
49 //______________________________________________________________________________
50 //
51 // Provides interface for loading and navigating standard AliRoot data
52 // (AliRunLoader), ESD, AOD and RAW.
53 //
54 // ESDfriend is attached automatically, if the file is found.
55 //
56 // AODfriends are not attached automatically as there are several
57 // possible files involved. To have a specific AODfriend attached, call
58 // static method
59 //   AliEveEventManager::AddAODfriend("AliAOD.VertexingHF.root");
60 // before initializing the event-manager.
61 //
62 // Also provides interface to magnetic-field and geometry. Mostly
63 // intended as wrappers over standard AliRoot functionality for
64 // convenient use from visualizateion macros.
65 //
66 // There can be a single main event-manger, it is stored in private
67 // data member fgMaster and can be accessed via static member function
68 // GetMaster().
69 //
70 // For event overlaying and embedding one can instantiate additional
71 // event-managers via static method AddDependentManager(const TString& path).
72 // This interface is under development.
73
74 ClassImp(AliEveEventManager)
75
76 Bool_t AliEveEventManager::fgAssertRunLoader = kFALSE;
77 Bool_t AliEveEventManager::fgAssertESD       = kFALSE;
78 Bool_t AliEveEventManager::fgAssertAOD       = kFALSE;
79 Bool_t AliEveEventManager::fgAssertRaw       = kFALSE;
80
81 TString  AliEveEventManager::fgESDFileName("AliESDs.root");
82 TString  AliEveEventManager::fgAODFileName("AliAOD.root");
83 TString  AliEveEventManager::fgRawFileName("raw.root");
84 TString  AliEveEventManager::fgCdbUri("local://$ALICE_ROOT/OCDB");
85
86 TList*   AliEveEventManager::fgAODfriends = 0;
87
88 AliGRPObject* AliEveEventManager::fgGRPData      = 0;
89 AliMagF*      AliEveEventManager::fgMagField     = 0;
90 Bool_t        AliEveEventManager::fgUniformField = kFALSE;
91
92 AliEveEventManager* AliEveEventManager::fgMaster  = 0;
93 AliEveEventManager* AliEveEventManager::fgCurrent = 0;
94
95 void AliEveEventManager::InitInternals()
96 {
97   // Initialize internal members.
98
99   static const TEveException kEH("AliEveEventManager::InitInternals ");
100
101   if (fgCurrent != 0)
102   {
103     throw(kEH + "Dependent event-managers should be created via static method AddDependentManager().");
104   }
105
106   if (fgMaster == 0)
107   {
108     fgMaster = this;
109   }
110
111   fgCurrent = this;
112
113   fAutoLoadTimer = new TTimer;
114   fAutoLoadTimer->Connect("Timeout()", "AliEveEventManager", this, "AutoLoadNextEvent()");
115
116   fExecutor = new AliEveMacroExecutor;
117
118   fTransients = new TEveElementList("Transients", "Transient per-event elements.");
119   fTransients->IncDenyDestroy();
120   gEve->AddToListTree(fTransients, kFALSE);
121
122   fTransientLists = new TEveElementList("Transient Lists", "Containers of transient elements.");
123   fTransientLists->IncDenyDestroy();
124   gEve->AddToListTree(fTransientLists, kFALSE);
125 }
126
127 AliEveEventManager::AliEveEventManager(const TString& name) :
128   TEveEventManager(name),
129
130   fPath      ( ), fEventId (-1),
131   fRunLoader (0),
132   fESDFile   (0), fESDTree (0), fESD (0),
133   fESDfriend (0), fESDfriendExists(kFALSE),
134   fAODFile   (0), fAODTree (0), fAOD (0),
135   fRawReader (0),
136   fAutoLoad  (kFALSE), fAutoLoadTime (5.),     fAutoLoadTimer(0),
137   fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
138   fSelectOnTriggerType(kFALSE), fTriggerType(""),
139   fExecutor    (0), fTransients(0), fTransientLists(0),
140   fSubManagers (0),
141   fAutoLoadTimerRunning(kFALSE)
142 {
143   // Default constructor.
144
145   InitInternals();
146 }
147
148 AliEveEventManager::AliEveEventManager(const TString& name, const TString& path, Int_t ev) :
149   TEveEventManager(name, path),
150
151   fPath   (path), fEventId(-1),
152   fRunLoader (0),
153   fESDFile   (0), fESDTree (0), fESD (0),
154   fESDfriend (0), fESDfriendExists(kFALSE),
155   fAODFile   (0), fAODTree (0), fAOD (0),
156   fRawReader (0),
157   fAutoLoad  (kFALSE), fAutoLoadTime (5),      fAutoLoadTimer(0),
158   fIsOpen    (kFALSE), fHasEvent     (kFALSE), fExternalCtrl (kFALSE),
159   fSelectOnTriggerType(kFALSE), fTriggerType(""),
160   fExecutor    (0), fTransients(0), fTransientLists(0),
161   fSubManagers (0),
162   fAutoLoadTimerRunning(kFALSE)
163 {
164   // Constructor with event-directory URL and event-id.
165
166   InitInternals();
167
168   Open();
169   if (ev >= 0)
170   {
171     GotoEvent(ev);
172   }
173 }
174
175 AliEveEventManager::~AliEveEventManager()
176 {
177   // Destructor.
178
179   delete fSubManagers;
180
181   if (fIsOpen)
182   {
183     Close();
184   }
185
186   fTransients->DecDenyDestroy();
187   fTransients->Destroy();
188
189   fTransientLists->DecDenyDestroy();
190   fTransientLists->Destroy();
191 }
192
193 /******************************************************************************/
194
195 void AliEveEventManager::SetESDFileName(const TString& esd)
196 {
197   // Set file-name for opening ESD, default "AliESDs.root".
198
199   if ( ! esd.IsNull()) fgESDFileName = esd;
200 }
201
202 void AliEveEventManager::SetAODFileName(const TString& aod)
203 {
204   // Set file-name for opening AOD, default "AliAOD.root".
205
206   if ( ! aod.IsNull()) fgAODFileName = aod;
207 }
208
209 void AliEveEventManager::AddAODfriend(const TString& friendFileName)
210 {
211   // Add new AOD friend file-name to be attached when opening AOD.
212   // This should include '.root', as in 'AliAOD.VertexingHF.root'.
213
214   if (fgAODfriends == 0)
215   {
216     fgAODfriends = new TList;
217     fgAODfriends->SetOwner(kTRUE);
218   }
219   if (fgAODfriends->FindObject(friendFileName) == 0)
220   {
221     fgAODfriends->Add(new TObjString(friendFileName));
222   }
223 }
224
225 void AliEveEventManager::SetRawFileName(const TString& raw)
226 {
227   // Set file-name for opening of raw-data, default "raw.root"
228   if ( ! raw.IsNull()) fgRawFileName = raw;
229 }
230
231 void AliEveEventManager::SetCdbUri(const TString& cdb)
232 {
233   // Set path to CDB, default "local://$ALICE_ROOT/OCDB".
234
235   if ( ! cdb.IsNull()) fgCdbUri = cdb;
236 }
237
238 void AliEveEventManager::SetAssertElements(Bool_t assertRunloader, Bool_t assertEsd,
239                                            Bool_t assertAod, Bool_t assertRaw)
240 {
241   // Set global flags that detrmine which parts of the event-data must
242   // be present when the event is opened.
243
244   fgAssertRunLoader = assertRunloader;
245   fgAssertESD = assertEsd;
246   fgAssertAOD = assertAod;
247   fgAssertRaw = assertRaw;
248 }
249
250 /******************************************************************************/
251
252 void AliEveEventManager::Open()
253 {
254   // Open event-data from URL specified in fPath.
255   // Attempts to create AliRunLoader() and to open ESD with ESDfriends.
256   // Warning is reported if run-loader or ESD is not found.
257   // Global data-members fgAssertRunLoader and fgAssertESD can be set
258   // to throw exceptions instead.
259
260   static const TEveException kEH("AliEveEventManager::Open ");
261
262   if (fExternalCtrl)
263   {
264     throw (kEH + "Event-loop is under external control.");
265   }
266   if (fIsOpen)
267   {
268     throw (kEH + "Event-files already opened.");
269   }
270
271   gSystem->ExpandPathName(fPath);
272   // The following magick is required for ESDfriends to be loaded properly
273   // from non-current directory.
274   if (fPath.IsNull() || fPath == ".")
275   {
276     fPath = gSystem->WorkingDirectory();
277   }
278   else if ( ! fPath.BeginsWith("file:/"))
279   {
280     TUrl    url(fPath, kTRUE);
281     TString protocol(url.GetProtocol());
282     if (protocol == "file" && fPath[0] != '/')
283       fPath = Form("%s/%s", gSystem->WorkingDirectory(), fPath.Data());
284   }
285
286   Int_t runNo = -1;
287
288   // Open ESD and ESDfriends
289
290   TString esdPath(Form("%s/%s", fPath.Data(), fgESDFileName.Data()));
291   if ((fESDFile = TFile::Open(esdPath)))
292   {
293     fESD = new AliESDEvent();
294     fESDTree = (TTree*) fESDFile->Get("esdTree");
295     if (fESDTree != 0)
296     {
297       // Check if ESDfriends exists and attach the branch.
298       // We use TFile::Open() instead of gSystem->AccessPathName
299       // as it seems to work better when attachine alieve to a
300       // running reconstruction process with auto-save on.
301       // There was also a problem with TTree::Refresh() - it didn't
302       // save the friend branch on a separate file, fixed in 5.22.2 -
303       // so we might want to try the old way again soon.
304       TString p(Form("%s/AliESDfriends.root", fPath.Data()));
305       TFile *esdFriendFile = TFile::Open(p);
306       if (esdFriendFile)
307       {
308         if (!esdFriendFile->IsZombie())
309         {
310           esdFriendFile->Close();
311           fESDfriendExists = kTRUE;
312           fESDTree->SetBranchStatus ("ESDfriend*", 1);
313         }
314         delete esdFriendFile;
315       }
316
317       fESD->ReadFromTree(fESDTree);
318       if (fESDfriendExists)
319       {
320         fESDfriend = (AliESDfriend*) fESD->FindListObject("AliESDfriend");
321         Info(kEH, "found and attached ESD friend.");
322       }
323       else
324       {
325         Warning(kEH, "ESDfriend not found.");
326       }
327
328       if (fESDTree->GetEntry(0) <= 0)
329       {
330         delete fESDFile; fESDFile = 0;
331         delete fESD; fESD = 0;
332         Warning(kEH, "failed getting the first entry from esdTree.");
333       }
334       else
335       {
336         if (runNo < 0)
337           runNo = fESD->GetESDRun()->GetRunNumber();
338       }
339     }
340     else // esdtree == 0
341     {
342       delete fESDFile; fESDFile = 0;
343       delete fESD; fESD = 0;
344       Warning(kEH, "failed getting the esdTree.");
345     }
346   }
347   else // esd not readable
348   {
349     Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
350   }
351   if (fESDTree == 0)
352   {
353     if (fgAssertESD)
354     {
355       throw (kEH + "ESD not initialized. Its precence was requested.");
356     } else {
357       Warning(kEH, "ESD not initialized.");
358     }
359   }
360
361   // Open AOD and registered friends
362
363   TString aodPath(Form("%s/%s", fPath.Data(), fgAODFileName.Data()));
364   if ((fAODFile = TFile::Open(aodPath)))
365   {
366     fAOD = new AliAODEvent();
367     fAODTree = (TTree*) fAODFile->Get("aodTree");
368     if (fAODTree != 0)
369     {
370       // Check if AODfriends exist and attach them.
371       TIter       friends(fgAODfriends);
372       TObjString *name;
373       while ((name = (TObjString*) friends()) != 0)
374       {
375         TString p(Form("%s/%s", fPath.Data(), name->GetName()));
376         if (gSystem->AccessPathName(p, kReadPermission) == kFALSE)
377         {
378           fAODTree->AddFriend("aodTree", name->GetName());
379         }
380       }
381
382       fAOD->ReadFromTree(fAODTree);
383
384       if (fAODTree->GetEntry(0) <= 0)
385       {
386         delete fAODFile; fAODFile = 0;
387         delete fAOD;     fAOD     = 0;
388         Warning(kEH, "failed getting the first entry from addTree.");
389       }
390       else
391       {
392         if (runNo < 0)
393           runNo = fAOD->GetRunNumber();
394       }
395     }
396     else // aodtree == 0
397     {
398       delete fAODFile; fAODFile = 0;
399       delete fAOD;     fAOD     = 0;
400       Warning(kEH, "failed getting the aodTree.");
401     }
402   }
403   else // aod not readable
404   {
405     Warning(kEH, "can not read AOD file '%s'.", aodPath.Data());
406   }
407   if (fAODTree == 0)
408   {
409     if (fgAssertAOD)
410     {
411       throw (kEH + "AOD not initialized. Its precence was requested.");
412     } else {
413       Warning(kEH, "AOD not initialized.");
414     }
415   }
416
417   // Open RunLoader from galice.root
418
419   TString gaPath(Form("%s/galice.root", fPath.Data()));
420   // If i use open directly, we get fatal.
421   // Is AccessPathName check ok for xrootd / alien? Yes, not for http.
422   if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
423   {
424     fRunLoader = AliRunLoader::Open(gaPath, GetName());
425     if (fRunLoader)
426     {
427       TString alicePath = fPath + "/";
428       fRunLoader->SetDirName(alicePath);
429
430       if (fRunLoader->LoadgAlice() != 0)
431         Warning(kEH, "failed loading gAlice via run-loader.");
432
433       if (fRunLoader->LoadHeader() == 0)
434       {
435         if (runNo < 0)
436           runNo = fRunLoader->GetHeader()->GetRun();
437       }
438       else
439       {
440         Warning(kEH, "failed loading run-loader's header.");
441         delete fRunLoader;
442         fRunLoader = 0;
443       }
444     }
445     else // run-loader open failed
446     {
447       Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
448     }
449   }
450   else // galice not readable
451   {
452     Warning(kEH, "can not read '%s'.", gaPath.Data());
453   }
454   if (fRunLoader == 0)
455   {
456     if (fgAssertRunLoader)
457       throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
458     else
459       Warning(kEH, "Bootstraping of run-loader failed.");
460   }
461
462   // Open raw-data file
463
464   TString rawPath(Form("%s/%s", fPath.Data(), fgRawFileName.Data()));
465   // If i use open directly, raw-reader reports an error but i have
466   // no way to detect it.
467   // Is this (AccessPathName check) ok for xrootd / alien? Yes, not for http.
468   AliLog::EType_t oldLogLevel = (AliLog::EType_t) AliLog::GetGlobalLogLevel();
469   if (fgAssertRaw == kFALSE)
470   {
471     AliLog::SetGlobalLogLevel(AliLog::kFatal);
472   }
473   if (gSystem->AccessPathName(rawPath, kReadPermission) == kFALSE)
474   {
475     fRawReader = AliRawReader::Create(rawPath);
476   }
477   else
478   {
479     fRawReader = AliRawReader::Create(fgRawFileName);
480   }
481   if (fgAssertRaw == kFALSE)
482   {
483     AliLog::SetGlobalLogLevel(oldLogLevel);
484   }
485
486   if (fRawReader == 0)
487   {
488     if (fgAssertRaw)
489     {
490       throw (kEH + "raw-data not initialized. Its precence was requested.");
491     } else {
492       Warning(kEH, "raw-data not initialized.");
493     }
494   }
495
496   if (runNo < 0)
497   {
498     if (fRawReader)
499     {
500       fRawReader->NextEvent();
501       runNo = fRawReader->GetRunNumber();
502       Info(kEH, "Determining run-no from raw ... run=%d.", runNo);
503       fRawReader->RewindEvents();
504     } else {
505       throw (kEH + "unknown run number.");
506     }
507   }
508
509   // Initialize OCDB ... only in master event-manager
510
511   if (this == fgMaster)
512   {
513     AliCDBManager* cdb = AliCDBManager::Instance();
514     if (cdb->IsDefaultStorageSet() == kTRUE)
515     {
516       Warning(kEH, "CDB already set - using the old storage:\n  '%s'",
517               cdb->GetDefaultStorage()->GetURI().Data());
518     }
519     else
520     {
521       cdb->SetDefaultStorage(fgCdbUri);
522       if (cdb->IsDefaultStorageSet() == kFALSE)
523         throw (kEH + "CDB initialization failed.");
524     }
525     cdb->SetRun(runNo);
526   }
527
528   fIsOpen = kTRUE;
529 }
530
531 void AliEveEventManager::SetEvent(AliRunLoader *runLoader, AliRawReader *rawReader, AliESDEvent *esd, AliESDfriend *esdf)
532 {
533   // Set an event from an external source.
534   // The method is used in the online visualisation.
535   // AOD is not supported.
536
537   static const TEveException kEH("AliEveEventManager::SetEvent ");
538
539   if (fIsOpen)
540   {
541     Warning(kEH, "Event-files were open. Closing and switching to external control.");
542     Close();
543   }
544
545   fRunLoader = runLoader;
546   fRawReader = rawReader;
547   fESD       = esd;
548   fESDfriend = esdf;
549   fAOD       = 0;
550
551   fEventId++;
552   fHasEvent     = kTRUE;
553   fExternalCtrl = kTRUE;
554
555   SetTitle("Online event in memory");
556   SetName ("Online Event");
557   ElementChanged();
558
559   AfterNewEventLoaded();
560
561   if (fAutoLoad) StartAutoLoadTimer();
562 }
563
564 Int_t AliEveEventManager::GetMaxEventId(Bool_t /*refreshESD*/) const
565 {
566   // Returns maximum available event id.
567   // If under external control or event is not opened -1 is returned.
568   // If raw-data is the only data-source this can not be known
569   // and 10,000,000 is returned.
570   // If neither data-source is initialised an exception is thrown.
571   // If refresh_esd is true and ESD is the primary event-data source
572   // its header is re-read from disk.
573
574   static const TEveException kEH("AliEveEventManager::GetMaxEventId ");
575
576   if (fExternalCtrl || fIsOpen == kFALSE)
577   {
578     return -1;
579   }
580
581   if (fESDTree)
582   {
583     // Refresh crashes with root-5.21.1-alice.
584     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
585     // when we move to a newer root.
586     // if (refreshESD)
587     //   fESDTree->Refresh();
588     return fESDTree->GetEntries() - 1;
589   }
590   else if (fAODTree)
591   {
592     return fAODTree->GetEntries() - 1;
593   }
594   else if (fRunLoader)
595   {
596     return fRunLoader->GetNumberOfEvents() - 1;
597   }
598   else if (fRawReader)
599   {
600     Int_t n = fRawReader->GetNumberOfEvents() - 1;
601     return n > -1 ? n : 10000000;
602   }
603   else
604   {
605     throw (kEH + "neither ESD, AOD, RunLoader nor Raw loaded.");
606   }
607 }
608
609 void AliEveEventManager::GotoEvent(Int_t event)
610 {
611   // Load data for specified event.
612   // If event is out of range an exception is thrown and old state
613   // is preserved.
614   // After successful loading of event, the virtual function
615   // AfterNewEventLoaded() is called. This executes commands that
616   // were registered via TEveEventManager::AddNewEventCommand().
617   //
618   // If event is negative, it is subtracted from the number of
619   // available events, thus passing -1 will load the last event.
620   // This is not supported when raw-data is the only data-source
621   // as the number of events is not known.
622
623   static const TEveException kEH("AliEveEventManager::GotoEvent ");
624
625   if (fAutoLoadTimerRunning)
626   {
627     throw (kEH + "Event auto-load timer is running.");
628   }
629   if (fExternalCtrl)
630   {
631     throw (kEH + "Event-loop is under external control.");
632   }
633   else if (!fIsOpen)
634   {
635     throw (kEH + "Event-files not opened.");
636   }
637
638   fHasEvent = kFALSE;
639
640   Int_t maxEvent = 0;
641   if (fESDTree)
642   {
643     // Refresh crashes with root-5.21.1-alice.
644     // Fixed by Philippe 5.8.2008 r25053, can be reactivated
645     // when we move to a newer root.
646     // fESDTree->Refresh();
647     maxEvent = fESDTree->GetEntries() - 1;
648     if (event < 0)
649       event = fESDTree->GetEntries() + event;
650   }
651   else if (fAODTree)
652   {
653     maxEvent = fAODTree->GetEntries() - 1;
654     if (event < 0)
655       event = fAODTree->GetEntries() + event;
656   }
657   else if (fRunLoader)
658   {
659     maxEvent = fRunLoader->GetNumberOfEvents() - 1;
660     if (event < 0)
661       event = fRunLoader->GetNumberOfEvents() + event;
662   }
663   else if (fRawReader)
664   {
665     maxEvent = fRawReader->GetNumberOfEvents() - 1;
666     if (maxEvent < 0)
667     {
668       maxEvent = 10000000;
669       if (event < 0) {
670         Error(kEH, "current raw-data source does not support direct event access.");
671         return;
672       }
673       Info(kEH, "number of events unknown for current raw-data source, setting max-event id to 10M.");
674     }
675     else
676     {
677       if (event < 0)
678         event = fRawReader->GetNumberOfEvents() + event;
679     }
680   }
681   else
682   {
683     throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
684   }
685   if (event < 0 || event > maxEvent)
686   {
687     throw (kEH + Form("event %d not present, available range [%d, %d].",
688                       event, 0, maxEvent));
689   }
690
691   TEveManager::TRedrawDisabler rd(gEve);
692   gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
693
694   // !!! MT this is somewhat brutal; at least optionally, one could be
695   // a bit gentler, checking for objs owning their external refs and having
696   // additinal parents.
697   gEve->GetViewers()->DeleteAnnotations();
698   fTransients->DestroyElements();
699   for (TEveElement::List_i i = fTransientLists->BeginChildren();
700        i != fTransientLists->EndChildren(); ++i)
701   {
702     (*i)->DestroyElements();
703   }
704   DestroyElements();
705
706   if (fESDTree) {
707     if (fESDTree->GetEntry(event) <= 0)
708       throw (kEH + "failed getting required event from ESD.");
709
710     if (fESDfriendExists)
711       fESD->SetESDfriend(fESDfriend);
712   }
713
714   if (fAODTree) {
715     if (fAODTree->GetEntry(event) <= 0)
716       throw (kEH + "failed getting required event from AOD.");
717   }
718
719   if (fRunLoader) {
720     if (fRunLoader->GetEvent(event) != 0)
721       throw (kEH + "failed getting required event.");
722   }
723
724   if (fRawReader)
725   {
726     // AliRawReader::GotoEvent(Int_t) works for AliRawReaderRoot/Chain.
727     if (fRawReader->GotoEvent(event) == kFALSE)
728     {
729       // Use fallback method - iteration with NextEvent().
730       Int_t rawEv = fEventId;
731       if (event < rawEv)
732       {
733         fRawReader->RewindEvents();
734         rawEv = -1;
735       }
736
737       while (rawEv < event)
738       {
739         if ( ! fRawReader->NextEvent())
740         {
741           fRawReader->RewindEvents();
742           fEventId = -1;
743           throw (kEH + Form("Error going to next raw-event from event %d.", rawEv));
744         }
745         ++rawEv;
746       }
747       Warning(kEH, "Loaded raw-event %d with fallback method.\n", rawEv);
748     }
749   }
750
751   fHasEvent = kTRUE;
752   fEventId  = event;
753   if (this == fgMaster)
754   {
755     SetName(Form("Event %d", fEventId));
756     ElementChanged();
757   }
758
759   AfterNewEventLoaded();
760 }
761
762 void AliEveEventManager::NextEvent()
763 {
764   // Loads next event.
765   // Does magick needed for online display when under external event control.
766
767   static const TEveException kEH("AliEveEventManager::NextEvent ");
768
769   if (fAutoLoadTimerRunning)
770   {
771     throw (kEH + "Event auto-load timer is running.");
772   }
773
774   if (fExternalCtrl)
775   {
776     // !!! This should really go somewhere else. It is done in GotoEvent(),
777     // so here we should do it in SetEvent().
778     DestroyElements();
779
780     gSystem->ExitLoop();
781   }
782   else
783   {
784     Int_t nexteventbytrigger=0;
785     if (fSelectOnTriggerType)
786     {
787       if (FindNextByTrigger(nexteventbytrigger)) //if not found do nothing
788         GotoEvent(nexteventbytrigger);
789     }
790     else if (fEventId < GetMaxEventId(kTRUE))
791       GotoEvent(fEventId + 1);
792     else
793       GotoEvent(0);
794   }
795 }
796
797 void AliEveEventManager::PrevEvent()
798 {
799   // Loads previous event.
800
801   static const TEveException kEH("AliEveEventManager::PrevEvent ");
802
803   if (fAutoLoadTimerRunning)
804   {
805     throw (kEH + "Event auto-load timer is running.");
806   }
807   if (fExternalCtrl)
808   {
809     throw (kEH + "Event-loop is under external control.");
810   }
811   Int_t nexteventbytrigger=0;
812   if (fSelectOnTriggerType)
813   {
814     if (FindPrevByTrigger(nexteventbytrigger))
815       GotoEvent(nexteventbytrigger);
816   }
817   else
818     GotoEvent(fEventId - 1);
819 }
820
821 void AliEveEventManager::Close()
822 {
823   // Close the event data-files and delete ESD, ESDfriend, run-loader
824   // and raw-reader.
825
826   static const TEveException kEH("AliEveEventManager::Close ");
827
828   if (!fIsOpen)
829   {
830     throw (kEH + "Event-files not opened.");
831   }
832
833   if (fAutoLoadTimerRunning)
834     StopAutoLoadTimer();
835
836   if (fESDTree) {
837     delete fESD;       fESD       = 0;
838     delete fESDfriend; fESDfriend = 0;
839     fESDfriendExists = kFALSE;
840
841     delete fESDTree;   fESDTree = 0;
842     delete fESDFile;   fESDFile = 0;
843   }
844
845   if (fAODTree) {
846     delete fAOD;       fAOD       = 0;
847
848     delete fAODTree;   fAODTree = 0;
849     delete fAODFile;   fAODFile = 0;
850   }
851
852   if (fRunLoader) {
853     delete fRunLoader; fRunLoader = 0;
854   }
855
856   if (fRawReader) {
857     delete fRawReader; fRawReader = 0;
858   }
859
860   fEventId  = -1;
861   fIsOpen   = kFALSE;
862   fHasEvent = kFALSE;
863 }
864
865
866 //------------------------------------------------------------------------------
867 // Static convenience functions, mainly used from macros.
868 //------------------------------------------------------------------------------
869
870 Bool_t AliEveEventManager::HasRunLoader()
871 {
872   // Check if AliRunLoader is initialized.
873
874   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRunLoader;
875 }
876
877 Bool_t AliEveEventManager::HasESD()
878 {
879   // Check if AliESDEvent is initialized.
880
881   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESD;
882 }
883
884 Bool_t AliEveEventManager::HasESDfriend()
885 {
886   // Check if AliESDfriend is initialized.
887
888   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESDfriend;
889 }
890
891 Bool_t AliEveEventManager::HasAOD()
892 {
893   // Check if AliESDEvent is initialized.
894
895   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fAOD;
896 }
897
898 Bool_t AliEveEventManager::HasRawReader()
899 {
900   // Check if raw-reader is initialized.
901
902   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRawReader;
903 }
904
905 AliRunLoader* AliEveEventManager::AssertRunLoader()
906 {
907   // Make sure AliRunLoader is initialized and return it.
908   // Throws exception in case run-loader is not available.
909   // Static utility for macros.
910
911   static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
912
913   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
914     throw (kEH + "ALICE event not ready.");
915   if (fgCurrent->fRunLoader == 0)
916     throw (kEH + "AliRunLoader not initialised.");
917   return fgCurrent->fRunLoader;
918 }
919
920 AliESDEvent* AliEveEventManager::AssertESD()
921 {
922   // Make sure AliESDEvent is initialized and return it.
923   // Throws exception in case ESD is not available.
924   // Static utility for macros.
925
926   static const TEveException kEH("AliEveEventManager::AssertESD ");
927
928   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
929     throw (kEH + "ALICE event not ready.");
930   if (fgCurrent->fESD == 0)
931     throw (kEH + "AliESD not initialised.");
932   return fgCurrent->fESD;
933 }
934
935 AliESDfriend* AliEveEventManager::AssertESDfriend()
936 {
937   // Make sure AliESDfriend is initialized and return it.
938   // Throws exception in case ESDfriend-loader is not available.
939   // Static utility for macros.
940
941   static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
942
943   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
944     throw (kEH + "ALICE event not ready.");
945   if (fgCurrent->fESDfriend == 0)
946     throw (kEH + "AliESDfriend not initialised.");
947   return fgCurrent->fESDfriend;
948 }
949
950 AliAODEvent* AliEveEventManager::AssertAOD()
951 {
952   // Make sure AliAODEvent is initialized and return it.
953   // Throws exception in case AOD is not available.
954   // Static utility for macros.
955
956   static const TEveException kEH("AliEveEventManager::AssertAOD ");
957
958   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
959     throw (kEH + "ALICE event not ready.");
960   if (fgCurrent->fAOD == 0)
961     throw (kEH + "AliAOD not initialised.");
962   return fgCurrent->fAOD;
963 }
964
965 AliRawReader* AliEveEventManager::AssertRawReader()
966 {
967   // Make sure raw-reader is initialized and return it.
968
969   static const TEveException kEH("AliEveEventManager::AssertRawReader ");
970
971   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
972     throw (kEH + "ALICE event not ready.");
973   if (fgCurrent->fRawReader == 0)
974     throw (kEH + "RawReader not ready.");
975
976   return fgCurrent->fRawReader;
977 }
978
979 //==============================================================================
980
981 AliMagF* AliEveEventManager::AssertMagField()    
982 {        
983   // Make sure AliMagF is initialized and returns it.    
984   // Throws exception in case magnetic field is not available.   
985   // Static utility for macros.          
986
987   static const TEveException kEH("AliEveEventManager::AssertMagField ");         
988                  
989   if (fgMagField)
990     return fgMagField;
991
992   if (fgGRPData == 0)
993   {
994     InitGRP();
995   }
996
997   if (TGeoGlobalMagField::Instance())
998   {
999     fgMagField = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField());
1000     if (fgMagField == 0)
1001       throw kEH + "Global field set, but it is not AliMagF.";
1002   }
1003   else
1004   {
1005     throw kEH + "Could not initialize magnetic field.";
1006   }
1007
1008   return fgMagField;     
1009 }
1010
1011 TGeoManager* AliEveEventManager::AssertGeometry()
1012 {
1013   // Make sure AliGeomManager is initialized and returns the
1014   // corresponding TGeoManger.
1015   // gGeoManager is set to the return value.
1016   // Throws exception if geometry can not be loaded or if it is not
1017   // available and the TGeoManager is locked.
1018   // Static utility for macros.
1019
1020   static const TEveException kEH("AliEveEventManager::AssertGeometry ");
1021
1022   if (AliGeomManager::GetGeometry() == 0)
1023   {
1024     if (TGeoManager::IsLocked())
1025       throw (kEH + "geometry is not loaded but TGeoManager is locked.");
1026
1027     gGeoManager = 0;
1028     AliGeomManager::LoadGeometry();
1029     if ( ! AliGeomManager::GetGeometry())
1030     {
1031       throw (kEH + "can not load geometry.");
1032     }
1033     if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
1034     {
1035       ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
1036       // throw (kEH + "could not apply align objs.");
1037     }
1038     AliGeomManager::GetGeometry()->DefaultColors();
1039   }
1040
1041   gGeoManager = AliGeomManager::GetGeometry();
1042   return gGeoManager;
1043 }
1044
1045 //------------------------------------------------------------------------------
1046
1047 AliEveEventManager* AliEveEventManager::AddDependentManager(const TString& name, const TString& path)
1048 {
1049   // Create and attach a dependent event-manager.
1050   // It is not added into eve list tree.
1051
1052   static const TEveException kEH("AliEveEventManager::AddDependentManager ");
1053
1054   if (fgMaster == 0)
1055     throw(kEH + "Master event-manager must be instantiated first.");
1056
1057   if (fgMaster->fSubManagers == 0)
1058   {
1059     fgMaster->fSubManagers = new TList;
1060     fgMaster->fSubManagers->SetOwner(kTRUE);
1061   }
1062
1063   AliEveEventManager* new_mgr = 0;
1064   fgCurrent = 0;
1065   try
1066   {
1067     new_mgr = new AliEveEventManager(name, path, fgMaster->fEventId);
1068     fgMaster->fSubManagers->Add(new_mgr);
1069   }
1070   catch (TEveException& exc)
1071   {
1072     ::Error(kEH, "Creation of new event-manager failed: '%s'.", exc.Data());
1073   }
1074   fgCurrent = fgMaster;
1075
1076   return new_mgr;
1077 }
1078
1079 AliEveEventManager* AliEveEventManager::GetDependentManager(const TString& name)
1080 {
1081   // Get a dependant manager by name.
1082   // This will not change the current manager, use helper class
1083   // AliEveEventManager::CurrentChanger for that.
1084
1085   static const TEveException kEH("AliEveEventManager::GetDependentManager ");
1086
1087   if (fgMaster == 0)
1088     throw(kEH + "Master event-manager must be instantiated first.");
1089
1090   if (fgMaster->fSubManagers == 0)
1091     return 0;
1092
1093   return dynamic_cast<AliEveEventManager*>(fgMaster->fSubManagers->FindObject(name));
1094 }
1095
1096 AliEveEventManager* AliEveEventManager::GetMaster()
1097 {
1098   // Get master event-manager.
1099
1100   return fgMaster;
1101 }
1102
1103 AliEveEventManager* AliEveEventManager::GetCurrent()
1104 {
1105   // Get current event-manager.
1106
1107   return fgCurrent;
1108 }
1109
1110 void AliEveEventManager::RegisterTransient(TEveElement* element)
1111 {
1112   GetCurrent()->fTransients->AddElement(element);
1113 }
1114
1115 void AliEveEventManager::RegisterTransientList(TEveElement* element)
1116 {
1117   GetCurrent()->fTransientLists->AddElement(element);
1118 }
1119
1120 //------------------------------------------------------------------------------
1121 // Autoloading of events
1122 //------------------------------------------------------------------------------
1123
1124 void AliEveEventManager::SetAutoLoadTime(Float_t time)
1125 {
1126   // Set the auto-load time in seconds
1127
1128   fAutoLoadTime = time;
1129 }
1130
1131 void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
1132 {
1133   // Set the automatic event loading mode
1134
1135   static const TEveException kEH("AliEveEventManager::SetAutoLoad ");
1136
1137   if (fAutoLoad == autoLoad)
1138   {
1139     Warning(kEH, "Setting autoload to the same value as before - %s. Ignoring.", fAutoLoad ? "true" : "false");
1140     return;
1141   }
1142
1143   fAutoLoad = autoLoad;
1144   if (fAutoLoad)
1145   {
1146     StartAutoLoadTimer();
1147   }
1148   else
1149   {
1150     StopAutoLoadTimer();
1151   }
1152 }
1153
1154 void AliEveEventManager::StartAutoLoadTimer()
1155 {
1156   // Start the auto-load timer.
1157
1158   fAutoLoadTimer->SetTime((Long_t)(1000*fAutoLoadTime));
1159   fAutoLoadTimer->Reset();
1160   fAutoLoadTimer->TurnOn();
1161   fAutoLoadTimerRunning = kTRUE;
1162 }
1163
1164 void AliEveEventManager::StopAutoLoadTimer()
1165 {
1166   // Stop the auto-load timer.
1167
1168   fAutoLoadTimerRunning = kFALSE;
1169   fAutoLoadTimer->TurnOff();
1170 }
1171
1172 void AliEveEventManager::AutoLoadNextEvent()
1173 {
1174   // Called from auto-load timer, so it has to be public.
1175   // Do NOT call it directly.
1176
1177   static const TEveException kEH("AliEveEventManager::AutoLoadNextEvent ");
1178
1179   if ( ! fAutoLoadTimerRunning || ! fAutoLoadTimer->HasTimedOut())
1180   {
1181     Warning(kEH, "Called unexpectedly - ignoring the call. Should ONLY be called from an internal timer.");
1182     return;
1183   }
1184
1185   StopAutoLoadTimer();
1186   NextEvent();
1187   if (fAutoLoad && !fExternalCtrl)
1188     StartAutoLoadTimer();
1189 }
1190
1191
1192 //------------------------------------------------------------------------------
1193 // Event selection by trigger
1194 //------------------------------------------------------------------------------
1195
1196 Bool_t AliEveEventManager::FindNextByTrigger(Int_t& event)
1197 {
1198   // Find next event that matches the trigger.
1199   // If a matching event is not found, we loop around and eventually
1200   // end up at the same event.
1201
1202   static const TEveException kEH("AliEveEventManager::FindNextByTrigger ");
1203
1204   if (!fESDTree) return kFALSE;
1205   TString firedtrclasses;
1206   for (Int_t i = fEventId+1; i<GetMaxEventId(kTRUE)+1; i++)
1207   {
1208     if (fESDTree->GetEntry(i) <= 0)
1209       throw (kEH + "failed getting required event from ESD.");
1210     firedtrclasses = fESD->GetFiredTriggerClasses();
1211     if (firedtrclasses.Contains(fTriggerType))
1212     {
1213       event=i;
1214       return kTRUE;
1215     }
1216   }
1217   for (Int_t i = 0; i<fEventId+1; i++)
1218   {
1219     if (fESDTree->GetEntry(i) <= 0)
1220       throw (kEH + "failed getting required event from ESD.");
1221     firedtrclasses = fESD->GetFiredTriggerClasses();
1222     if (firedtrclasses.Contains(fTriggerType))
1223     {
1224       event=i;
1225       return kTRUE;
1226     }
1227   }
1228   return kFALSE;
1229 }
1230
1231 Bool_t AliEveEventManager::FindPrevByTrigger(Int_t& event)
1232 {
1233   // Find previous event that matches the trigger.
1234
1235   static const TEveException kEH("AliEveEventManager::FindPrevByTrigger ");
1236
1237   if (!fESDTree) return kFALSE;
1238   TString firedtrclasses;
1239   for (Int_t i = fEventId-1; i>=0; i--)
1240   {
1241     if (fESDTree->GetEntry(i) <= 0)
1242       throw (kEH + "failed getting required event from ESD.");
1243     firedtrclasses = fESD->GetFiredTriggerClasses();
1244     if (firedtrclasses.Contains(fTriggerType))
1245     {
1246       event=i;
1247       return kTRUE;
1248     }
1249   }
1250   for (Int_t i = GetMaxEventId(kTRUE); i>fEventId-1; i--)
1251   {
1252     if (fESDTree->GetEntry(i) <= 0)
1253       throw (kEH + "failed getting required event from ESD.");
1254     firedtrclasses = fESD->GetFiredTriggerClasses();
1255     if (firedtrclasses.Contains(fTriggerType))
1256     {
1257       event=i;
1258       return kTRUE;
1259     }
1260   }
1261   return kFALSE;
1262 }
1263
1264
1265 //------------------------------------------------------------------------------
1266 // Post event-loading functions
1267 //------------------------------------------------------------------------------
1268
1269 void AliEveEventManager::AfterNewEventLoaded()
1270 {
1271   // Execute registered macros and commands.
1272   // At the end emit NewEventLoaded signal.
1273   //
1274   // Virtual from TEveEventManager.
1275
1276   static const TEveException kEH("AliEveEventManager::AfterNewEventLoaded ");
1277
1278   if (fExecutor)
1279     fExecutor->ExecMacros();
1280
1281   TEveEventManager::AfterNewEventLoaded();
1282
1283   NewEventLoaded();
1284
1285   if (this == fgMaster && fSubManagers != 0)
1286   {
1287     TIter next(fSubManagers);
1288     while ((fgCurrent = dynamic_cast<AliEveEventManager*>(next())) != 0)
1289     {
1290       gEve->SetCurrentEvent(fgCurrent);
1291       try
1292       {
1293         fgCurrent->GotoEvent(fEventId);
1294       }
1295       catch (TEveException& exc)
1296       {
1297         // !!! Should somehow tag / disable / remove it?
1298         Error(kEH, "Getting event %d for sub-event-manager '%s' failed: '%s'.",
1299               fEventId, fgCurrent->GetName(), exc.Data());
1300       }
1301     }
1302     fgCurrent = fgMaster;
1303     gEve->SetCurrentEvent(fgMaster);
1304   }
1305 }
1306
1307 void AliEveEventManager::NewEventLoaded()
1308 {
1309   // Emit NewEventLoaded signal.
1310
1311   Emit("NewEventLoaded()");
1312 }
1313
1314
1315 //------------------------------------------------------------------------------
1316 // Event info dumpers
1317 //------------------------------------------------------------------------------
1318
1319 TString AliEveEventManager::GetEventInfoHorizontal() const
1320 {
1321   // Dumps the event-header contents in vertical formatting.
1322
1323   TString rawInfo, esdInfo;
1324
1325   if (!fRawReader)
1326   {
1327     rawInfo = "No raw-data event info is available!\n";
1328   }
1329   else
1330   {
1331     const UInt_t* attr = fRawReader->GetAttributes();
1332     TTimeStamp ts(fRawReader->GetTimestamp());
1333     rawInfo.Form("RAW event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1334                  "Trigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x  Timestamp: %s\n",
1335                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1336                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1337                  fRawReader->GetClassMask(),
1338                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1339                  attr[0],attr[1],attr[2], ts.AsString("s"));
1340   }
1341
1342   if (!fESD)
1343   {
1344     esdInfo = "No ESD event info is available!";
1345   }
1346   else
1347   {
1348     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1349     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1350     TTimeStamp ts(fESD->GetTimeStamp());
1351     esdInfo.Form("ESD event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1352                  "Active trigger classes: %s\nTrigger: %llx (%s)\nEvent# in file: %d  Timestamp: %s, MagField: %.2e",
1353                  fESD->GetRunNumber(),
1354                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1355                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1356                  acttrclasses.Data(),
1357                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1358                  fESD->GetEventNumberInFile(), ts.AsString("s"), fESD->GetMagneticField());
1359   }
1360
1361   return rawInfo + esdInfo;
1362 }
1363
1364 TString AliEveEventManager::GetEventInfoVertical() const
1365 {
1366   // Dumps the event-header contents in vertical formatting.
1367
1368   TString rawInfo, esdInfo;
1369
1370   if (!fRawReader)
1371   {
1372     rawInfo = "No raw-data event info is available!\n";
1373   }
1374   else
1375   {
1376     const UInt_t* attr = fRawReader->GetAttributes();
1377     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",
1378                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1379                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1380                  fRawReader->GetClassMask(),
1381                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1382                  attr[0],attr[1],attr[2],
1383                  fRawReader->GetTimestamp());
1384   }
1385
1386   if (!fESD)
1387   {
1388     esdInfo = "No ESD event info is available!\n";
1389   }
1390   else
1391   {
1392     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1393     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1394     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",
1395                  fESD->GetRunNumber(),
1396                  acttrclasses.Data(),
1397                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1398                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1399                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1400                  fESD->GetEventNumberInFile(),
1401                  fESD->GetTimeStamp());
1402   }
1403
1404   return rawInfo + "\n" + esdInfo;
1405 }
1406
1407
1408 //==============================================================================
1409 // Reading of GRP and MagneticField.
1410 // This is a reap-off from reconstruction ... should really be a common
1411 // code to do this somewhere in STEER.
1412 //==============================================================================
1413
1414 Bool_t AliEveEventManager::InitGRP()
1415 {
1416   //------------------------------------
1417   // Initialization of the GRP entry 
1418   //------------------------------------
1419
1420   static const TEveException kEH("AliEveEventManager::InitGRP ");
1421
1422   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
1423
1424   if (entry)
1425   {
1426     TMap* m = dynamic_cast<TMap*>(entry->GetObject());  // old GRP entry
1427
1428     if (m)
1429     {
1430       ::Info(kEH, "Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
1431       fgGRPData = new AliGRPObject();
1432       fgGRPData->ReadValuesFromMap(m);
1433     }
1434     else
1435     {
1436       ::Info(kEH, "Found an AliGRPObject in GRP/GRP/Data, reading it");
1437       fgGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
1438       entry->SetOwner(0);
1439     }
1440
1441     AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1442   }
1443
1444   if (!fgGRPData)
1445   {
1446     ::Error(kEH, "No GRP entry found in OCDB!");
1447     return kFALSE;
1448   }
1449
1450   TString lhcState = fgGRPData->GetLHCState();
1451   if (lhcState==AliGRPObject::GetInvalidString())
1452   {
1453     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the LHC state ! Using UNKNOWN");
1454     lhcState = "UNKNOWN";
1455   }
1456
1457   TString beamType = fgGRPData->GetBeamType();
1458   if (beamType==AliGRPObject::GetInvalidString())
1459   {
1460     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
1461     beamType = "UNKNOWN";
1462   }
1463
1464   Float_t beamEnergy = fgGRPData->GetBeamEnergy();
1465   if (beamEnergy==AliGRPObject::GetInvalidFloat())
1466   {
1467     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the beam energy ! Using 0");
1468     beamEnergy = 0;
1469   }
1470   beamEnergy /= 120E3; // energy is provided in MeV*120
1471
1472   TString runType = fgGRPData->GetRunType();
1473   if (runType==AliGRPObject::GetInvalidString())
1474   {
1475     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the run type ! Using UNKNOWN");
1476     runType = "UNKNOWN";
1477   }
1478
1479   Int_t activeDetectors = fgGRPData->GetDetectorMask();
1480   if (activeDetectors==AliGRPObject::GetInvalidUInt())
1481   {
1482     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
1483     activeDetectors = 1074790399;
1484   }
1485
1486
1487   // Might become useful.
1488   /*
1489     fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1490     printf("AliRunInfo - %s %s %f %s %d\n", lhcState.Data(), beamType.Data(), beamEnergy, runType.Data(), activeDetectors);
1491     fRunInfo->Dump();
1492
1493
1494     // Process the list of active detectors
1495     if (activeDetectors) {
1496     UInt_t detMask = activeDetectors;
1497     fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
1498     fRunTracking = MatchDetectorList(fRunTracking,detMask);
1499     fFillESD = MatchDetectorList(fFillESD,detMask);
1500     fQADetectors = MatchDetectorList(fQADetectors,detMask);
1501     fLoadCDB.Form("%s %s %s %s",
1502     fRunLocalReconstruction.Data(),
1503     fRunTracking.Data(),
1504     fFillESD.Data(),
1505     fQADetectors.Data());
1506     fLoadCDB = MatchDetectorList(fLoadCDB,detMask);
1507     if (!((detMask >> AliDAQ::DetectorID("ITSSPD")) & 0x1)) {
1508     // switch off the vertexer
1509     ::Info(kEH, "SPD is not in the list of active detectors. Vertexer switched off.");
1510     fRunVertexFinder = kFALSE;
1511     }
1512     if (!((detMask >> AliDAQ::DetectorID("TRG")) & 0x1)) {
1513     // switch off the reading of CTP raw-data payload
1514     if (fFillTriggerESD) {
1515     ::Info(kEH, "CTP is not in the list of active detectors. CTP data reading switched off.");
1516     fFillTriggerESD = kFALSE;
1517     }
1518     }
1519     }
1520
1521     ::Info(kEH, "===================================================================================");
1522     ::Info(kEH, "Running local reconstruction for detectors: %s",fRunLocalReconstruction.Data());
1523     ::Info(kEH, "Running tracking for detectors: %s",fRunTracking.Data());
1524     ::Info(kEH, "Filling ESD for detectors: %s",fFillESD.Data());
1525     ::Info(kEH, "Quality assurance is active for detectors: %s",fQADetectors.Data());
1526     ::Info(kEH, "CDB and reconstruction parameters are loaded for detectors: %s",fLoadCDB.Data());
1527     ::Info(kEH, "===================================================================================");
1528   */
1529
1530   //*** Dealing with the magnetic field map
1531   if (TGeoGlobalMagField::Instance()->IsLocked())
1532   {
1533     ::Info(kEH, "Running with externally locked B field!");
1534   }
1535   else
1536   {
1537     // Construct the field map out of the information retrieved from GRP.
1538
1539     Float_t l3Current = fgGRPData->GetL3Current((AliGRPObject::Stats)0);
1540     if (l3Current == AliGRPObject::GetInvalidFloat())
1541       throw kEH + "GRPData entry: missing value for the L3 current!";
1542     
1543     Char_t l3Polarity = fgGRPData->GetL3Polarity();
1544     if (l3Polarity == AliGRPObject::GetInvalidChar())
1545       throw kEH + "GRPData entry: missing value for the L3 polarity!";
1546
1547     Float_t diCurrent = fgGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1548     if (diCurrent == AliGRPObject::GetInvalidFloat())
1549       throw kEH + "GRPData entry: missing value for the dipole current!";
1550
1551     Char_t diPolarity = fgGRPData->GetDipolePolarity();
1552     if (diPolarity == AliGRPObject::GetInvalidChar()) 
1553       throw kEH + "GRPData entry: missing value for the dipole polarity!";
1554
1555     if (!SetFieldMap(l3Current, diCurrent, l3Polarity ? -1:1, diPolarity ? -1:1))
1556       throw kEH + "Failed to create B field map!";
1557
1558     ::Info(kEH, "Running with the B field constructed from GRP.");
1559   }
1560   
1561   //*** Get the diamond profiles from OCDB
1562   // Eventually useful.
1563
1564   /*
1565     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1566     if (entry) {
1567     fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1568     } else {
1569     ::Error(kEH, "No SPD diamond profile found in OCDB!");
1570     }
1571
1572     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1573     if (entry) {
1574     fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1575     } else {
1576     ::Error(kEH, "No diamond profile found in OCDB!");
1577     }
1578
1579     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1580     if (entry) {
1581     fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1582     } else {
1583     ::Error(kEH, "No TPC diamond profile found in OCDB!");
1584     }
1585   */
1586
1587   return kTRUE;
1588
1589
1590 Bool_t AliEveEventManager::SetFieldMap(Float_t l3Cur, Float_t diCur,
1591                                        Float_t l3Pol, Float_t diPol,
1592                                        Float_t beamenergy,
1593                                        const Char_t *beamtype,
1594                                        const Char_t *path) 
1595 {
1596   //------------------------------------------------
1597   // The magnetic field map, defined externally...
1598   // L3 current 30000 A  -> 0.5 T
1599   // L3 current 12000 A  -> 0.2 T
1600   // dipole current 6000 A
1601   // The polarities must be the same
1602   //------------------------------------------------
1603
1604   static const TEveException kEH("AliEveEventManager::SetFieldMap ");
1605
1606   const Float_t l3NominalCurrent1 = 30000.0; // (A)
1607   const Float_t l3NominalCurrent2 = 12000.0; // (A)
1608   const Float_t diNominalCurrent  = 6000.0;  // (A)
1609
1610   const Float_t tolerance = 0.03; // relative current tolerance
1611   const Float_t zero      = 77.0; // "zero" current (A)
1612
1613   TString s = (l3Pol < 0) ? "L3: -" : "L3: +";
1614
1615   AliMagF::BMap_t map = AliMagF::k5kG;
1616
1617   double fcL3, fcDip;
1618
1619   l3Cur = TMath::Abs(l3Cur);
1620   if (TMath::Abs(l3Cur-l3NominalCurrent1)/l3NominalCurrent1 < tolerance)
1621   {
1622     fcL3 = l3Cur/l3NominalCurrent1;
1623     map  = AliMagF::k5kG;
1624     s   += "0.5 T;  ";
1625   }
1626   else if (TMath::Abs(l3Cur-l3NominalCurrent2)/l3NominalCurrent2 < tolerance)
1627   {
1628     fcL3 = l3Cur/l3NominalCurrent2;
1629     map  = AliMagF::k2kG;
1630     s   += "0.2 T;  ";
1631   }
1632   else if (l3Cur <= zero)
1633   {
1634     fcL3 = 0;
1635     map  = AliMagF::k5kGUniform;
1636     s   += "0.0 T;  ";
1637     fgUniformField = kTRUE; // track with the uniform (zero) B field
1638   }
1639   else
1640   {
1641     ::Error(kEH, "Wrong L3 current (%f A)!", l3Cur);
1642     return kFALSE;
1643   }
1644
1645   diCur = TMath::Abs(diCur);
1646   if (TMath::Abs(diCur-diNominalCurrent)/diNominalCurrent < tolerance)
1647   {
1648     // 3% current tolerance...
1649     fcDip = diCur/diNominalCurrent;
1650     s    += "Dipole ON";
1651   }
1652   else if (diCur <= zero)
1653   { // some small current..
1654     fcDip = 0.;
1655     s    += "Dipole OFF";
1656   }
1657   else
1658   {
1659     ::Error(kEH, "Wrong dipole current (%f A)!", diCur);
1660     return kFALSE;
1661   }
1662
1663   if (l3Pol != diPol && (map==AliMagF::k5kG || map==AliMagF::k2kG) && fcDip != 0)
1664   {
1665     ::Error(kEH, "L3 and Dipole polarities must be the same");
1666     return kFALSE;
1667   }
1668
1669   if (l3Pol<0) fcL3  = -fcL3;
1670   if (diPol<0) fcDip = -fcDip;
1671
1672   AliMagF::BeamType_t btype = AliMagF::kNoBeamField;
1673   TString btypestr = beamtype;
1674   btypestr.ToLower();
1675
1676   TPRegexp protonBeam("(proton|p)\\s*-?\\s*\\1");
1677   TPRegexp ionBeam   ("(lead|pb|ion|a)\\s*-?\\s*\\1");
1678
1679   if (btypestr.Contains(ionBeam))
1680     btype = AliMagF::kBeamTypeAA;
1681   else if (btypestr.Contains(protonBeam))
1682     btype = AliMagF::kBeamTypepp;
1683   else
1684     ::Info(kEH, "Cannot determine the beam type from %s, assume no LHC magnet field",
1685            beamtype);
1686
1687   AliMagF* fld = new AliMagF("MagneticFieldMap", s.Data(), 2, fcL3, fcDip, 10., map, path, 
1688                              btype,beamenergy);
1689   TGeoGlobalMagField::Instance()->SetField(fld);
1690   TGeoGlobalMagField::Instance()->Lock();
1691
1692   return kTRUE;
1693 }