0402675cd0d44bbfc75ccbc4b68938b27fa5920c
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinder.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 #include "AliITSClusterFinder.h"
17 #include "AliITSdigit.h"
18 #include "AliRun.h"
19 #include "AliITS.h"
20
21 ClassImp(AliITSClusterFinder)
22
23 //----------------------------------------------------------------------
24 AliITSClusterFinder::AliITSClusterFinder(){
25     // default cluster finder
26
27     fSegmentation = 0;
28     fResponse     = 0;
29     fMap          = 0;
30     fDigits       = 0;
31     fNdigits      = 0;
32     fNRawClusters = 0;
33     fNperMax      = 0;
34     fDeclusterFlag= 0;
35     fClusterSize  = 0;
36     fNPeaks       = 0;
37 }
38 //----------------------------------------------------------------------
39 AliITSClusterFinder::AliITSClusterFinder(AliITSsegmentation *seg, 
40                                          AliITSresponse *response, 
41                                          TClonesArray *digits){
42   // cluster finder
43     fSegmentation=seg;
44     fResponse=response;
45     fMap = 0;
46     
47     fDigits=digits;
48     fNdigits = fDigits->GetEntriesFast();
49
50     fNRawClusters=0;
51
52     SetNperMax();
53     SetClusterSize();
54     SetDeclusterFlag();
55
56     fNPeaks=-1;
57 }
58 //----------------------------------------------------------------------
59 AliITSClusterFinder::~AliITSClusterFinder(){
60     // destructor cluster finder
61
62     // Zero local pointers. Other classes own these pointers.
63     fSegmentation = 0;
64     fResponse     = 0;
65     fMap          = 0;
66     fDigits       = 0;
67     fNdigits      = 0;
68     fNRawClusters = 0;
69     fNperMax      = 0;
70     fDeclusterFlag= 0;
71     fClusterSize  = 0;
72     fNPeaks       = 0;
73 }
74 //__________________________________________________________________________
75 AliITSClusterFinder::AliITSClusterFinder(const AliITSClusterFinder &source){
76     //     Copy Constructor 
77     if(&source == this) return;
78     this->fDigits = source.fDigits;
79     this->fNdigits = source.fNdigits;
80     this->fResponse = source.fResponse;
81     this->fSegmentation = source.fSegmentation;
82     this->fNRawClusters = source.fNRawClusters;
83     this->fMap = source.fMap;
84     this->fNperMax = source.fNperMax;
85     this->fDeclusterFlag = source.fDeclusterFlag;
86     this->fClusterSize = source.fClusterSize;
87     this->fNPeaks = source.fNPeaks;
88     return;
89 }
90 //______________________________________________________________________
91 AliITSClusterFinder& AliITSClusterFinder::operator=(const AliITSClusterFinder &source) {
92     //    Assignment operator
93
94     if(&source == this) return *this;
95     this->fDigits = source.fDigits;
96     this->fNdigits = source.fNdigits;
97     this->fResponse = source.fResponse;
98     this->fSegmentation = source.fSegmentation;
99     this->fNRawClusters = source.fNRawClusters;
100     this->fMap = source.fMap;
101     this->fNperMax = source.fNperMax;
102     this->fDeclusterFlag = source.fDeclusterFlag;
103     this->fClusterSize = source.fClusterSize;
104     this->fNPeaks = source.fNPeaks;
105     return *this;
106 }
107 //----------------------------------------------------------------------
108 void AliITSClusterFinder::AddCluster(Int_t branch, AliITSRawCluster *c){
109     // Add a raw cluster copy to the list
110
111     AliITS *iTS=(AliITS*)gAlice->GetModule("ITS");
112     iTS->AddCluster(branch,c); 
113     fNRawClusters++;
114 }
115 //----------------------------------------------------------------------
116 void AliITSClusterFinder::AddCluster(Int_t branch, AliITSRawCluster *c, 
117                                      AliITSRecPoint &rp){
118     // Add a raw cluster copy to the list
119
120     AliITS *iTS=(AliITS*)gAlice->GetModule("ITS");
121     iTS->AddCluster(branch,c); 
122     fNRawClusters++;
123     iTS->AddRecPoint(rp); 
124 }
125 //______________________________________________________________________
126 void AliITSClusterFinder::FindRawClusters(Int_t module){
127     // Default Cluster finder.
128     // Input:
129     //   Int_t module   Module number for which culster are to be found.
130     // Output:
131     //   none.
132     // Return:
133     //   none.
134     const Int_t kelms = 10;
135     Int_t ndigits = fDigits->GetEntriesFast();
136     TObjArray *digs = new TObjArray(ndigits);
137     TObjArray *clusts = new TObjArray(ndigits); // max # cluster
138     TObjArray *clust0=0; // A spacific cluster of digits
139     TObjArray *clust1=0; // A spacific cluster of digits
140     AliITSdigit *dig=0; // locat pointer to a digit
141     Int_t i=0,nc=0,j[4],k,k2;
142
143     // Copy all digits for this module into a local TObjArray.
144     for(i=0;i<ndigits;i++) digs->AddAt(new AliITSdigit(*((AliITSdigit*)(fDigits->At(i)))),i);
145     digs->Sort();
146     // First digit is a cluster.
147     i  = 0;
148     nc = 0;
149     clusts->AddAt(new TObjArray(kelms),nc);
150     clust0 = (TObjArray*)(clusts->At(nc));
151     clust0->AddAtFree(digs->At(i)); // move owner ship from digs to clusts
152     nc++;
153     for(i=1;i<ndigits;i++){
154         if(IsNeighbor(digs,i,j)){
155             dig = (AliITSdigit*)(digs->At(j[0]));
156             // Add to existing cluster. Find which cluster this digis 
157             for(k=0;k<nc;k++){
158                 clust0 = ((TObjArray*)(clusts->At(k)));
159                 if(clust0->IndexOf(dig)>=0) break;
160             } // end for k
161             if(k>=nc){
162                 Error("FindRawClusters","Digit not found as expected");
163                 abort();
164             } // end if
165             if(j[1]>=0){
166                 dig = (AliITSdigit*)(digs->At(j[1]));
167                 // Add to existing cluster. Find which cluster this digis 
168                 for(k2=0;k2<nc;k2++){
169                     clust1 = ((TObjArray*)(clusts->At(k2)));
170                     if(clust1->IndexOf(dig)>=0) break;
171                 } // end for k2
172                 if(k2>=nc){
173                     Error("FindRawClusters","Digit not found as expected");
174                     abort();
175                 } // end if
176             } // end if j[1]>=0
177             // Found cluster with neighboring digits add this one to it.
178             if(clust0==clust1){ // same cluster
179                 clust0->AddAtFree(digs->At(i));
180                 clust0 = 0; // finished with cluster. zero for safty
181                 clust1 = 0; // finished wit hcluster. zero for safty
182             }else{ // two different clusters which need to be merged.
183                 clust0->AddAtFree(digs->At(i)); // Add digit to this cluster.
184                 for(k=0;k<clust1->GetEntriesFast();k++){
185                     // move clust1 into clust0
186                     clust0->AddAtFree(clust1->At(k));//move digit to this cluster
187                     clust1->AddAt(0,k); // zero this one
188                 } // end for k
189                 delete clust1;
190                 clusts->AddAt(0,k2); // zero array of clusters element clust1
191                 clust0 = 0; // finished with cluster. zero for safty
192                 clust1 = 0; // finished wit hcluster. zero for safty
193             } // end if clust0==clust1
194         }else{// New cluster
195             clusts->AddAt(new TObjArray(kelms),nc);
196             clust0 = ((TObjArray*)(clusts->At(nc)));
197             clust0->AddAtFree(digs->At(i));// move owner ship from digs to clusts
198             clust0 = 0; // finished with cluster. zero for safty
199             nc++;
200         } // End if IsNeighbor
201     } // end for i
202     // There are now nc clusters in clusts. Each element of clust is an
203     // array of digits which are clustered together.
204
205     // For each cluster call detector specific CreateRecPoints
206     for(i=0;i<nc;i++) CreateRecPoints((TObjArray*)(clusts->At(i)),module);
207
208     // clean up at the end.
209     for(i=0;i<nc;i++){ 
210         clust0 =(TObjArray*)(clusts->At(i));
211         // Digits deleted below, so zero this TObjArray
212         for(k=0;k<clust0->GetEntriesFast();k++) clust0->AddAt(0,k);
213         delete clust0; // Delete this TObjArray
214         clusts->AddAt(0,i); // Contents deleted above, so zero it.
215     } // end for i
216     delete clusts; // Delete this TObjArray/
217     // Delete the digits then the TObjArray which containted them.
218     for(i=0;i<ndigits;i++) delete ((AliITSdigit*)(digs->At(i)));
219     delete digs;
220 }
221 //______________________________________________________________________
222 Bool_t AliITSClusterFinder::IsNeighbor(TObjArray *digs,Int_t i,Int_t n[]){
223     // Locagical function which checks to see if digit i has a neighbor.
224     // If so, then it returns kTRUE and its neighbor index j.
225     // This routine checks if the digits are side by side or one before the
226     // other. Requires that the array of digits be in proper order.
227     // Returns kTRUE in the following cases.
228     //                 ji   0j   if kdiagonal  j0    0i
229     //                 00   0i   if kdiagonal  0i    j0
230     // Inputs:
231     //    TObjArray *digs   Array to search for neighbors in
232     //    Int_t      i      Index of digit for which we are searching for
233     //                      a neighbor of.
234     // Output:
235     //    Int_t      j[4]   Index of one or more of the digits which is a
236     //                      neighbor of digit a index i.
237     // Return:
238     //    Bool_t            kTRUE if a neighbor was found kFALSE otherwise.
239     Int_t ix,jx,iz,jz,j;
240     const Bool_t kdiagonal=kFALSE;
241     Bool_t nei[4];
242
243     // No neighbors found if array empty.
244     if(digs->GetEntriesFast()<=0) return kFALSE;
245     // can not be a digit with first element or elements out or range
246     if(i<=0 || i>=digs->GetEntriesFast()) return kFALSE;
247
248     for(j=0;j<4;j++){n[j] = -1;nei[j]=kFALSE;}
249     ix = ((AliITSdigit*)(digs->At(i)))->GetCoord1();
250     iz = ((AliITSdigit*)(digs->At(i)))->GetCoord2();
251     for(j=0;j<i;j++){
252         jx = ((AliITSdigit*)(digs->At(j)))->GetCoord1();
253         jz = ((AliITSdigit*)(digs->At(j)))->GetCoord2();
254         if(jx+1==ix && jz  ==iz){n[0] = j;nei[0] = kTRUE;}
255         if(jx  ==ix && jz+1==iz){n[1] = j;nei[1] = kTRUE;}
256         if(jx+1==ix && jz+1==iz){n[2] = j;nei[2] = kTRUE;}
257         if(jx+1==ix && jz-1==iz){n[3] = j;nei[3] = kTRUE;}
258     } // end for k
259     if(nei[0]||nei[1]) return kTRUE;
260     if(kdiagonal&&(nei[2]||nei[3])) return kTRUE;
261     // no Neighbors found.
262     return kFALSE;
263 }