- Class description on 5 lines (Coding conventions)
[u/mrichter/AliRoot.git] / MUON / AliMUONClusterReconstructor.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 AliMUONClusterReconstructor
20 // ----------------------------------
21 // MUON cluster reconstructor for MUON
22 // Should implement a virtual class ClusterFinder to choose between VS and AZ method
23
24 #include "AliMUONClusterReconstructor.h"
25 #include "AliRun.h" // for gAlice
26 #include "AliRunLoader.h"
27 #include "AliLoader.h"
28
29 #include "AliMUON.h"
30 #include "AliMUONDigit.h"
31 #include "AliMUONConstants.h"
32 #include "AliMUONData.h"
33 #include "AliMUONClusterFinderVS.h"
34 #include "AliMUONClusterInput.h"
35 #include "AliMUONRawCluster.h"
36 #include "AliLog.h"
37
38 ClassImp(AliMUONClusterReconstructor) // Class implementation in ROOT context
39  
40 //__________________________________________________________________________
41 AliMUONClusterReconstructor::AliMUONClusterReconstructor(AliMUONData* data)
42 : TObject(),
43   fMUONData(data),
44   fRecModel(new AliMUONClusterFinderVS()),
45   fDigitsCath0(new TClonesArray("AliMUONDigit",1000)),
46   fDigitsCath1(new TClonesArray("AliMUONDigit",1000))
47 {
48 /// Standard Constructor
49
50   fDigitsCath0->SetOwner(kTRUE); 
51   fDigitsCath1->SetOwner(kTRUE);
52 }
53
54 //_______________________________________________________________________
55 AliMUONClusterReconstructor::AliMUONClusterReconstructor (const AliMUONClusterReconstructor& rhs)
56   : TObject(rhs)
57 {
58 /// Protected copy constructor
59
60   AliFatal("Not implemented.");
61 }
62
63 //_______________________________________________________________________
64 AliMUONClusterReconstructor & 
65 AliMUONClusterReconstructor::operator=(const AliMUONClusterReconstructor& rhs)
66 {
67 /// Protected assignement operator
68
69   if (this == &rhs) return *this;
70
71   AliFatal("Not implemented.");
72     
73   return *this;  
74 }
75
76 //__________________________________________________________________________
77 AliMUONClusterReconstructor::~AliMUONClusterReconstructor(void)
78 {
79 /// Destructor
80
81   delete fRecModel;
82   delete fDigitsCath0;
83   delete fDigitsCath1;
84 }
85
86 //______________________________________________________________________________
87 void
88 AliMUONClusterReconstructor::CheckSize(TClonesArray& a)
89 {
90 /// Check if one can adds a new element, or if a is already full.
91 /// If full, it is resized.
92
93   if ( a.GetLast()+1 >= a.GetSize() )
94   {
95     AliInfo(Form("Increasing array size from %d to %d",
96                  a.GetSize(),a.GetSize()*2));
97     a.Expand(a.GetSize()*2);
98   }
99 }
100
101 //______________________________________________________________________________
102 void
103 AliMUONClusterReconstructor::ClusterizeOneDE(Int_t detElemId)
104 {
105 /// Clusterize one detection element, and let fMUONData know about
106 /// the results.
107   
108   if ( fDigitsCath0->GetEntriesFast() || fDigitsCath1->GetEntriesFast() )
109   {
110     Int_t iChamber = detElemId/100 - 1;
111     AliMUONClusterInput::Instance()->SetDigits(iChamber, detElemId,
112                                                fDigitsCath0,fDigitsCath1);
113     AliDebug(3,Form("ClusterizeOneDE iChamber=%d DE=%d",iChamber,detElemId));
114     StdoutToAliDebug(3,cout << "DigitsCath0=" << endl;
115                      fDigitsCath0->Print();
116                      cout << "DigitsCath1=" << endl;
117                      fDigitsCath1->Print(););
118     fRecModel->FindRawClusters();
119     
120     // copy results into the output container
121     TClonesArray* tmp = fRecModel->GetRawClusters();
122     for (Int_t id = 0; id < tmp->GetEntriesFast(); ++id) 
123     {
124       AliMUONRawCluster* pClus = (AliMUONRawCluster*) tmp->At(id);
125       fMUONData->AddRawCluster(iChamber, *pClus);
126     }        
127     
128     // Reset the arrays
129     fDigitsCath0->Clear("C");
130     fDigitsCath1->Clear("C");
131   }
132 }
133
134 //____________________________________________________________________
135 void AliMUONClusterReconstructor::Digits2Clusters(Int_t chBeg)
136 {
137 /// Clusterize all the tracking chamber digits.
138 ///
139 /// For each chamber, we loop *once* on that chamber digits, and store them
140 /// in 2 temporary arrays (one pair of arrays per detection element, 
141 /// one array per cathode). Once a pair of arrays is full (i.e. all the digits
142 /// of that detection element have been stored), we clusterize this DE, and
143 /// move to the next one.
144   
145   if (!fRecModel)
146   {
147     AliWarning("No reco model defined. Nothing to do...");
148     return;
149   }
150   
151   Int_t iChamber(-1);
152   Int_t currentDE(-1);
153   
154   // Loop on chambers 
155   for ( iChamber = chBeg; iChamber < AliMUONConstants::NTrackingCh(); ++iChamber ) 
156   {
157     TClonesArray* muonDigits = fMUONData->Digits(iChamber); 
158     
159     Int_t ndig = muonDigits->GetEntriesFast();
160     if (!ndig) continue;
161     
162     muonDigits->Sort(); // the sort *must* be per DE (at least), otherwise
163                         // the following logic with currentDE will fail.
164     
165     currentDE = -1; // initialize the DE counter (that is used to track 
166                     // when we change of DE in the following loop over
167                     // all digits) to an invalid value.
168
169     for ( Int_t k = 0; k < ndig; ++k ) 
170     {
171       AliMUONDigit* digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
172       if ( ! digit->Signal() > 0 ) continue; // skip void digits.
173       
174       if ( digit->DetElemId() != currentDE )
175       {
176         AliDebug(3,Form("Switching DE from %d to %d",currentDE,digit->DetElemId()));
177         // we get to a new DE, so clusterize the previous one before
178         // moving on.
179         ClusterizeOneDE(currentDE);
180         currentDE = digit->DetElemId();
181       }
182       
183       // Add the digit to the array with the right cathode number.
184       if (digit->Cathode() == 0)
185       {
186         CheckSize(*fDigitsCath0);
187         new((*fDigitsCath0)[fDigitsCath0->GetLast()+1]) AliMUONDigit(*digit);
188       }
189       else 
190       {
191         CheckSize(*fDigitsCath1);
192         new((*fDigitsCath1)[fDigitsCath1->GetLast()+1]) AliMUONDigit(*digit);
193       }
194     } // end of loop on chamber digits
195     
196     // As the above logic is based on detecting a change in DE number,
197     // the last DE of each chamber has not been clusterized, so we do 
198     // it here.
199     ClusterizeOneDE(currentDE);
200   } // end of loop over chambers
201 }
202
203 //_______________________________________________________________________
204 void 
205 AliMUONClusterReconstructor::SetRecoModel(AliMUONClusterFinderVS* rec)
206
207 /// Set reconstruction model
208
209   delete fRecModel; 
210   fRecModel = rec;
211
212
213 //_______________________________________________________________________
214 void AliMUONClusterReconstructor::Trigger2Trigger() 
215 {
216 /// Copy trigger from TreeD to TreeR
217
218   fMUONData->SetTreeAddress("GLT");
219   fMUONData->GetTriggerD();
220 }