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