AliEveEventManager
[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 <TEveManager.h>
12
13 #include <AliRunLoader.h>
14 #include <AliRun.h>
15 #include <AliESDEvent.h>
16 #include <AliESDfriend.h>
17 #include <AliRawReaderRoot.h>
18 #include <AliRawReaderFile.h>
19 #include <AliRawReaderDate.h>
20 #include <AliMagFMaps.h>
21 #include <AliCDBManager.h>
22 #include <AliHeader.h>
23 #include <AliGeomManager.h>
24
25 #include <TFile.h>
26 #include <TTree.h>
27 #include <TSystem.h>
28
29 //==============================================================================
30 //==============================================================================
31 // AliEveEventManager
32 //==============================================================================
33
34 //______________________________________________________________________________
35 //
36 // Provide interface for loading and navigating standard AliRoot data
37 // (AliRunLoader) and ESDs.
38 //
39 // Missing support for raw-data. For now this is handled individually
40 // by each sub-detector.
41 //
42 // Also provides interface to magnetic-field and geometry. Mostly
43 // intended as wrappers over standard AliRoot functionality for
44 // convenient use from visualizateion macros.
45
46 ClassImp(AliEveEventManager)
47
48 AliEveEventManager* gAliEveEvent = 0;
49
50 Bool_t AliEveEventManager::fgAssertRunLoader = kFALSE;
51 Bool_t AliEveEventManager::fgAssertESD       = kFALSE;
52 Bool_t AliEveEventManager::fgAssertRaw       = kFALSE;
53
54 TString  AliEveEventManager::fgESDFileName("AliESDs.root");
55 TString  AliEveEventManager::fgRawFileName("raw.root");
56 TString  AliEveEventManager::fgCdbUri("local://$ALICE_ROOT");
57
58 AliMagF* AliEveEventManager::fgMagField = 0;
59
60
61 AliEveEventManager::AliEveEventManager() :
62   TEveEventManager(),
63
64   fPath      ( ), fEventId (-1),
65   fRunLoader (0),
66   fESDFile   (0), fESDTree (0), fESD (0),
67   fESDfriend (0), fESDfriendExists(kFALSE),
68   fRawReader (0)
69 {
70   // Default constructor.
71 }
72
73 AliEveEventManager::AliEveEventManager(TString path, Int_t ev) :
74   TEveEventManager("AliEVE AliEveEventManager"),
75
76   fPath   (path), fEventId(-1),
77   fRunLoader (0),
78   fESDFile   (0), fESDTree (0), fESD (0),
79   fESDfriend (0), fESDfriendExists(kFALSE),
80   fRawReader (0)
81 {
82   // Constructor with event-directory URL and event-id.
83
84   Open();
85   if (ev >= 0) GotoEvent(ev);
86 }
87
88 AliEveEventManager::~AliEveEventManager()
89 {
90   // Destructor.
91
92   // Somewhat unclear what to do here.
93   // In principle should close all data sources and deregister from
94   // TEveManager.
95 }
96
97 /******************************************************************************/
98
99 void AliEveEventManager::SetESDFileName(const Text_t* esd)
100 {
101   // Set file-name for opening ESD, default "AliESDs.root".
102
103   if (esd) fgESDFileName = esd;
104 }
105
106 void AliEveEventManager::SetRawFileName(const Text_t* raw)
107 {
108   // Set file-name for opening of raw-data, default "raw.root"
109   if (raw) fgRawFileName = raw;
110 }
111
112 void AliEveEventManager::SetCdbUri(const Text_t* cdb)
113 {
114   // Set path to CDB, default "local://$ALICE_ROOT".
115
116   if (cdb) fgCdbUri = cdb;
117 }
118
119 void AliEveEventManager::SetAssertElements(Bool_t assertRunloader,
120                                            Bool_t assertEsd,
121                                            Bool_t assertRaw)
122 {
123   // Set global flags that detrmine which parts of the event-data must
124   // be present when the event is opened.
125
126   fgAssertRunLoader = assertRunloader;
127   fgAssertESD = assertEsd;
128   fgAssertRaw = assertRaw;
129 }
130
131 /******************************************************************************/
132
133 void AliEveEventManager::Open()
134 {
135   // Open event-data from URL specified in fPath.
136   // Attempts to create AliRunLoader() and to open ESD with ESDfriends.
137   // Warning is reported if run-loader or ESD is not found.
138   // Global data-members fgAssertRunLoader and fgAssertESD can be set
139   // to throw exceptions instead.
140
141   static const TEveException kEH("AliEveEventManager::Open ");
142
143   gSystem->ExpandPathName(fPath);
144   if (fPath[0] != '/')
145     fPath = Form("%s/%s", gSystem->WorkingDirectory(), fPath.Data());
146
147   Int_t runNo = -1;
148
149   TString gaPath(Form("%s/galice.root", fPath.Data()));
150   // If i use open directly, we get fatal.
151   // Is this (AccessPathName check) ok for xrootd / alien?
152   if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
153   {
154     fRunLoader = AliRunLoader::Open(gaPath);
155     if (fRunLoader)
156     {
157       TString alicePath = fPath + "/";
158       fRunLoader->SetDirName(alicePath);
159
160       if (fRunLoader->LoadgAlice() != 0)
161         Warning(kEH, "failed loading gAlice via run-loader.");
162
163       if (fRunLoader->LoadHeader() == 0)
164       {
165         runNo = fRunLoader->GetHeader()->GetRun();
166       }
167       else
168       {
169         Warning(kEH, "failed loading run-loader's header.");
170         delete fRunLoader;
171         fRunLoader = 0;
172       }
173     }
174     else // run-loader open failed
175     {
176       Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
177     }
178   }
179   else // galice not readable
180   {
181     Warning(kEH, "can not read '%s'.", gaPath.Data());
182   }
183   if (fRunLoader == 0)
184   {
185     if (fgAssertRunLoader)
186       throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
187     else
188       Warning(kEH, "Bootstraping of run-loader failed.");
189   }
190
191
192   TString esdPath(Form("%s/%s", fPath.Data(), fgESDFileName.Data()));
193   if ((fESDFile = TFile::Open(esdPath)))
194   {
195     fESD = new AliESDEvent();
196     fESDTree = (TTree*) fESDFile->Get("esdTree");
197     if (fESDTree != 0)
198     {
199       fESD->ReadFromTree(fESDTree);
200       runNo = fESD->GetESDRun()->GetRunNumber();
201
202       // Check if ESDfriends exists and attach the branch
203       TString p = Form("%s/AliESDfriends.root", fPath.Data());
204       if (gSystem->AccessPathName(p, kReadPermission) == kFALSE)
205       {
206         fESDfriendExists = kTRUE;
207         fESDTree->SetBranchStatus ("ESDfriend*", 1);
208         fESDTree->SetBranchAddress("ESDfriend.", &fESDfriend);
209       }
210     }
211     else // esdtree == 0
212     {
213       delete fESDFile; fESDFile = 0;
214       Warning(kEH, "failed getting the esdTree.");
215     }
216   }
217   else // esd not readable
218   {
219     Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
220   }
221   if (fESDTree == 0)
222   {
223     if (fgAssertESD)
224     {
225       throw (kEH + "ESD not initialized. Its precence was requested.");
226     } else {
227       Warning(kEH, "ESD not initialized.");
228     }
229   }
230
231   TString rawPath(Form("%s/%s", fPath.Data(), fgRawFileName.Data()));
232   // If i use open directly, raw-reader reports an error but i have
233   // no way to detect it.
234   // Is this (AccessPathName check) ok for xrootd / alien?
235   if (gSystem->AccessPathName(rawPath, kReadPermission) == kFALSE)
236   {
237     if (fgRawFileName.EndsWith("/"))
238     {
239       fRawReader = new AliRawReaderFile(rawPath);
240     }
241     else if (fgRawFileName.EndsWith(".root"))
242     {
243       fRawReader = new AliRawReaderRoot(rawPath);
244     }
245     else if (!fgRawFileName.IsNull())
246     {
247       fRawReader = new AliRawReaderDate(rawPath);
248     } 
249   }
250
251   if (fRawReader == 0)
252   {
253     if (fgAssertRaw)
254     {
255       throw (kEH + "raw-data not initialized. Its precence was requested.");
256     } else {
257       Warning(kEH, "raw-data not initialized.");
258     }
259   }
260
261   if (runNo < 0)
262   {
263     if (fRawReader)
264     {
265       fRawReader->NextEvent();
266       runNo = fRawReader->GetRunNumber();
267       printf("Determining run-no from raw ... run=%d\n", runNo);
268       fRawReader->RewindEvents();
269     } else {
270       throw (kEH + "unknown run number.");
271     }
272   }
273
274   {
275     AliCDBManager* cdb = AliCDBManager::Instance();
276     cdb->SetDefaultStorage(fgCdbUri);
277     if (cdb->IsDefaultStorageSet() == kFALSE)
278       throw (kEH + "CDB initialization failed.");
279     cdb->SetRun(runNo);
280   }
281
282   SetName(Form("Event %d", fEventId));
283   SetTitle(fPath);
284 }
285
286 void AliEveEventManager::GotoEvent(Int_t event)
287 {
288   // Load data for specified event.
289   // If event is out of range an exception is thrown and old state
290   // is preserved.
291   // After successful loading of event, the virtual function
292   // AfterNewEventLoaded() is called. This executes commands that
293   // were registered via TEveEventManager::AddNewEventCommand().
294
295   static const TEveException kEH("AliEveEventManager::GotoEvent ");
296
297   if (event < 0) {
298     Error(kEH, "event must be non-negative.");
299     return;
300   }
301
302   Int_t maxEvent = 0;
303   if (fRunLoader) {
304     maxEvent = fRunLoader->GetNumberOfEvents() - 1;
305   } else if (fESDTree) {
306     maxEvent = fESDTree->GetEntries() - 1;
307   } else if (fRawReader) {
308     maxEvent = 10000000;
309     Info(kEH, "number of events unknown for raw-data, setting max-event id to 10M.");
310   } else {
311     throw (kEH + "neither RunLoader, ESD nor Raw loaded.");
312   }
313   if (event < 0 || event > maxEvent)
314     throw (kEH + Form("event %d not present, available range [%d, %d].",
315                       event, 0, maxEvent));
316
317   TEveManager::TRedrawDisabler rd(gEve);
318   gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
319
320   // !!! MT this is somewhat brutal; at least optionally, one could be
321   // a bit gentler, checking for objs owning their external refs and having
322   // additinal parents.
323   DestroyElements();
324
325   if (fRunLoader) {
326     if (fRunLoader->GetEvent(event) != 0)
327       throw (kEH + "failed getting required event.");
328   }
329
330   if (fESDTree) {
331     if (fESDTree->GetEntry(event) <= 0)
332       throw (kEH + "failed getting required event from ESD.");
333
334     if (fESDfriendExists)
335       fESD->SetESDfriend(fESDfriend);
336   }
337
338   if (fRawReader)
339   {
340     Int_t rawEv = fEventId;
341     if (event < rawEv)
342     {
343       fRawReader->RewindEvents();
344       rawEv = -1;
345     }
346
347     while (rawEv < event)
348     {
349       if ( ! fRawReader->NextEvent())
350       {
351         fRawReader->RewindEvents();
352         fEventId = -1;
353         throw (kEH + Form("Error going to next raw-event from event %d.", rawEv));
354       }
355       ++rawEv;
356     }
357
358     printf ("Loaded raw-event %d.\n", rawEv);
359   }
360
361   fEventId = event;
362   SetName(Form("Event %d", fEventId));
363   UpdateItems();
364
365   AfterNewEventLoaded();
366 }
367
368 void AliEveEventManager::Close()
369 {
370   // Close the event files.
371   // For the moment only ESD is closed. Needs to be investigated for
372   // AliRunLoader and Raw.
373
374   if (fESDTree) {
375     delete fESD;       fESD       = 0;
376     delete fESDfriend; fESDfriend = 0;
377
378     delete fESDTree; fESDTree = 0;
379     delete fESDFile; fESDFile = 0;
380   }
381 }
382
383
384 /******************************************************************************/
385 // Static convenience functions, mainly used from macros.
386 /******************************************************************************/
387
388 AliRunLoader* AliEveEventManager::AssertRunLoader()
389 {
390   // Make sure AliRunLoader is initialized and return it.
391   // Throws exception in case run-loader is not available.
392   // Static utility for macros.
393
394   static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
395
396   if (gAliEveEvent == 0)
397     throw (kEH + "ALICE event not ready.");
398   if (gAliEveEvent->fRunLoader == 0)
399     throw (kEH + "AliRunLoader not initialised.");
400   return gAliEveEvent->fRunLoader;
401 }
402
403 AliESDEvent* AliEveEventManager::AssertESD()
404 {
405   // Make sure AliESDEvent is initialized and return it.
406   // Throws exception in case ESD is not available.
407   // Static utility for macros.
408
409   static const TEveException kEH("AliEveEventManager::AssertESD ");
410
411   if (gAliEveEvent == 0)
412     throw (kEH + "ALICE event not ready.");
413   if (gAliEveEvent->fESD == 0)
414     throw (kEH + "AliESD not initialised.");
415   return gAliEveEvent->fESD;
416 }
417
418 AliESDfriend* AliEveEventManager::AssertESDfriend()
419 {
420   // Make sure AliESDfriend is initialized and return it.
421   // Throws exception in case ESDfriend-loader is not available.
422   // Static utility for macros.
423
424   static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
425
426   if (gAliEveEvent == 0)
427     throw (kEH + "ALICE event not ready.");
428   if (gAliEveEvent->fESDfriend == 0)
429     throw (kEH + "AliESDfriend not initialised.");
430   return gAliEveEvent->fESDfriend;
431 }
432
433 AliRawReader* AliEveEventManager::AssertRawReader()
434 {
435   // Make sure raw-reader is initialized and return it.
436
437   static const TEveException kEH("AliEveEventManager::AssertRawReader ");
438
439   if (gAliEveEvent == 0)
440     throw (kEH + "ALICE event not ready.");
441   if (gAliEveEvent->fRawReader == 0)
442     throw (kEH + "RawReader not ready.");
443
444   return gAliEveEvent->fRawReader;
445 }
446
447 AliMagF* AliEveEventManager::AssertMagField()
448 {
449   // Make sure AliMagF is initialized and return it.
450   // Throws exception in case magnetic field is not available.
451   // Static utility for macros.
452
453   if (fgMagField == 0)
454   {
455     if (gAliEveEvent && gAliEveEvent->fRunLoader && gAliEveEvent->fRunLoader->GetAliRun())
456       fgMagField = gAliEveEvent->fRunLoader->GetAliRun()->Field();
457     else
458       fgMagField = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k5kG);
459   }
460   return fgMagField;
461 }
462
463 TGeoManager* AliEveEventManager::AssertGeometry()
464 {
465   // Make sure AliGeomManager is initialized and returns the
466   // corresponding TGeoManger.
467   // gGeoManager is not set, maybe it should be.
468   // Throws exception in case run-loader is not available.
469   // Static utility for macros.
470
471   // !!!! Should we set gGeoManager here?
472
473   static const TEveException kEH("AliEveEventManager::AssertGeometry ");
474
475   if (AliGeomManager::GetGeometry() == 0)
476   {
477     gGeoManager = 0;
478     AliGeomManager::LoadGeometry();
479     if ( ! AliGeomManager::GetGeometry())
480     {
481       throw (kEH + "can not load geometry.");
482     }
483     if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
484     {
485       ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
486       // throw (kEH + "could not apply align objs.");
487     }
488
489     // Temporary fix.
490     // In AliEve several simplified geometries can be loaded at a later stage.
491     // Should handle this inTEveManager::GetGeometry() by properly
492     // unlocking and re-locking the geo-manager.
493     TGeoManager::UnlockGeometry();
494   }
495
496   return AliGeomManager::GetGeometry();
497 }