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