Fixes for #86059: Install data when ALICE_ROOT does not point to source (Christian)
[u/mrichter/AliRoot.git] / MUON / AliMUONMCDataInterface.cxx
CommitLineData
1df4a03e 1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
15
16// $Id$
17
3d1463c8 18//-----------------------------------------------------------------------------
1df4a03e 19/// \class AliMUONMCDataInterface
20///
21/// Easy to use MC data accessor
22///
23/// \author Laurent Aphecetche, Subatech
e8636ba0 24///
25// Moved parts of old AliMUONDataInterface interface to AliMUONMCDataInterface
26// Artur Szostak <artursz@iafrica.com> (University of Cape Town)
3d1463c8 27//-----------------------------------------------------------------------------
1df4a03e 28
29#include "AliMUONMCDataInterface.h"
e9bef706 30#include "AliMUONVDigitStore.h"
31#include "AliMUONVHitStore.h"
e9bef706 32#include "AliMUONVTriggerStore.h"
e8636ba0 33#include "AliMUONHit.h"
34#include "AliMUONVDigit.h"
35#include "AliMUONLocalTrigger.h"
36#include "AliMUONRegionalTrigger.h"
37#include "AliMUONGlobalTrigger.h"
38
168e9c4d 39#include "AliMpEncodePair.h"
e8636ba0 40#include "AliMpDEManager.h"
41#include "AliMpConstants.h"
a55f49a0 42#include "AliMpCDB.h"
1df4a03e 43
44#include "AliLog.h"
c93255fe 45#include "AliLoader.h"
1df4a03e 46#include "AliRunLoader.h"
aa73f8fb 47#include "AliHeader.h"
1df4a03e 48#include "AliStack.h"
aa73f8fb 49#include "AliCDBManager.h"
e9bef706 50
c93255fe 51#include <TTree.h>
1df4a03e 52#include <Riostream.h>
53#include <TClonesArray.h>
e9bef706 54#include <TList.h>
1df4a03e 55#include <TParticle.h>
e8636ba0 56#include <TIterator.h>
57#include <cstdlib>
58#include <cassert>
1df4a03e 59
60/// \cond CLASSIMP
61ClassImp(AliMUONMCDataInterface)
62/// \endcond
63
e9bef706 64Int_t AliMUONMCDataInterface::fgInstanceCounter(0);
65
1df4a03e 66//_____________________________________________________________________________
67AliMUONMCDataInterface::AliMUONMCDataInterface(const char* filename) :
68TObject(),
e9bef706 69fLoader(0x0),
70fHitStore(0x0),
71fSDigitStore(0x0),
72fDigitStore(0x0),
73fTriggerStore(0x0),
74fTrackRefs(0x0),
75fCurrentEvent(-1),
e8636ba0 76fIsValid(kFALSE),
77fCurrentIteratorType(kNoIterator),
78fCurrentIndex(-1),
79fDataX(-1),
80fDataY(-1),
81fIterator(0x0)
1df4a03e 82{
83 /// ctor
e9bef706 84
85 ++fgInstanceCounter;
86
88c5d53f 87 if ( AliCDBManager::Instance() != NULL &&
88 AliCDBManager::Instance()->GetDefaultStorage() == NULL ) {
89 AliFatal("CDB default storage not defined.");
ae9e8f66 90 }
91
e9bef706 92 Open(filename);
a55f49a0 93
94 // Load mapping
95 if ( ! AliMpCDB::LoadMpSegmentation() ) {
96 AliFatal("Could not access mapping from OCDB !");
97 }
1df4a03e 98}
99
100//_____________________________________________________________________________
101AliMUONMCDataInterface::~AliMUONMCDataInterface()
102{
103 /// dtor
e9bef706 104 --fgInstanceCounter;
105}
106
107//_____________________________________________________________________________
e8636ba0 108AliMUONVHitStore*
109AliMUONMCDataInterface::HitStore(Int_t event, Int_t track)
110{
111 /// Return the hitStore for a given track of one event
112 /// Return 0x0 if event and/or track not found
113 /// Returned pointer should not be deleted
46df197d 114 ///
115 /// \note If a previous store has been retrieved by one of the methods of
116 /// this class, but for a different event number, then those stores will
117 /// be deleted and no longer valid.
118 /// If you require access to the data for the earlier retrieved store,
119 /// but for different events, then you should deep copy / clone the object.
e8636ba0 120
121 if (not IsValid()) return 0x0;
4cfe83bc 122
123 if (event == fCurrentEvent)
124 {
125 if (track == fDataX and fHitStore != 0x0) // using fDataX as track number.
e8636ba0 126 return fHitStore;
4cfe83bc 127 }
128 else
129 {
130 ResetStores();
131 if ( not LoadEvent(event) ) return 0x0;
132 }
e8636ba0 133
134 fLoader->LoadHits();
135
136 TTree* treeH = fLoader->TreeH();
137 if (treeH == 0x0)
138 {
139 AliError("Could not get treeH");
140 return 0x0;
141 }
142
143 fHitStore = AliMUONVHitStore::Create(*treeH);
144 AliDebug(1,"Creating hitStore from treeH");
145 if ( fHitStore != 0x0 )
146 {
147 fHitStore->Connect(*treeH);
148 if ( treeH->GetEvent(track) == 0 )
149 {
150 AliError(Form("Could not read track %d",track));
151 fHitStore->Clear();
152 return 0x0;
153 }
154 fDataX = track; // using fDataX as track number.
155 }
156
157 fLoader->UnloadHits();
158
159 return fHitStore;
160}
161
162//_____________________________________________________________________________
163AliMUONVDigitStore*
164AliMUONMCDataInterface::SDigitStore(Int_t event)
165{
166 /// Return the SDigit store for a given event.
167 /// Return 0 if event not found
168 /// Returned pointer should not be deleted
46df197d 169 ///
170 /// \note If a previous store has been retrieved by one of the methods of
171 /// this class, but for a different event number, then those stores will
172 /// be deleted and no longer valid.
173 /// If you require access to the data for the earlier retrieved store,
174 /// but for different events, then you should deep copy / clone the object.
e8636ba0 175
176 if (not IsValid()) return 0x0;
e8636ba0 177
4cfe83bc 178 if (event == fCurrentEvent)
179 {
180 if (fSDigitStore != 0x0)
181 return fSDigitStore;
182 }
183 else
184 {
185 ResetStores();
186 if ( not LoadEvent(event) ) return 0x0;
187 }
e8636ba0 188
189 fLoader->LoadSDigits();
190
191 TTree* treeS = fLoader->TreeS();
192 if (treeS == 0x0)
193 {
194 AliError("Could not get treeS");
195 return 0x0;
196 }
197
198 fSDigitStore = AliMUONVDigitStore::Create(*treeS);
199 if ( fSDigitStore != 0x0 )
200 {
201 fSDigitStore->Clear();
202 fSDigitStore->Connect(*treeS);
203 treeS->GetEvent(0);
204 }
205
206 fLoader->UnloadSDigits();
207
208 return fSDigitStore;
209}
210
211//_____________________________________________________________________________
e9bef706 212AliMUONVDigitStore*
213AliMUONMCDataInterface::DigitStore(Int_t event)
214{
215 /// Return a pointer to the digitStore for a given event (or 0 if not found)
216 /// Returned pointer should not be deleted
46df197d 217 ///
218 /// \note If a previous store has been retrieved by one of the methods of
219 /// this class, but for a different event number, then those stores will
220 /// be deleted and no longer valid.
221 /// If you require access to the data for the earlier retrieved store,
222 /// but for different events, then you should deep copy / clone the object.
e9bef706 223
e8636ba0 224 if (not IsValid()) return 0x0;
e8636ba0 225
4cfe83bc 226 if (event == fCurrentEvent)
227 {
228 if (fDigitStore != 0x0)
229 return fDigitStore;
230 }
231 else
232 {
233 ResetStores();
234 if ( not LoadEvent(event) ) return 0x0;
235 }
e9bef706 236
237 fLoader->LoadDigits();
238
239 TTree* treeD = fLoader->TreeD();
e8636ba0 240 if (treeD == 0x0)
e9bef706 241 {
242 AliError("Could not get treeD");
243 return 0x0;
244 }
245
e8636ba0 246 fDigitStore = AliMUONVDigitStore::Create(*treeD);
247 if ( fDigitStore != 0x0 )
e9bef706 248 {
249 fDigitStore->Clear();
250 fDigitStore->Connect(*treeD);
251 treeD->GetEvent(0);
252 }
253
254 fLoader->UnloadDigits();
255
256 return fDigitStore;
257}
258
259//_____________________________________________________________________________
e8636ba0 260AliStack*
261AliMUONMCDataInterface::Stack(Int_t event)
262{
263 /// Get the Stack (list of generated particles) for one event
264 /// Returned pointer should not be deleted
46df197d 265 ///
266 /// \note If a previous store has been retrieved by one of the methods of
267 /// this class, but for a different event number, then those stores will
268 /// be deleted and no longer valid.
269 /// If you require access to the data for the earlier retrieved store,
270 /// but for different events, then you should deep copy / clone the object.
e8636ba0 271
272 if ( not IsValid() ) return 0x0;
273
274 if (event != fCurrentEvent)
275 {
276 ResetStores();
277 if ( not LoadEvent(event) ) return 0x0;
278 }
279
280 fLoader->GetRunLoader()->LoadKinematics();
281
282 return fLoader->GetRunLoader()->Stack();
283}
284
285//_____________________________________________________________________________
286TClonesArray*
287AliMUONMCDataInterface::TrackRefs(Int_t event, Int_t track)
288{
289 /// Get the track references for a given (generated) track of one event
290 /// Returned pointer should not be deleted
46df197d 291 ///
292 /// \note If a previous store has been retrieved by one of the methods of
293 /// this class, but for a different event number, then those stores will
294 /// be deleted and no longer valid.
295 /// If you require access to the data for the earlier retrieved store,
296 /// but for different events, then you should deep copy / clone the object.
e8636ba0 297
298 if ( not IsValid() ) return 0x0;
4cfe83bc 299
300 if (event == fCurrentEvent)
301 {
302 if (track == fDataX and fTrackRefs != 0x0) // using fDataX as track number.
303 return fTrackRefs;
304 }
305 else
e8636ba0 306 {
307 ResetStores();
308 if ( not LoadEvent(event) ) return 0x0;
309 }
310
e8636ba0 311 fLoader->GetRunLoader()->LoadTrackRefs();
312
313 TTree* treeTR = fLoader->GetRunLoader()->TreeTR();
314
315 if ( fTrackRefs != 0x0 ) fTrackRefs->Clear("C");
316
317 if (treeTR != 0x0)
318 {
319 if ( treeTR->GetEvent(track) > 0 )
320 {
91469ad4 321 TBranch* branch = treeTR->GetBranch("TrackReferences");
e8636ba0 322 branch->SetAddress(&fTrackRefs);
323 branch->GetEvent(track);
324 fDataX = track; // using fDataX as track number.
325 }
326 }
327 else
328 {
329 AliError("Could not get TreeTR");
330 }
331
332 fLoader->GetRunLoader()->UnloadTrackRefs();
333
334 return fTrackRefs;
335}
336
337//_____________________________________________________________________________
338AliMUONVTriggerStore*
339AliMUONMCDataInterface::TriggerStore(Int_t event)
340{
341 /// Return the triggerStore for a given event.
342 /// Return 0x0 if event not found.
343 /// Returned pointer should not be deleted.
46df197d 344 ///
345 /// \note If a previous store has been retrieved by one of the methods of
346 /// this class, but for a different event number, then those stores will
347 /// be deleted and no longer valid.
348 /// If you require access to the data for the earlier retrieved store,
349 /// but for different events, then you should deep copy / clone the object.
e8636ba0 350
351 if (not IsValid()) return 0x0;
e8636ba0 352
4cfe83bc 353 if (event == fCurrentEvent)
354 {
355 if (fTriggerStore != 0x0)
356 return fTriggerStore;
357 }
358 else
359 {
360 ResetStores();
361 if ( not LoadEvent(event) ) return 0x0;
362 }
e8636ba0 363
364 fLoader->LoadDigits();
365
366 TTree* treeD = fLoader->TreeD();
367 if ( treeD == 0x0 )
368 {
369 AliError("Could not get treeD");
370 return 0x0;
371 }
372
373 fTriggerStore = AliMUONVTriggerStore::Create(*treeD);
374 if ( fTriggerStore != 0x0 )
375 {
376 fTriggerStore->Clear();
377 fTriggerStore->Connect(*treeD);
378 treeD->GetEvent(0);
379 }
380
381 fLoader->UnloadDigits();
382
383 return fTriggerStore;
384}
385
386//_____________________________________________________________________________
e9bef706 387void
388AliMUONMCDataInterface::DumpDigits(Int_t event, Bool_t sorted)
389{
390 /// Dump the digits for a given event, sorted if requested.
391 DigitStore(event);
392
e8636ba0 393 if ( fDigitStore != 0x0 )
e9bef706 394 {
395 if ( sorted )
396 {
397 DumpSorted(*fDigitStore);
398 }
399 else
400 {
401 fDigitStore->Print();
402 }
403 }
1df4a03e 404}
405
406//_____________________________________________________________________________
407void
e9bef706 408AliMUONMCDataInterface::DumpHits(Int_t event)
1df4a03e 409{
410 /// Dump all the hits for one event
411
412 Int_t ntracks = NumberOfTracks(event);
413
414 for ( Int_t i = 0; i < ntracks; ++i )
415 {
416 cout << ">> Track " << i << endl;
e9bef706 417 HitStore(event,i);
418 if ( fHitStore )
419 {
420 fHitStore->Print("","full");
421 }
1df4a03e 422 }
423}
424
425//_____________________________________________________________________________
426void
e9bef706 427AliMUONMCDataInterface::DumpKine(Int_t event)
1df4a03e 428{
429 /// Dump all generated particles for one event
430 AliStack* stack = Stack(event);
431
e8636ba0 432 if ( stack != 0x0 )
1df4a03e 433 {
434 Int_t nparticles = (Int_t) stack->GetNtrack();
435
436 for (Int_t iparticle=0; iparticle<nparticles; ++iparticle)
437 {
438 stack->Particle(iparticle)->Print("");
439 }
440 }
441 else
442 {
443 AliError("Could not get stack");
444 }
445}
446
447//_____________________________________________________________________________
448void
e9bef706 449AliMUONMCDataInterface::DumpSDigits(Int_t event, Bool_t sorted)
450{
451 /// Dump the SDigits for a given event, sorted if requested
452 SDigitStore(event);
453
e8636ba0 454 if ( fSDigitStore != 0x0 )
e9bef706 455 {
456 if ( sorted )
457 {
458 DumpSorted(*fSDigitStore);
459 }
460 else
461 {
462 fSDigitStore->Print();
463 }
464 }
465}
466
467//_____________________________________________________________________________
468void
469AliMUONMCDataInterface::DumpSorted(const AliMUONVStore& store) const
470{
471 /// Dump the given store in sorted order
472
473 TIter next(store.CreateIterator());
474 TObject* object;
475 TList list;
476 list.SetOwner(kFALSE);
477
478 while ( ( object = next() ) )
479 {
480 list.Add(object);
481 }
482
483 list.Sort();
484
485 list.Print();
486}
487
488//_____________________________________________________________________________
489void
490AliMUONMCDataInterface::DumpTrackRefs(Int_t event)
1df4a03e 491{
492 /// Dump track references for one event
493 Int_t ntrackrefs = NumberOfTrackRefs(event);
494
495 for ( Int_t i = 0; i < ntrackrefs; ++i )
496 {
e9bef706 497 TrackRefs(event,i);
e8636ba0 498 if ( fTrackRefs != 0x0 )
e9bef706 499 {
500 fTrackRefs->Print("","*");
501 }
502 }
503}
504
505//_____________________________________________________________________________
506void
507AliMUONMCDataInterface::DumpTrigger(Int_t event)
508{
509 /// Dump trigger for a given event (trigger is read from TreeD)
510
511 TriggerStore(event);
512
e8636ba0 513 if ( fTriggerStore != 0x0 )
e9bef706 514 {
515 fTriggerStore->Print();
1df4a03e 516 }
517}
518
519//_____________________________________________________________________________
1df4a03e 520Bool_t
e9bef706 521AliMUONMCDataInterface::LoadEvent(Int_t event)
522{
523 /// Load event if different from the current one.
e8636ba0 524 /// Returns kFALSE on error and kTRUE if the event was loaded.
525
526 assert( IsValid() );
527
528 AliDebug(1,Form("Loading event %d using runLoader %p",event,fLoader->GetRunLoader()));
529 if (fLoader->GetRunLoader()->GetEvent(event) == 0)
e9bef706 530 {
531 fCurrentEvent = event;
e8636ba0 532 return kTRUE;
e9bef706 533 }
e8636ba0 534 else
535 return kFALSE;
1df4a03e 536}
537
e9bef706 538
1df4a03e 539//_____________________________________________________________________________
540Int_t
541AliMUONMCDataInterface::NumberOfEvents() const
542{
543 /// Number of events in the file we're connected to
e8636ba0 544 if (not IsValid()) return -1;
e9bef706 545 return fLoader->GetRunLoader()->GetNumberOfEvents();
1df4a03e 546}
547
548//_____________________________________________________________________________
549Int_t
e9bef706 550AliMUONMCDataInterface::NumberOfTracks(Int_t event)
1df4a03e 551{
552 /// Number of tracks in the event
e8636ba0 553 if ( not IsValid()) return -1;
1df4a03e 554
e8636ba0 555 if (event != fCurrentEvent)
556 {
557 ResetStores();
558 if ( not LoadEvent(event) ) return -1;
559 }
e9bef706 560
561 fLoader->LoadHits();
1df4a03e 562
e8636ba0 563 Int_t rv(-1);
1df4a03e 564
e9bef706 565 TTree* treeH = fLoader->TreeH();
e8636ba0 566 if (treeH != 0x0)
1df4a03e 567 {
e9bef706 568 rv = static_cast<Int_t>(treeH->GetEntries());
1df4a03e 569 }
570 else
571 {
572 AliError("Could not get TreeH");
573 }
574
e9bef706 575 fLoader->UnloadHits();
1df4a03e 576
577 return rv;
578}
579
580//_____________________________________________________________________________
581Int_t
e9bef706 582AliMUONMCDataInterface::NumberOfTrackRefs(Int_t event)
1df4a03e 583{
584 /// Number of track references in the event
e8636ba0 585 if ( not IsValid()) return -1;
1df4a03e 586
e8636ba0 587 if (event != fCurrentEvent)
588 {
589 ResetStores();
590 if ( not LoadEvent(event) ) return -1;
591 }
e9bef706 592
593 fLoader->GetRunLoader()->LoadTrackRefs();
1df4a03e 594
e8636ba0 595 Int_t rv(-1);
1df4a03e 596
e9bef706 597 TTree* treeTR = fLoader->GetRunLoader()->TreeTR();
e8636ba0 598 if (treeTR != 0x0)
1df4a03e 599 {
e9bef706 600 rv = static_cast<Int_t>(treeTR->GetEntries());
1df4a03e 601 }
602 else
603 {
604 AliError("Could not get TreeTR");
605 }
606
e9bef706 607 fLoader->GetRunLoader()->UnloadTrackRefs();
1df4a03e 608
609 return rv;
610}
611
612//_____________________________________________________________________________
e9bef706 613void
614AliMUONMCDataInterface::Open(const char* filename)
615{
616 /// Connect to a given galice.root file
617
e8636ba0 618 ResetStores();
e9bef706 619
620 fCurrentEvent=-1;
621
e8636ba0 622 if ( fLoader != 0x0 )
e9bef706 623 {
624 delete fLoader->GetRunLoader();
625 }
626
627 fLoader = 0x0;
628
629 fIsValid = kTRUE;
630
631 TString foldername(Form("%s-%d",ClassName(),fgInstanceCounter));
632
633 while (AliRunLoader::GetRunLoader(foldername))
634 {
635 delete AliRunLoader::GetRunLoader(foldername);
636 }
637
638 AliRunLoader* runLoader = AliRunLoader::Open(filename,foldername);
e8636ba0 639 if (runLoader == 0x0)
e9bef706 640 {
641 AliError(Form("Cannot open file %s",filename));
642 fIsValid = kFALSE;
fc2293be 643 return;
e9bef706 644 }
aa73f8fb 645
646 // Get run number and set it to CDB manager
647 runLoader->LoadHeader();
648 if ( ! runLoader->GetHeader() ) {
649 AliError("Cannot load header.");
650 fIsValid = kFALSE;
651 }
652 else {
653 Int_t runNumber = runLoader->GetHeader()->GetRun();
654 AliCDBManager::Instance()->SetRun(runNumber);
655 }
656 runLoader->UnloadHeader();
657
e9bef706 658 fLoader = runLoader->GetDetectorLoader("MUON");
e8636ba0 659 if (fLoader == 0x0)
e9bef706 660 {
661 AliError("Cannot get AliMUONLoader");
662 fIsValid = kFALSE;
663 }
664
e8636ba0 665 if (not IsValid())
e9bef706 666 {
667 AliError(Form("Could not access %s filename. Object is unuseable",filename));
668 }
669}
670
671//_____________________________________________________________________________
e8636ba0 672Bool_t AliMUONMCDataInterface::GetEvent(Int_t event)
e9bef706 673{
e8636ba0 674/// Loads all simulated data for the given event.
675
676 if (HitStore(event, 0) == 0x0) return kFALSE;
677 if (SDigitStore(event) == 0x0) return kFALSE;
678 if (DigitStore(event) == 0x0) return kFALSE;
679 if (TriggerStore(event) == 0x0) return kFALSE;
680 if (TrackRefs(event, 0) == 0x0) return kFALSE;
681 return kTRUE;
682}
683
684//_____________________________________________________________________________
685Int_t AliMUONMCDataInterface::NumberOfParticles()
686{
687/// Returns the total number of particles in the kinematics tree.
688
689 AliStack* stack = Stack(fCurrentEvent);
690 if ( stack == 0x0 ) return -1;
691 return (Int_t) stack->GetNtrack();
692}
693
694//_____________________________________________________________________________
695TParticle* AliMUONMCDataInterface::Particle(Int_t index)
696{
697/// Returns the index'th particle in the kinematics tree.
698/// @param index The index number of the particle in the range [0 ... N-1]
699/// where N = NumberOfParticles()
700
701 AliStack* stack = Stack(fCurrentEvent);
702 if ( stack == 0x0 ) return 0x0;
703 return static_cast<TParticle*>( stack->Particle(index) );
704}
705
706//_____________________________________________________________________________
707Int_t AliMUONMCDataInterface::NumberOfTracks()
708{
709/// Returns the number of primary tracks (from primary particles) in the current event.
710
711 return NumberOfTracks(fCurrentEvent);
712}
713
714//_____________________________________________________________________________
715Int_t AliMUONMCDataInterface::NumberOfHits(Int_t track)
716{
717/// Returns the number of hits for a given primary track/particle.
718/// @param track The track number in the range [0 .. N-1]
719/// where N = NumberOfTracks()
720
721 TIterator* iter = GetIterator(kHitIterator, track);
722 return CountObjects(iter);
723}
724
725//_____________________________________________________________________________
726AliMUONHit*
727AliMUONMCDataInterface::Hit(Int_t track, Int_t index)
728{
729/// Returns a pointer to the index'th hit object.
730/// @param track The track number in the range [0 .. N-1]
731/// where N = NumberOfTracks()
732/// @param index The index number of the hit in the range [0 ... M-1]
733/// where M = NumberOfHits(track)
734
735 TIterator* iter = GetIterator(kHitIterator, track);
736 return static_cast<AliMUONHit*>( FetchObject(iter, index) );
737}
738
739//_____________________________________________________________________________
740Int_t AliMUONMCDataInterface::NumberOfSDigits(Int_t detElemId)
741{
742/// Returns the number of summable digits to be found on a given detector element.
743/// @param detElemId The detector element ID number to search on.
744
745 TIterator* iter = GetIterator(kSDigitIteratorByDetectorElement, detElemId);
746 return CountObjects(iter);
747}
748
749//_____________________________________________________________________________
750AliMUONVDigit* AliMUONMCDataInterface::SDigit(Int_t detElemId, Int_t index)
751{
752/// Returns the a pointer to the index'th summable digit on the specified detector element.
753/// @param detElemId The detector element ID number to search on.
754/// @param index The index number of the digit to fetch in the range [0 .. N-1],
755/// where N = NumberOfDigits(detElemId)
756
757 TIterator* iter = GetIterator(kSDigitIteratorByDetectorElement, detElemId);
758 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
759}
760
761//_____________________________________________________________________________
762Int_t AliMUONMCDataInterface::NumberOfSDigits(Int_t chamber, Int_t cathode)
763{
764/// Returns the number of summable digits to be found on a specific chamber and cathode.
765/// @param chamber The chamber number in the range [0 .. 13].
766/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
767/// 1 is the non-bending plane.
768
769 TIterator* iter = GetIterator(kSDigitIteratorByChamberAndCathode, chamber, cathode);
770 return CountObjects(iter);
771}
772
773//_____________________________________________________________________________
774AliMUONVDigit* AliMUONMCDataInterface::SDigit(Int_t chamber, Int_t cathode, Int_t index)
775{
776/// Returns the a pointer to the index'th summable digit on the specified chamber and cathode.
777/// @param chamber The chamber number in the range [0 .. 13].
778/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
779/// 1 is the non-bending plane.
780/// @param index The index number of the digit to fetch in the range [0 .. N-1],
781/// where N = NumberOfDigits(chamber, cathode)
782
783 TIterator* iter = GetIterator(kSDigitIteratorByChamberAndCathode, chamber, cathode);
784 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
785}
786
787//_____________________________________________________________________________
788Int_t AliMUONMCDataInterface::NumberOfDigits(Int_t detElemId)
789{
790/// Returns the number of simulated digits to be found on a given detector element.
791/// @param detElemId The detector element ID number to search on.
792
793 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
794 return CountObjects(iter);
795}
796
797//_____________________________________________________________________________
798AliMUONVDigit* AliMUONMCDataInterface::Digit(Int_t detElemId, Int_t index)
799{
800/// Returns the a pointer to the index'th simulated digit on the specified detector element.
801/// @param detElemId The detector element ID number to search on.
802/// @param index The index number of the digit to fetch in the range [0 .. N-1],
803/// where N = NumberOfDigits(detElemId)
804
805 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
806 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
807}
808
809//_____________________________________________________________________________
810Int_t AliMUONMCDataInterface::NumberOfDigits(Int_t chamber, Int_t cathode)
811{
812/// Returns the number of simulated digits to be found on a specific chamber and cathode.
813/// @param chamber The chamber number in the range [0 .. 13].
814/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
815/// 1 is the non-bending plane.
816
817 TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
818 return CountObjects(iter);
819}
820
821//_____________________________________________________________________________
822AliMUONVDigit* AliMUONMCDataInterface::Digit(Int_t chamber, Int_t cathode, Int_t index)
823{
824/// Returns the a pointer to the index'th simulated digit on the specified chamber and cathode.
825/// @param chamber The chamber number in the range [0 .. 13].
826/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
827/// 1 is the non-bending plane.
828/// @param index The index number of the digit to fetch in the range [0 .. N-1],
829/// where N = NumberOfDigits(chamber, cathode)
830
831 TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
832 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
833}
834
835//_____________________________________________________________________________
836Int_t AliMUONMCDataInterface::NumberOfLocalTriggers()
837{
838/// Returns the number of simulated local trigger objects.
839
840 TIterator* iter = GetIterator(kLocalTriggerIterator);
841 return CountObjects(iter);
842}
843
844//_____________________________________________________________________________
845AliMUONLocalTrigger* AliMUONMCDataInterface::LocalTrigger(Int_t index)
846{
847/// Returns a pointer to the index'th simulated local trigger object.
848/// @param index The index number of the local trigger object to fetch in the range [0 .. N-1],
849/// where N = NumberOfLocalTriggers()
850
851 TIterator* iter = GetIterator(kLocalTriggerIterator);
852 return static_cast<AliMUONLocalTrigger*>( FetchObject(iter, index) );
853}
854
855//_____________________________________________________________________________
856Int_t AliMUONMCDataInterface::NumberOfRegionalTriggers()
857{
858/// Returns the number of simulated regional trigger objects.
859
860 TIterator* iter = GetIterator(kRegionalTriggerIterator);
861 return CountObjects(iter);
862}
863
864//_____________________________________________________________________________
865AliMUONRegionalTrigger* AliMUONMCDataInterface::RegionalTrigger(Int_t index)
866{
867/// Returns a pointer to the index'th simulated regional trigger object.
868/// @param index The index number of the regional trigger object to fetch in the range [0 .. N-1],
869/// where N = NumberOfRegionalTriggers()
870
871 TIterator* iter = GetIterator(kRegionalTriggerIterator);
872 return static_cast<AliMUONRegionalTrigger*>( FetchObject(iter, index) );
873}
874
875//_____________________________________________________________________________
876AliMUONGlobalTrigger* AliMUONMCDataInterface::GlobalTrigger()
877{
878/// Returns a pointer to the simulated global trigger object for the event.
879
880 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
881 if (store == 0x0) return 0x0;
882 return store->Global();
883}
884
885//_____________________________________________________________________________
886Int_t AliMUONMCDataInterface::NumberOfTrackRefs()
887{
888/// Number of track references in the currently selected event.
889
890 return NumberOfTrackRefs(fCurrentEvent);
891}
892
893//_____________________________________________________________________________
894TClonesArray* AliMUONMCDataInterface::TrackRefs(Int_t track)
895{
896/// Returns the track references for a given track in the current event.
897/// @param track The track to returns track references for. In the range [0 .. N-1]
898/// where N = NumberOfTrackRefs()
899
900 return TrackRefs(fCurrentEvent, track);
901}
902
903//_____________________________________________________________________________
904void AliMUONMCDataInterface::ResetStores()
905{
906/// Deletes all the store objects that have been created and resets the pointers to 0x0.
907/// The temporary iterator object is automatically reset. See ResetIterator for more details.
908
909 ResetIterator();
910 if (fHitStore != 0x0)
e9bef706 911 {
e8636ba0 912 delete fHitStore;
913 fHitStore = 0x0;
e9bef706 914 }
e8636ba0 915 if (fSDigitStore != 0x0)
916 {
917 delete fSDigitStore;
918 fSDigitStore = 0x0;
919 }
920 if (fDigitStore != 0x0)
921 {
922 delete fDigitStore;
923 fDigitStore = 0x0;
924 }
925 if (fTrackRefs != 0x0)
e9bef706 926 {
e8636ba0 927 delete fTrackRefs;
928 fTrackRefs = 0x0;
e9bef706 929 }
e8636ba0 930 if (fTriggerStore != 0x0)
931 {
932 delete fTriggerStore;
933 fTriggerStore = 0x0;
934 }
935}
936
937//_____________________________________________________________________________
938TIterator* AliMUONMCDataInterface::GetIterator(IteratorType type, Int_t x, Int_t y)
939{
940/// Creates an appropriate iterator object and returns it.
941/// If the iterator has already been created then that one is returned otherwise
942/// a new object is created.
943/// Depending on the value of 'type' the semantics of parameters x and y can change.
944/// @param type The type of iterator to create.
945/// @param x This is the detector element ID if type equals kDigitIteratorByDetectorElement
946/// or kSDigitIteratorByDetectorElement.
947/// If type equals kDigitIteratorByChamberAndCathode or
948/// kSDigitIteratorByChamberAndCathode then this is the chamber number.
949/// For type == kHitIterator the parameter x is the track number.
950/// In all other cases this parameter is ignored.
951/// @param y If type equals kDigitIteratorByChamberAndCathode or
952/// kSDigitIteratorByChamberAndCathode then this parameter is the cathode
953/// number. In all other cases this parameter is ignored.
954
955 if (type == fCurrentIteratorType and fDataX == x and fDataY == y)
956 return fIterator;
e9bef706 957
e8636ba0 958 if (fCurrentEvent == -1)
e9bef706 959 {
e8636ba0 960 AliError("No event was selected. Try first using GetEvent().");
961 return 0x0;
e9bef706 962 }
963
e8636ba0 964 ResetIterator();
e9bef706 965
e8636ba0 966 switch (type)
967 {
968 case kHitIterator:
969 {
970 Int_t track = x;
971 AliMUONVHitStore* store = HitStore(fCurrentEvent, track);
972 if (store == 0x0) return 0x0;
973 fIterator = store->CreateIterator();
974 if (fIterator == 0x0) return 0x0;
975 fCurrentIteratorType = kHitIterator;
976 return fIterator;
977 }
978
979 case kSDigitIteratorByDetectorElement:
980 {
981 Int_t detElem = x;
982 AliMUONVDigitStore* store = SDigitStore(fCurrentEvent);
983 if (store == 0x0) return 0x0;
e8636ba0 984 fIterator = store->CreateIterator(detElem, detElem, 2);
985 if (fIterator == 0x0) return 0x0;
986 fCurrentIteratorType = kSDigitIteratorByDetectorElement;
987 fDataX = detElem;
988 return fIterator;
989 }
990
991 case kSDigitIteratorByChamberAndCathode:
992 {
993 Int_t chamber = x;
994 Int_t cathode = y;
995 if (chamber < 0 or AliMpConstants::NofChambers() <= chamber)
996 {
997 AliError(Form(
998 "Must have give a chamber value in the range [0..%d], but got a value of: %d",
999 AliMpConstants::NofChambers() - 1,
1000 chamber
1001 ));
1002 return 0x0;
1003 }
1004 if (cathode < 0 or 1 < cathode)
1005 {
1006 AliError(Form("Must have give a cathode value in the range [0..1], but got a value of: %d", cathode));
1007 return 0x0;
1008 }
1009
1010 AliMUONVDigitStore* store = SDigitStore(fCurrentEvent);
1011 if (store == 0x0) return 0x0;
168e9c4d 1012 MpPair_t pair = AliMpDEManager::GetDetElemIdRange(chamber);
1013 fIterator = store->CreateIterator(AliMp::PairFirst(pair), AliMp::PairSecond(pair), cathode);
e8636ba0 1014 if (fIterator == 0x0) return 0x0;
1015 fCurrentIteratorType = kSDigitIteratorByChamberAndCathode;
1016 fDataX = chamber;
1017 fDataY = cathode;
1018 return fIterator;
1019 }
1020
1021 case kDigitIteratorByDetectorElement:
1022 {
1023 Int_t detElem = x;
1024 AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
1025 if (store == 0x0) return 0x0;
e8636ba0 1026 fIterator = store->CreateIterator(detElem, detElem, 2);
1027 if (fIterator == 0x0) return 0x0;
1028 fCurrentIteratorType = kDigitIteratorByDetectorElement;
1029 fDataX = detElem;
1030 return fIterator;
1031 }
1032
1033 case kDigitIteratorByChamberAndCathode:
1034 {
1035 Int_t chamber = x;
1036 Int_t cathode = y;
1037 if (chamber < 0 or AliMpConstants::NofChambers() <= chamber)
1038 {
1039 AliError(Form(
1040 "Must have give a chamber value in the range [0..%d], but got a value of: %d",
1041 AliMpConstants::NofChambers() - 1,
1042 chamber
1043 ));
1044 return 0x0;
1045 }
1046 if (cathode < 0 or 1 < cathode)
1047 {
1048 AliError(Form("Must have give a cathode value in the range [0..1], but got a value of: %d", cathode));
1049 return 0x0;
1050 }
1051
1052 AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
1053 if (store == 0x0) return 0x0;
168e9c4d 1054 MpPair_t pair = AliMpDEManager::GetDetElemIdRange(chamber);
1055 fIterator = store->CreateIterator(AliMp::PairFirst(pair), AliMp::PairSecond(pair), cathode);
e8636ba0 1056 if (fIterator == 0x0) return 0x0;
1057 fCurrentIteratorType = kDigitIteratorByChamberAndCathode;
1058 fDataX = chamber;
1059 fDataY = cathode;
1060 return fIterator;
1061 }
1062
1063 case kLocalTriggerIterator:
1064 {
1065 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
1066 if (store == 0x0) return 0x0;
1067 fIterator = store->CreateLocalIterator();
1068 if (fIterator == 0x0) return 0x0;
1069 fCurrentIteratorType = kLocalTriggerIterator;
1070 return fIterator;
1071 }
1072
1073 case kRegionalTriggerIterator:
1074 {
1075 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
1076 if (store == 0x0) return 0x0;
1077 fIterator = store->CreateRegionalIterator();
1078 if (fIterator == 0x0) return 0x0;
1079 fCurrentIteratorType = kRegionalTriggerIterator;
1080 return fIterator;
1081 }
1082
1083 default:
1084 return 0x0;
1085 }
e9bef706 1086}
1087
1088//_____________________________________________________________________________
e8636ba0 1089void AliMUONMCDataInterface::ResetIterator()
1df4a03e 1090{
e8636ba0 1091/// The temporary iterator object is deleted if it exists and the pointer reset to 0x0.
1092/// The iterator type and temporary data indicating the state of the iterator are
1093/// also reset.
1df4a03e 1094
e8636ba0 1095 if (fIterator != 0x0) delete fIterator;
1096 fCurrentIteratorType = kNoIterator;
1097 fCurrentIndex = fDataX = fDataY = -1;
1098 fIterator = 0x0;
1df4a03e 1099}
1100
1101//_____________________________________________________________________________
e8636ba0 1102Int_t AliMUONMCDataInterface::CountObjects(TIterator* iter)
1df4a03e 1103{
e8636ba0 1104/// Counts the number of objects in the iterator and resets it.
1105/// @return The number of objects in 'iter'.
e9bef706 1106
e8636ba0 1107 if (iter == 0x0) return -1;
1108 Int_t count = 0;
1109 iter->Reset();
1110 while ( iter->Next() != 0x0 ) count++;
1111 iter->Reset();
1112 fCurrentIndex = -1;
1113 return count;
e9bef706 1114}
1115
1116//_____________________________________________________________________________
e8636ba0 1117TObject* AliMUONMCDataInterface::FetchObject(TIterator* iter, Int_t index)
e9bef706 1118{
e8636ba0 1119/// Fetches the index'th object from the iterator counting the first object
1120/// returned by iterator after it is reset as index == 0. The next object
1121/// has index == 1 and so on where the last object returned by the iterator
1122/// has index == N-1 where N = CountObjects(iter)
1123/// This method will only reset the iterator if index is smaller than
1124/// fCurrentIndex, which is used to track the iteration progress and is
1125/// updated when a new object if returned by this method.
1126/// @param iter The iterator to fetch an object from.
1127/// @param index The index number of the object to fetch in the range [0 .. N-1]
1128/// where N = CountObjects(iter)
1129
1130 if (index < 0)
e9bef706 1131 {
e8636ba0 1132 AliError(Form("Index is out of bounds. Got a value of %d.", index));
e9bef706 1133 return 0x0;
1134 }
e8636ba0 1135
1136 if (iter == 0x0) return 0x0;
1137 if (index <= fCurrentIndex)
e9bef706 1138 {
e8636ba0 1139 iter->Reset();
1140 fCurrentIndex = -1;
e9bef706 1141 }
1142
e8636ba0 1143 TObject* object = 0x0;
1144 while (fCurrentIndex < index)
e9bef706 1145 {
e8636ba0 1146 object = iter->Next();
1147 if (object == 0x0)
1148 {
1149 AliError(Form("Index is out of bounds. Got a value of %d.", index));
1150 iter->Reset();
1151 fCurrentIndex = -1;
1152 return 0x0;
1153 }
1154 fCurrentIndex++;
e9bef706 1155 }
e8636ba0 1156 return object;
1df4a03e 1157}