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