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