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