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