From Cvetan: when opening an event from ESD get the first tree-entry so that run...
[u/mrichter/AliRoot.git] / EVE / EveBase / AliEveEventManager.cxx
CommitLineData
d810d0de 1// $Id$
2// Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
5a5a1232 3
d810d0de 4/**************************************************************************
5 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for *
51346b82 7 * full copyright notice. *
d810d0de 8 **************************************************************************/
9
10#include "AliEveEventManager.h"
84aff7a4 11#include <TEveManager.h>
5a5a1232 12
13#include <AliRunLoader.h>
93845f6c 14#include <AliRun.h>
af885e0f 15#include <AliESDEvent.h>
3aecaefc 16#include <AliESDfriend.h>
c2c4b7a2 17#include <AliRawReaderRoot.h>
18#include <AliRawReaderFile.h>
19#include <AliRawReaderDate.h>
93845f6c 20#include <AliMagFMaps.h>
632d2b03 21#include <AliCDBManager.h>
22#include <AliHeader.h>
23#include <AliGeomManager.h>
5a5a1232 24
25#include <TFile.h>
26#include <TTree.h>
5a5a1232 27#include <TSystem.h>
d810d0de 28
a15e6d7d 29//==============================================================================
30//==============================================================================
31// AliEveEventManager
32//==============================================================================
5a5a1232 33
57ffa5fb 34//______________________________________________________________________________
5a5a1232 35//
4852ff6f 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.
51346b82 41//
a15e6d7d 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.
5a5a1232 45
d810d0de 46ClassImp(AliEveEventManager)
5a5a1232 47
a15e6d7d 48AliEveEventManager* gAliEveEvent = 0;
5a5a1232 49
d810d0de 50Bool_t AliEveEventManager::fgAssertRunLoader = kFALSE;
c76ea574 51Bool_t AliEveEventManager::fgAssertESD = kFALSE;
c2c4b7a2 52Bool_t AliEveEventManager::fgAssertRaw = kFALSE;
5a5a1232 53
c2c4b7a2 54TString AliEveEventManager::fgESDFileName("AliESDs.root");
55TString AliEveEventManager::fgRawFileName("raw.root");
d810d0de 56TString AliEveEventManager::fgCdbUri("local://$ALICE_ROOT");
632d2b03 57
d810d0de 58AliMagF* AliEveEventManager::fgMagField = 0;
93845f6c 59
60
d810d0de 61AliEveEventManager::AliEveEventManager() :
84aff7a4 62 TEveEventManager(),
265ecb21 63
c2c4b7a2 64 fPath ( ), fEventId (-1),
265ecb21 65 fRunLoader (0),
90fa773e 66 fESDFile (0), fESDTree (0), fESD (0),
c2c4b7a2 67 fESDfriend (0), fESDfriendExists(kFALSE),
319f3084 68 fRawReader (0),
69 fAutoLoad(kFALSE),
70 fAutoLoadTime(5.),
71 fAutoLoadTimer(0),
72 fIsOnline(kFALSE)
c76ea574 73{
74 // Default constructor.
75}
5a5a1232 76
d810d0de 77AliEveEventManager::AliEveEventManager(TString path, Int_t ev) :
78 TEveEventManager("AliEVE AliEveEventManager"),
265ecb21 79
c76ea574 80 fPath (path), fEventId(-1),
265ecb21 81 fRunLoader (0),
90fa773e 82 fESDFile (0), fESDTree (0), fESD (0),
c2c4b7a2 83 fESDfriend (0), fESDfriendExists(kFALSE),
319f3084 84 fRawReader (0),
85 fAutoLoad(kFALSE),
86 fAutoLoadTime(5.),
87 fAutoLoadTimer(0),
88 fIsOnline(kFALSE)
5a5a1232 89{
c76ea574 90 // Constructor with event-directory URL and event-id.
91
5a5a1232 92 Open();
90fa773e 93 if (ev >= 0) GotoEvent(ev);
5a5a1232 94}
95
a15e6d7d 96AliEveEventManager::~AliEveEventManager()
97{
98 // Destructor.
99
319f3084 100 if (fAutoLoadTimer) delete fAutoLoadTimer;
a15e6d7d 101 // Somewhat unclear what to do here.
102 // In principle should close all data sources and deregister from
103 // TEveManager.
104}
105
57ffa5fb 106/******************************************************************************/
5a5a1232 107
c2c4b7a2 108void 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
115void 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
121void AliEveEventManager::SetCdbUri(const Text_t* cdb)
122{
123 // Set path to CDB, default "local://$ALICE_ROOT".
124
125 if (cdb) fgCdbUri = cdb;
126}
127
128void 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
d810d0de 142void AliEveEventManager::Open()
5a5a1232 143{
c76ea574 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
a15e6d7d 150 static const TEveException kEH("AliEveEventManager::Open ");
5a5a1232 151
152 gSystem->ExpandPathName(fPath);
84aff7a4 153 if (fPath[0] != '/')
5a5a1232 154 fPath = Form("%s/%s", gSystem->WorkingDirectory(), fPath.Data());
155
632d2b03 156 Int_t runNo = -1;
157
a15e6d7d 158 TString gaPath(Form("%s/galice.root", fPath.Data()));
c2c4b7a2 159 // If i use open directly, we get fatal.
160 // Is this (AccessPathName check) ok for xrootd / alien?
a15e6d7d 161 if (gSystem->AccessPathName(gaPath, kReadPermission) == kFALSE)
90fa773e 162 {
a15e6d7d 163 fRunLoader = AliRunLoader::Open(gaPath);
a1896a82 164 if (fRunLoader)
5a5a1232 165 {
a15e6d7d 166 TString alicePath = fPath + "/";
167 fRunLoader->SetDirName(alicePath);
a1896a82 168
169 if (fRunLoader->LoadgAlice() != 0)
c2c4b7a2 170 Warning(kEH, "failed loading gAlice via run-loader.");
a1896a82 171
172 if (fRunLoader->LoadHeader() == 0)
173 {
c2c4b7a2 174 runNo = fRunLoader->GetHeader()->GetRun();
a1896a82 175 }
176 else
177 {
c2c4b7a2 178 Warning(kEH, "failed loading run-loader's header.");
179 delete fRunLoader;
180 fRunLoader = 0;
a1896a82 181 }
182 }
183 else // run-loader open failed
184 {
a15e6d7d 185 Warning(kEH, "failed opening ALICE run-loader from '%s'.", gaPath.Data());
5a5a1232 186 }
5a5a1232 187 }
a1896a82 188 else // galice not readable
189 {
a15e6d7d 190 Warning(kEH, "can not read '%s'.", gaPath.Data());
a1896a82 191 }
192 if (fRunLoader == 0)
193 {
84aff7a4 194 if (fgAssertRunLoader)
c2c4b7a2 195 throw (kEH + "Bootstraping of run-loader failed. Its precence was requested.");
a1896a82 196 else
a15e6d7d 197 Warning(kEH, "Bootstraping of run-loader failed.");
a1896a82 198 }
51346b82 199
5a5a1232 200
c2c4b7a2 201 TString esdPath(Form("%s/%s", fPath.Data(), fgESDFileName.Data()));
202 if ((fESDFile = TFile::Open(esdPath)))
90fa773e 203 {
c2c4b7a2 204 fESD = new AliESDEvent();
205 fESDTree = (TTree*) fESDFile->Get("esdTree");
206 if (fESDTree != 0)
90fa773e 207 {
c2c4b7a2 208 fESD->ReadFromTree(fESDTree);
e8974bc9 209 fESDTree->GetEntry(0);
c2c4b7a2 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)
a1896a82 215 {
c2c4b7a2 216 fESDfriendExists = kTRUE;
217 fESDTree->SetBranchStatus ("ESDfriend*", 1);
218 fESDTree->SetBranchAddress("ESDfriend.", &fESDfriend);
753fdd1e 219 }
220 }
c2c4b7a2 221 else // esdtree == 0
a1896a82 222 {
5a5a1232 223 delete fESDFile; fESDFile = 0;
c2c4b7a2 224 Warning(kEH, "failed getting the esdTree.");
5a5a1232 225 }
a1896a82 226 }
227 else // esd not readable
228 {
a15e6d7d 229 Warning(kEH, "can not read ESD file '%s'.", esdPath.Data());
a1896a82 230 }
231 if (fESDTree == 0)
232 {
c76ea574 233 if (fgAssertESD)
90fa773e 234 {
c2c4b7a2 235 throw (kEH + "ESD not initialized. Its precence was requested.");
51346b82 236 } else {
a15e6d7d 237 Warning(kEH, "ESD not initialized.");
3aecaefc 238 }
5a5a1232 239 }
240
c2c4b7a2 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
632d2b03 271 if (runNo < 0)
c2c4b7a2 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 }
632d2b03 283
284 {
285 AliCDBManager* cdb = AliCDBManager::Instance();
286 cdb->SetDefaultStorage(fgCdbUri);
287 if (cdb->IsDefaultStorageSet() == kFALSE)
c2c4b7a2 288 throw (kEH + "CDB initialization failed.");
632d2b03 289 cdb->SetRun(runNo);
290 }
291
73c1c0ec 292 SetName(Form("Event %d", fEventId));
5a5a1232 293 SetTitle(fPath);
294}
295
319f3084 296void 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
d810d0de 311void AliEveEventManager::GotoEvent(Int_t event)
1eaa5849 312{
73c1c0ec 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
a15e6d7d 320 static const TEveException kEH("AliEveEventManager::GotoEvent ");
1eaa5849 321
c2c4b7a2 322 if (event < 0) {
323 Error(kEH, "event must be non-negative.");
324 return;
325 }
326
1eaa5849 327 Int_t maxEvent = 0;
c2c4b7a2 328 if (fRunLoader) {
1eaa5849 329 maxEvent = fRunLoader->GetNumberOfEvents() - 1;
c2c4b7a2 330 } else if (fESDTree) {
1eaa5849 331 maxEvent = fESDTree->GetEntries() - 1;
c2c4b7a2 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 }
84aff7a4 338 if (event < 0 || event > maxEvent)
c2c4b7a2 339 throw (kEH + Form("event %d not present, available range [%d, %d].",
340 event, 0, maxEvent));
1eaa5849 341
84aff7a4 342 TEveManager::TRedrawDisabler rd(gEve);
343 gEve->Redraw3D(kFALSE, kTRUE); // Enforce drop of all logicals.
d9e0d6c5 344
32e219c2 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.
1eaa5849 348 DestroyElements();
1eaa5849 349
84aff7a4 350 if (fRunLoader) {
c2c4b7a2 351 if (fRunLoader->GetEvent(event) != 0)
352 throw (kEH + "failed getting required event.");
1eaa5849 353 }
354
84aff7a4 355 if (fESDTree) {
c2c4b7a2 356 if (fESDTree->GetEntry(event) <= 0)
357 throw (kEH + "failed getting required event from ESD.");
1eaa5849 358
2cea771a 359 if (fESDfriendExists)
1eaa5849 360 fESD->SetESDfriend(fESDfriend);
1eaa5849 361 }
90fa773e 362
c2c4b7a2 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));
319f3084 388 ElementChanged();
c2c4b7a2 389
90fa773e 390 AfterNewEventLoaded();
1eaa5849 391}
392
d810d0de 393void AliEveEventManager::Close()
5a5a1232 394{
73c1c0ec 395 // Close the event files.
396 // For the moment only ESD is closed. Needs to be investigated for
397 // AliRunLoader and Raw.
398
2cea771a 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 }
5a5a1232 406}
407
90fa773e 408
57ffa5fb 409/******************************************************************************/
c76ea574 410// Static convenience functions, mainly used from macros.
57ffa5fb 411/******************************************************************************/
5a5a1232 412
d810d0de 413AliRunLoader* AliEveEventManager::AssertRunLoader()
5a5a1232 414{
73c1c0ec 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
a15e6d7d 419 static const TEveException kEH("AliEveEventManager::AssertRunLoader ");
5a5a1232 420
a15e6d7d 421 if (gAliEveEvent == 0)
c2c4b7a2 422 throw (kEH + "ALICE event not ready.");
a15e6d7d 423 if (gAliEveEvent->fRunLoader == 0)
c2c4b7a2 424 throw (kEH + "AliRunLoader not initialised.");
a15e6d7d 425 return gAliEveEvent->fRunLoader;
5a5a1232 426}
427
d810d0de 428AliESDEvent* AliEveEventManager::AssertESD()
5a5a1232 429{
73c1c0ec 430 // Make sure AliESDEvent is initialized and return it.
431 // Throws exception in case ESD is not available.
432 // Static utility for macros.
433
a15e6d7d 434 static const TEveException kEH("AliEveEventManager::AssertESD ");
5a5a1232 435
a15e6d7d 436 if (gAliEveEvent == 0)
c2c4b7a2 437 throw (kEH + "ALICE event not ready.");
a15e6d7d 438 if (gAliEveEvent->fESD == 0)
c2c4b7a2 439 throw (kEH + "AliESD not initialised.");
a15e6d7d 440 return gAliEveEvent->fESD;
5a5a1232 441}
3aecaefc 442
d810d0de 443AliESDfriend* AliEveEventManager::AssertESDfriend()
3aecaefc 444{
73c1c0ec 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
a15e6d7d 449 static const TEveException kEH("AliEveEventManager::AssertESDfriend ");
3aecaefc 450
a15e6d7d 451 if (gAliEveEvent == 0)
c2c4b7a2 452 throw (kEH + "ALICE event not ready.");
a15e6d7d 453 if (gAliEveEvent->fESDfriend == 0)
c2c4b7a2 454 throw (kEH + "AliESDfriend not initialised.");
a15e6d7d 455 return gAliEveEvent->fESDfriend;
3aecaefc 456}
93845f6c 457
c2c4b7a2 458AliRawReader* 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
d810d0de 472AliMagF* AliEveEventManager::AssertMagField()
93845f6c 473{
73c1c0ec 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
93845f6c 478 if (fgMagField == 0)
479 {
a15e6d7d 480 if (gAliEveEvent && gAliEveEvent->fRunLoader && gAliEveEvent->fRunLoader->GetAliRun())
481 fgMagField = gAliEveEvent->fRunLoader->GetAliRun()->Field();
93845f6c 482 else
483 fgMagField = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k5kG);
484 }
485 return fgMagField;
486}
632d2b03 487
d810d0de 488TGeoManager* AliEveEventManager::AssertGeometry()
632d2b03 489{
73c1c0ec 490 // Make sure AliGeomManager is initialized and returns the
491 // corresponding TGeoManger.
647814a2 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.
73c1c0ec 495 // Static utility for macros.
496
a15e6d7d 497 static const TEveException kEH("AliEveEventManager::AssertGeometry ");
632d2b03 498
499 if (AliGeomManager::GetGeometry() == 0)
500 {
647814a2 501 if (TGeoManager::IsLocked())
502 throw (kEH + "geometry is not loaded but TGeoManager is locked.");
503
af2e4ef5 504 gGeoManager = 0;
632d2b03 505 AliGeomManager::LoadGeometry();
506 if ( ! AliGeomManager::GetGeometry())
507 {
c2c4b7a2 508 throw (kEH + "can not load geometry.");
632d2b03 509 }
510 if ( ! AliGeomManager::ApplyAlignObjsFromCDB("ITS TPC TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO ACORDE"))
511 {
a15e6d7d 512 ::Warning(kEH, "mismatch of alignable volumes. Proceeding.");
c2c4b7a2 513 // throw (kEH + "could not apply align objs.");
632d2b03 514 }
c2c4b7a2 515
647814a2 516 // @@NEWROOT@@ Temporary fix.
c2c4b7a2 517 // In AliEve several simplified geometries can be loaded at a later stage.
647814a2 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.
c2c4b7a2 521 TGeoManager::UnlockGeometry();
632d2b03 522 }
523
647814a2 524 gGeoManager = AliGeomManager::GetGeometry();
525 return gGeoManager;
632d2b03 526}
319f3084 527
528void AliEveEventManager::SetAutoLoad(Bool_t autoLoad)
529{
530 // Set the automatic event loading mode
531 fAutoLoad = autoLoad;
532 StartStopAutoLoadTimer();
533}
534
535void AliEveEventManager::SetAutoLoadTime(Double_t time)
536{
537 // Set the auto-load time in seconds
538 fAutoLoadTime = time;
539 StartStopAutoLoadTimer();
540}
541
542void 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
558void 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
568void 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
587const 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