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