From Mikolaj: Implementation of event / trigger selection mechanism
[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     //else 
793     //  GotoEvent(fEventId + 1);
794   }
795 }
796
797 void AliEveEventManager::PrevEvent()
798 {
799   // Loads previous event.
800
801   static const TEveException kEH("AliEveEventManager::PrevEvent ");
802
803   if (fAutoLoadTimerRunning)
804   {
805     throw (kEH + "Event auto-load timer is running.");
806   }
807   if (fExternalCtrl)
808   {
809     throw (kEH + "Event-loop is under external control.");
810   }
811   Int_t nextevent=0;
812   if (fPEventSelector->FindPrev(nextevent))
813   {
814     GotoEvent(nextevent);
815   }
816   //else
817   //  GotoEvent(fEventId - 1);
818 }
819
820 void AliEveEventManager::Close()
821 {
822   // Close the event data-files and delete ESD, ESDfriend, run-loader
823   // and raw-reader.
824
825   static const TEveException kEH("AliEveEventManager::Close ");
826
827   if (!fIsOpen)
828   {
829     throw (kEH + "Event-files not opened.");
830   }
831
832   if (fAutoLoadTimerRunning)
833     StopAutoLoadTimer();
834
835   if (fESDTree) {
836     delete fESD;       fESD       = 0;
837     delete fESDfriend; fESDfriend = 0;
838     fESDfriendExists = kFALSE;
839
840     delete fESDTree;   fESDTree = 0;
841     delete fESDFile;   fESDFile = 0;
842   }
843
844   if (fAODTree) {
845     delete fAOD;       fAOD       = 0;
846
847     delete fAODTree;   fAODTree = 0;
848     delete fAODFile;   fAODFile = 0;
849   }
850
851   if (fRunLoader) {
852     delete fRunLoader; fRunLoader = 0;
853   }
854
855   if (fRawReader) {
856     delete fRawReader; fRawReader = 0;
857   }
858
859   fEventId  = -1;
860   fIsOpen   = kFALSE;
861   fHasEvent = kFALSE;
862 }
863
864
865 //------------------------------------------------------------------------------
866 // Static convenience functions, mainly used from macros.
867 //------------------------------------------------------------------------------
868
869 Bool_t AliEveEventManager::HasRunLoader()
870 {
871   // Check if AliRunLoader is initialized.
872
873   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRunLoader;
874 }
875
876 Bool_t AliEveEventManager::HasESD()
877 {
878   // Check if AliESDEvent is initialized.
879
880   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESD;
881 }
882
883 Bool_t AliEveEventManager::HasESDfriend()
884 {
885   // Check if AliESDfriend is initialized.
886
887   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fESDfriend;
888 }
889
890 Bool_t AliEveEventManager::HasAOD()
891 {
892   // Check if AliESDEvent is initialized.
893
894   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fAOD;
895 }
896
897 Bool_t AliEveEventManager::HasRawReader()
898 {
899   // Check if raw-reader is initialized.
900
901   return fgCurrent && fgCurrent->fHasEvent && fgCurrent->fRawReader;
902 }
903
904 AliRunLoader* AliEveEventManager::AssertRunLoader()
905 {
906   // Make sure AliRunLoader is initialized and return it.
907   // Throws exception in case run-loader is not available.
908   // Static utility for macros.
909
910   static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
911
912   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
913     throw (kEH + "ALICE event not ready.");
914   if (fgCurrent->fRunLoader == 0)
915     throw (kEH + "AliRunLoader not initialised.");
916   return fgCurrent->fRunLoader;
917 }
918
919 AliESDEvent* AliEveEventManager::AssertESD()
920 {
921   // Make sure AliESDEvent is initialized and return it.
922   // Throws exception in case ESD is not available.
923   // Static utility for macros.
924
925   static const TEveException kEH("AliEveEventManager::AssertESD ");
926
927   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
928     throw (kEH + "ALICE event not ready.");
929   if (fgCurrent->fESD == 0)
930     throw (kEH + "AliESD not initialised.");
931   return fgCurrent->fESD;
932 }
933
934 AliESDfriend* AliEveEventManager::AssertESDfriend()
935 {
936   // Make sure AliESDfriend is initialized and return it.
937   // Throws exception in case ESDfriend-loader is not available.
938   // Static utility for macros.
939
940   static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
941
942   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
943     throw (kEH + "ALICE event not ready.");
944   if (fgCurrent->fESDfriend == 0)
945     throw (kEH + "AliESDfriend not initialised.");
946   return fgCurrent->fESDfriend;
947 }
948
949 AliAODEvent* AliEveEventManager::AssertAOD()
950 {
951   // Make sure AliAODEvent is initialized and return it.
952   // Throws exception in case AOD is not available.
953   // Static utility for macros.
954
955   static const TEveException kEH("AliEveEventManager::AssertAOD ");
956
957   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
958     throw (kEH + "ALICE event not ready.");
959   if (fgCurrent->fAOD == 0)
960     throw (kEH + "AliAOD not initialised.");
961   return fgCurrent->fAOD;
962 }
963
964 AliRawReader* AliEveEventManager::AssertRawReader()
965 {
966   // Make sure raw-reader is initialized and return it.
967
968   static const TEveException kEH("AliEveEventManager::AssertRawReader ");
969
970   if (fgCurrent == 0 || fgCurrent->fHasEvent == kFALSE)
971     throw (kEH + "ALICE event not ready.");
972   if (fgCurrent->fRawReader == 0)
973     throw (kEH + "RawReader not ready.");
974
975   return fgCurrent->fRawReader;
976 }
977
978 //==============================================================================
979
980 AliMagF* AliEveEventManager::AssertMagField()    
981 {        
982   // Make sure AliMagF is initialized and returns it.    
983   // Throws exception in case magnetic field is not available.   
984   // Static utility for macros.          
985
986   static const TEveException kEH("AliEveEventManager::AssertMagField ");         
987                  
988   if (fgMagField)
989     return fgMagField;
990
991   if (fgGRPData == 0)
992   {
993     InitGRP();
994   }
995
996   if (TGeoGlobalMagField::Instance())
997   {
998     fgMagField = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField());
999     if (fgMagField == 0)
1000       throw kEH + "Global field set, but it is not AliMagF.";
1001   }
1002   else
1003   {
1004     throw kEH + "Could not initialize magnetic field.";
1005   }
1006
1007   return fgMagField;     
1008 }
1009
1010 TGeoManager* AliEveEventManager::AssertGeometry()
1011 {
1012   // Make sure AliGeomManager is initialized and returns the
1013   // corresponding TGeoManger.
1014   // gGeoManager is set to the return value.
1015   // Throws exception if geometry can not be loaded or if it is not
1016   // available and the TGeoManager is locked.
1017   // Static utility for macros.
1018
1019   static const TEveException kEH("AliEveEventManager::AssertGeometry ");
1020
1021   if (AliGeomManager::GetGeometry() == 0)
1022   {
1023     if (TGeoManager::IsLocked())
1024       throw (kEH + "geometry is not loaded but TGeoManager is locked.");
1025
1026     gGeoManager = 0;
1027     AliGeomManager::LoadGeometry();
1028     if ( ! AliGeomManager::GetGeometry())
1029     {
1030       throw (kEH + "can not load geometry.");
1031     }
1032     if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
1033     {
1034       ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
1035       // throw (kEH + "could not apply align objs.");
1036     }
1037     AliGeomManager::GetGeometry()->DefaultColors();
1038   }
1039
1040   gGeoManager = AliGeomManager::GetGeometry();
1041   return gGeoManager;
1042 }
1043
1044 //------------------------------------------------------------------------------
1045
1046 AliEveEventManager* AliEveEventManager::AddDependentManager(const TString& name, const TString& path)
1047 {
1048   // Create and attach a dependent event-manager.
1049   // It is not added into eve list tree.
1050
1051   static const TEveException kEH("AliEveEventManager::AddDependentManager ");
1052
1053   if (fgMaster == 0)
1054     throw(kEH + "Master event-manager must be instantiated first.");
1055
1056   if (fgMaster->fSubManagers == 0)
1057   {
1058     fgMaster->fSubManagers = new TList;
1059     fgMaster->fSubManagers->SetOwner(kTRUE);
1060   }
1061
1062   AliEveEventManager* new_mgr = 0;
1063   fgCurrent = 0;
1064   try
1065   {
1066     new_mgr = new AliEveEventManager(name, path, fgMaster->fEventId);
1067     fgMaster->fSubManagers->Add(new_mgr);
1068   }
1069   catch (TEveException& exc)
1070   {
1071     ::Error(kEH, "Creation of new event-manager failed: '%s'.", exc.Data());
1072   }
1073   fgCurrent = fgMaster;
1074
1075   return new_mgr;
1076 }
1077
1078 AliEveEventManager* AliEveEventManager::GetDependentManager(const TString& name)
1079 {
1080   // Get a dependant manager by name.
1081   // This will not change the current manager, use helper class
1082   // AliEveEventManager::CurrentChanger for that.
1083
1084   static const TEveException kEH("AliEveEventManager::GetDependentManager ");
1085
1086   if (fgMaster == 0)
1087     throw(kEH + "Master event-manager must be instantiated first.");
1088
1089   if (fgMaster->fSubManagers == 0)
1090     return 0;
1091
1092   return dynamic_cast<AliEveEventManager*>(fgMaster->fSubManagers->FindObject(name));
1093 }
1094
1095 AliEveEventManager* AliEveEventManager::GetMaster()
1096 {
1097   // Get master event-manager.
1098
1099   return fgMaster;
1100 }
1101
1102 AliEveEventManager* AliEveEventManager::GetCurrent()
1103 {
1104   // Get current event-manager.
1105
1106   return fgCurrent;
1107 }
1108
1109 void AliEveEventManager::RegisterTransient(TEveElement* element)
1110 {
1111   GetCurrent()->fTransients->AddElement(element);
1112 }
1113
1114 void AliEveEventManager::RegisterTransientList(TEveElement* element)
1115 {
1116   GetCurrent()->fTransientLists->AddElement(element);
1117 }
1118
1119 //------------------------------------------------------------------------------
1120 // Autoloading of events
1121 //------------------------------------------------------------------------------
1122
1123 void AliEveEventManager::SetAutoLoadTime(Float_t time)
1124 {
1125   // Set the auto-load time in seconds
1126
1127   fAutoLoadTime = time;
1128 }
1129
1130 void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
1131 {
1132   // Set the automatic event loading mode
1133
1134   static const TEveException kEH("AliEveEventManager::SetAutoLoad ");
1135
1136   if (fAutoLoad == autoLoad)
1137   {
1138     Warning(kEH, "Setting autoload to the same value as before - %s. Ignoring.", fAutoLoad ? "true" : "false");
1139     return;
1140   }
1141
1142   fAutoLoad = autoLoad;
1143   if (fAutoLoad)
1144   {
1145     StartAutoLoadTimer();
1146   }
1147   else
1148   {
1149     StopAutoLoadTimer();
1150   }
1151 }
1152
1153 void AliEveEventManager::StartAutoLoadTimer()
1154 {
1155   // Start the auto-load timer.
1156
1157   fAutoLoadTimer->SetTime((Long_t)(1000*fAutoLoadTime));
1158   fAutoLoadTimer->Reset();
1159   fAutoLoadTimer->TurnOn();
1160   fAutoLoadTimerRunning = kTRUE;
1161 }
1162
1163 void AliEveEventManager::StopAutoLoadTimer()
1164 {
1165   // Stop the auto-load timer.
1166
1167   fAutoLoadTimerRunning = kFALSE;
1168   fAutoLoadTimer->TurnOff();
1169 }
1170
1171 void AliEveEventManager::AutoLoadNextEvent()
1172 {
1173   // Called from auto-load timer, so it has to be public.
1174   // Do NOT call it directly.
1175
1176   static const TEveException kEH("AliEveEventManager::AutoLoadNextEvent ");
1177
1178   if ( ! fAutoLoadTimerRunning || ! fAutoLoadTimer->HasTimedOut())
1179   {
1180     Warning(kEH, "Called unexpectedly - ignoring the call. Should ONLY be called from an internal timer.");
1181     return;
1182   }
1183
1184   StopAutoLoadTimer();
1185   NextEvent();
1186   if (fAutoLoad && !fExternalCtrl)
1187     StartAutoLoadTimer();
1188 }
1189
1190 //------------------------------------------------------------------------------
1191 // Post event-loading functions
1192 //------------------------------------------------------------------------------
1193
1194 void AliEveEventManager::AfterNewEventLoaded()
1195 {
1196   // Execute registered macros and commands.
1197   // At the end emit NewEventLoaded signal.
1198   //
1199   // Virtual from TEveEventManager.
1200
1201   static const TEveException kEH("AliEveEventManager::AfterNewEventLoaded ");
1202
1203   if (fExecutor)
1204     fExecutor->ExecMacros();
1205
1206   TEveEventManager::AfterNewEventLoaded();
1207
1208   NewEventLoaded();
1209
1210   if (this == fgMaster && fSubManagers != 0)
1211   {
1212     TIter next(fSubManagers);
1213     while ((fgCurrent = dynamic_cast<AliEveEventManager*>(next())) != 0)
1214     {
1215       gEve->SetCurrentEvent(fgCurrent);
1216       try
1217       {
1218         fgCurrent->GotoEvent(fEventId);
1219       }
1220       catch (TEveException& exc)
1221       {
1222         // !!! Should somehow tag / disable / remove it?
1223         Error(kEH, "Getting event %d for sub-event-manager '%s' failed: '%s'.",
1224               fEventId, fgCurrent->GetName(), exc.Data());
1225       }
1226     }
1227     fgCurrent = fgMaster;
1228     gEve->SetCurrentEvent(fgMaster);
1229   }
1230 }
1231
1232 void AliEveEventManager::NewEventLoaded()
1233 {
1234   // Emit NewEventLoaded signal.
1235
1236   Emit("NewEventLoaded()");
1237 }
1238
1239
1240 //------------------------------------------------------------------------------
1241 // Event info dumpers
1242 //------------------------------------------------------------------------------
1243
1244 TString AliEveEventManager::GetEventInfoHorizontal() const
1245 {
1246   // Dumps the event-header contents in vertical formatting.
1247
1248   TString rawInfo, esdInfo;
1249
1250   if (!fRawReader)
1251   {
1252     rawInfo = "No raw-data event info is available!\n";
1253   }
1254   else
1255   {
1256     const UInt_t* attr = fRawReader->GetAttributes();
1257     TTimeStamp ts(fRawReader->GetTimestamp());
1258     rawInfo.Form("RAW event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1259                  "Trigger: %llx\nDetectors: %x (%s)\nAttributes:%x-%x-%x  Timestamp: %s\n",
1260                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1261                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1262                  fRawReader->GetClassMask(),
1263                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1264                  attr[0],attr[1],attr[2], ts.AsString("s"));
1265   }
1266
1267   if (!fESD)
1268   {
1269     esdInfo = "No ESD event info is available!";
1270   }
1271   else
1272   {
1273     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1274     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1275     TTimeStamp ts(fESD->GetTimeStamp());
1276     esdInfo.Form("ESD event info: Run#: %d  Event type: %d (%s)  Period: %x  Orbit: %x  BC: %x\n"
1277                  "Active trigger classes: %s\nTrigger: %llx (%s)\nEvent# in file: %d  Timestamp: %s, MagField: %.2e",
1278                  fESD->GetRunNumber(),
1279                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1280                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1281                  acttrclasses.Data(),
1282                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1283                  fESD->GetEventNumberInFile(), ts.AsString("s"), fESD->GetMagneticField());
1284   }
1285
1286   return rawInfo + esdInfo;
1287 }
1288
1289 TString AliEveEventManager::GetEventInfoVertical() const
1290 {
1291   // Dumps the event-header contents in vertical formatting.
1292
1293   TString rawInfo, esdInfo;
1294
1295   if (!fRawReader)
1296   {
1297     rawInfo = "No raw-data event info is available!\n";
1298   }
1299   else
1300   {
1301     const UInt_t* attr = fRawReader->GetAttributes();
1302     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",
1303                  fRawReader->GetRunNumber(),fRawReader->GetType(),AliRawEventHeaderBase::GetTypeName(fRawReader->GetType()),
1304                  fRawReader->GetPeriod(),fRawReader->GetOrbitID(),fRawReader->GetBCID(),
1305                  fRawReader->GetClassMask(),
1306                  *fRawReader->GetDetectorPattern(),AliDAQ::ListOfTriggeredDetectors(*fRawReader->GetDetectorPattern()),
1307                  attr[0],attr[1],attr[2],
1308                  fRawReader->GetTimestamp());
1309   }
1310
1311   if (!fESD)
1312   {
1313     esdInfo = "No ESD event info is available!\n";
1314   }
1315   else
1316   {
1317     TString acttrclasses   = fESD->GetESDRun()->GetActiveTriggerClasses();
1318     TString firedtrclasses = fESD->GetFiredTriggerClasses();
1319     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",
1320                  fESD->GetRunNumber(),
1321                  acttrclasses.Data(),
1322                  fESD->GetEventType(),AliRawEventHeaderBase::GetTypeName(fESD->GetEventType()),
1323                  fESD->GetPeriodNumber(),fESD->GetOrbitNumber(),fESD->GetBunchCrossNumber(),
1324                  fESD->GetTriggerMask(),firedtrclasses.Data(),
1325                  fESD->GetEventNumberInFile(),
1326                  fESD->GetTimeStamp());
1327   }
1328
1329   return rawInfo + "\n" + esdInfo;
1330 }
1331
1332
1333 //==============================================================================
1334 // Reading of GRP and MagneticField.
1335 // This is a reap-off from reconstruction ... should really be a common
1336 // code to do this somewhere in STEER.
1337 //==============================================================================
1338
1339 Bool_t AliEveEventManager::InitGRP()
1340 {
1341   //------------------------------------
1342   // Initialization of the GRP entry 
1343   //------------------------------------
1344
1345   static const TEveException kEH("AliEveEventManager::InitGRP ");
1346
1347   AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
1348
1349   if (entry)
1350   {
1351     TMap* m = dynamic_cast<TMap*>(entry->GetObject());  // old GRP entry
1352
1353     if (m)
1354     {
1355       ::Info(kEH, "Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
1356       fgGRPData = new AliGRPObject();
1357       fgGRPData->ReadValuesFromMap(m);
1358     }
1359     else
1360     {
1361       ::Info(kEH, "Found an AliGRPObject in GRP/GRP/Data, reading it");
1362       fgGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
1363       entry->SetOwner(0);
1364     }
1365
1366     AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
1367   }
1368
1369   if (!fgGRPData)
1370   {
1371     ::Error(kEH, "No GRP entry found in OCDB!");
1372     return kFALSE;
1373   }
1374
1375   TString lhcState = fgGRPData->GetLHCState();
1376   if (lhcState==AliGRPObject::GetInvalidString())
1377   {
1378     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the LHC state ! Using UNKNOWN");
1379     lhcState = "UNKNOWN";
1380   }
1381
1382   TString beamType = fgGRPData->GetBeamType();
1383   if (beamType==AliGRPObject::GetInvalidString())
1384   {
1385     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
1386     beamType = "UNKNOWN";
1387   }
1388
1389   Float_t beamEnergy = fgGRPData->GetBeamEnergy();
1390   if (beamEnergy==AliGRPObject::GetInvalidFloat())
1391   {
1392     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the beam energy ! Using 0");
1393     beamEnergy = 0;
1394   }
1395   beamEnergy /= 120E3; // energy is provided in MeV*120
1396
1397   TString runType = fgGRPData->GetRunType();
1398   if (runType==AliGRPObject::GetInvalidString())
1399   {
1400     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the run type ! Using UNKNOWN");
1401     runType = "UNKNOWN";
1402   }
1403
1404   Int_t activeDetectors = fgGRPData->GetDetectorMask();
1405   if (activeDetectors==AliGRPObject::GetInvalidUInt())
1406   {
1407     ::Error(kEH, "GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
1408     activeDetectors = 1074790399;
1409   }
1410
1411
1412   // Might become useful.
1413   /*
1414     fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
1415     printf("AliRunInfo - %s %s %f %s %d\n", lhcState.Data(), beamType.Data(), beamEnergy, runType.Data(), activeDetectors);
1416     fRunInfo->Dump();
1417
1418
1419     // Process the list of active detectors
1420     if (activeDetectors) {
1421     UInt_t detMask = activeDetectors;
1422     fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
1423     fRunTracking = MatchDetectorList(fRunTracking,detMask);
1424     fFillESD = MatchDetectorList(fFillESD,detMask);
1425     fQADetectors = MatchDetectorList(fQADetectors,detMask);
1426     fLoadCDB.Form("%s %s %s %s",
1427     fRunLocalReconstruction.Data(),
1428     fRunTracking.Data(),
1429     fFillESD.Data(),
1430     fQADetectors.Data());
1431     fLoadCDB = MatchDetectorList(fLoadCDB,detMask);
1432     if (!((detMask >> AliDAQ::DetectorID("ITSSPD")) & 0x1)) {
1433     // switch off the vertexer
1434     ::Info(kEH, "SPD is not in the list of active detectors. Vertexer switched off.");
1435     fRunVertexFinder = kFALSE;
1436     }
1437     if (!((detMask >> AliDAQ::DetectorID("TRG")) & 0x1)) {
1438     // switch off the reading of CTP raw-data payload
1439     if (fFillTriggerESD) {
1440     ::Info(kEH, "CTP is not in the list of active detectors. CTP data reading switched off.");
1441     fFillTriggerESD = kFALSE;
1442     }
1443     }
1444     }
1445
1446     ::Info(kEH, "===================================================================================");
1447     ::Info(kEH, "Running local reconstruction for detectors: %s",fRunLocalReconstruction.Data());
1448     ::Info(kEH, "Running tracking for detectors: %s",fRunTracking.Data());
1449     ::Info(kEH, "Filling ESD for detectors: %s",fFillESD.Data());
1450     ::Info(kEH, "Quality assurance is active for detectors: %s",fQADetectors.Data());
1451     ::Info(kEH, "CDB and reconstruction parameters are loaded for detectors: %s",fLoadCDB.Data());
1452     ::Info(kEH, "===================================================================================");
1453   */
1454
1455   //*** Dealing with the magnetic field map
1456   if (TGeoGlobalMagField::Instance()->IsLocked())
1457   {
1458     ::Info(kEH, "Running with externally locked B field!");
1459   }
1460   else
1461   {
1462     // Construct the field map out of the information retrieved from GRP.
1463
1464     Float_t l3Current = fgGRPData->GetL3Current((AliGRPObject::Stats)0);
1465     if (l3Current == AliGRPObject::GetInvalidFloat())
1466       throw kEH + "GRPData entry: missing value for the L3 current!";
1467     
1468     Char_t l3Polarity = fgGRPData->GetL3Polarity();
1469     if (l3Polarity == AliGRPObject::GetInvalidChar())
1470       throw kEH + "GRPData entry: missing value for the L3 polarity!";
1471
1472     Float_t diCurrent = fgGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
1473     if (diCurrent == AliGRPObject::GetInvalidFloat())
1474       throw kEH + "GRPData entry: missing value for the dipole current!";
1475
1476     Char_t diPolarity = fgGRPData->GetDipolePolarity();
1477     if (diPolarity == AliGRPObject::GetInvalidChar()) 
1478       throw kEH + "GRPData entry: missing value for the dipole polarity!";
1479
1480     if (!SetFieldMap(l3Current, diCurrent, l3Polarity ? -1:1, diPolarity ? -1:1))
1481       throw kEH + "Failed to create B field map!";
1482
1483     ::Info(kEH, "Running with the B field constructed from GRP.");
1484   }
1485   
1486   //*** Get the diamond profiles from OCDB
1487   // Eventually useful.
1488
1489   /*
1490     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1491     if (entry) {
1492     fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1493     } else {
1494     ::Error(kEH, "No SPD diamond profile found in OCDB!");
1495     }
1496
1497     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1498     if (entry) {
1499     fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1500     } else {
1501     ::Error(kEH, "No diamond profile found in OCDB!");
1502     }
1503
1504     entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
1505     if (entry) {
1506     fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
1507     } else {
1508     ::Error(kEH, "No TPC diamond profile found in OCDB!");
1509     }
1510   */
1511
1512   return kTRUE;
1513
1514
1515 Bool_t AliEveEventManager::SetFieldMap(Float_t l3Cur, Float_t diCur,
1516                                        Float_t l3Pol, Float_t diPol,
1517                                        Float_t beamenergy,
1518                                        const Char_t *beamtype,
1519                                        const Char_t *path) 
1520 {
1521   //------------------------------------------------
1522   // The magnetic field map, defined externally...
1523   // L3 current 30000 A  -> 0.5 T
1524   // L3 current 12000 A  -> 0.2 T
1525   // dipole current 6000 A
1526   // The polarities must be the same
1527   //------------------------------------------------
1528
1529   static const TEveException kEH("AliEveEventManager::SetFieldMap ");
1530
1531   const Float_t l3NominalCurrent1 = 30000.0; // (A)
1532   const Float_t l3NominalCurrent2 = 12000.0; // (A)
1533   const Float_t diNominalCurrent  = 6000.0;  // (A)
1534
1535   const Float_t tolerance = 0.03; // relative current tolerance
1536   const Float_t zero      = 77.0; // "zero" current (A)
1537
1538   TString s = (l3Pol < 0) ? "L3: -" : "L3: +";
1539
1540   AliMagF::BMap_t map = AliMagF::k5kG;
1541
1542   double fcL3, fcDip;
1543
1544   l3Cur = TMath::Abs(l3Cur);
1545   if (TMath::Abs(l3Cur-l3NominalCurrent1)/l3NominalCurrent1 < tolerance)
1546   {
1547     fcL3 = l3Cur/l3NominalCurrent1;
1548     map  = AliMagF::k5kG;
1549     s   += "0.5 T;  ";
1550   }
1551   else if (TMath::Abs(l3Cur-l3NominalCurrent2)/l3NominalCurrent2 < tolerance)
1552   {
1553     fcL3 = l3Cur/l3NominalCurrent2;
1554     map  = AliMagF::k2kG;
1555     s   += "0.2 T;  ";
1556   }
1557   else if (l3Cur <= zero)
1558   {
1559     fcL3 = 0;
1560     map  = AliMagF::k5kGUniform;
1561     s   += "0.0 T;  ";
1562     fgUniformField = kTRUE; // track with the uniform (zero) B field
1563   }
1564   else
1565   {
1566     ::Error(kEH, "Wrong L3 current (%f A)!", l3Cur);
1567     return kFALSE;
1568   }
1569
1570   diCur = TMath::Abs(diCur);
1571   if (TMath::Abs(diCur-diNominalCurrent)/diNominalCurrent < tolerance)
1572   {
1573     // 3% current tolerance...
1574     fcDip = diCur/diNominalCurrent;
1575     s    += "Dipole ON";
1576   }
1577   else if (diCur <= zero)
1578   { // some small current..
1579     fcDip = 0.;
1580     s    += "Dipole OFF";
1581   }
1582   else
1583   {
1584     ::Error(kEH, "Wrong dipole current (%f A)!", diCur);
1585     return kFALSE;
1586   }
1587
1588   if (l3Pol != diPol && (map==AliMagF::k5kG || map==AliMagF::k2kG) && fcDip != 0)
1589   {
1590     ::Error(kEH, "L3 and Dipole polarities must be the same");
1591     return kFALSE;
1592   }
1593
1594   if (l3Pol<0) fcL3  = -fcL3;
1595   if (diPol<0) fcDip = -fcDip;
1596
1597   AliMagF::BeamType_t btype = AliMagF::kNoBeamField;
1598   TString btypestr = beamtype;
1599   btypestr.ToLower();
1600
1601   TPRegexp protonBeam("(proton|p)\\s*-?\\s*\\1");
1602   TPRegexp ionBeam   ("(lead|pb|ion|a)\\s*-?\\s*\\1");
1603
1604   if (btypestr.Contains(ionBeam))
1605     btype = AliMagF::kBeamTypeAA;
1606   else if (btypestr.Contains(protonBeam))
1607     btype = AliMagF::kBeamTypepp;
1608   else
1609     ::Info(kEH, "Cannot determine the beam type from %s, assume no LHC magnet field",
1610            beamtype);
1611
1612   AliMagF* fld = new AliMagF("MagneticFieldMap", s.Data(), 2, fcL3, fcDip, 10., map, path, 
1613                              btype,beamenergy);
1614   TGeoGlobalMagField::Instance()->SetField(fld);
1615   TGeoGlobalMagField::Instance()->Lock();
1616
1617   return kTRUE;
1618 }