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