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