Correct formula for phi, in case of current local X <0, in GetLocalXat and GetPhiZat
[u/mrichter/AliRoot.git] / ITS / AliITSclusterSSD.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 //Piotr Krzysztof Skowronski                                              //
19 //Warsaw University of Technology                                         // 
20 //skowron@if.pw.edu.pl                                                    //
21 //                                                                        // 
22 // Describes set of neighbouring digits on one side of detector,          //
23 // that are supposed to be generated by one particle.                     //
24 // includes information about clusters on other side that it crosses with //
25 ////////////////////////////////////////////////////////////////////////////
26
27 #include <TArrayI.h>
28 #include <TMath.h>
29 #include <TClonesArray.h>
30
31
32 #include "AliITSdigitSSD.h"
33 #include "AliITSclusterSSD.h"
34
35 ClassImp(AliITSclusterSSD)
36
37 //______________________________________________________________________
38 AliITSclusterSSD::AliITSclusterSSD():
39 fSide(kTRUE),
40 fDigits(0),
41 fNDigits(0),
42 fDigitsIndex(0),
43 fNCrosses(0),
44 fCrossedClusterIndexes(0),
45 fLeftNeighbour(kFALSE),
46 fRightNeighbour(kFALSE),
47 fConsumed(kFALSE),
48 fTotalSignal(-1),
49 fNTracks(-1){
50     // default constructor
51 }
52 //______________________________________________________________________
53 AliITSclusterSSD::AliITSclusterSSD(Int_t ndigits, Int_t *DigitIndexes, 
54                                    TObjArray *Digits, Bool_t side):
55 fSide(side),
56 fDigits(Digits),
57 fNDigits(ndigits),
58 fDigitsIndex(0),
59 fNCrosses(0),
60 fCrossedClusterIndexes(0),
61 fLeftNeighbour(kFALSE),
62 fRightNeighbour(kFALSE),
63 fConsumed(kFALSE),
64 fTotalSignal(-1),
65 fNTracks(-1){
66     // non-default constructor
67
68     fDigitsIndex = new TArrayI(fNDigits,DigitIndexes ); 
69     fCrossedClusterIndexes = new TArrayI(300);
70 }
71 //______________________________________________________________________
72 AliITSclusterSSD::~AliITSclusterSSD(){
73     // destructor
74
75     delete fDigitsIndex;
76     delete fCrossedClusterIndexes;
77 }
78 //______________________________________________________________________
79 AliITSclusterSSD::AliITSclusterSSD(const AliITSclusterSSD &OneSCluster) : 
80 TObject(OneSCluster),
81 fSide(OneSCluster.fSide),
82 fDigits(OneSCluster.fDigits),
83 fNDigits(OneSCluster.fNDigits),
84 fDigitsIndex(0),
85 fNCrosses(OneSCluster.fNCrosses),
86 fCrossedClusterIndexes(0),
87 fLeftNeighbour(OneSCluster.fLeftNeighbour),
88 fRightNeighbour(OneSCluster.fRightNeighbour),
89 fConsumed(OneSCluster.fConsumed),
90 fTotalSignal(-1),
91 fNTracks(-1){
92     // copy constructor
93
94     fDigitsIndex = new TArrayI(fNDigits);
95     fTotalSignal =-1;
96     fNTracks     = -1;
97     Int_t i;
98     for (i = 0; i< fNCrosses ; i++){
99         fCrossedClusterIndexes[i] = OneSCluster.fCrossedClusterIndexes[i];
100     }
101     for (i = 0; i< fNDigits ; i++){
102         fDigitsIndex[i]=OneSCluster.fDigitsIndex[i];
103     }
104     return;
105 }
106 //______________________________________________________________________
107 AliITSclusterSSD& AliITSclusterSSD::operator=(const AliITSclusterSSD 
108                                               &OneSCluster){
109     // assignment operator
110
111     if (this == &OneSCluster) return *this;
112     fNDigits = OneSCluster.fNDigits;
113     fSide=OneSCluster.fSide;
114     fDigits=OneSCluster.fDigits;
115     fDigitsIndex = new TArrayI(fNDigits);
116     fLeftNeighbour  = OneSCluster.fLeftNeighbour;
117     fRightNeighbour = OneSCluster.fRightNeighbour;
118     fTotalSignal =-1;
119     fNTracks     = -1;
120     fNCrosses = OneSCluster.fNCrosses;
121     fConsumed = OneSCluster.fConsumed;
122     Int_t i;
123     for (i = 0; i< fNCrosses ; i++){
124         fCrossedClusterIndexes[i] = OneSCluster.fCrossedClusterIndexes[i];
125     }
126     for (i = 0; i< fNDigits ; i++){
127         fDigitsIndex[i]=OneSCluster.fDigitsIndex[i];
128     }
129     return *this;
130 }
131 //______________________________________________________________________
132 Int_t AliITSclusterSSD::SplitCluster(Int_t where, Int_t *outdigits){
133     //This methods generate data necessery to make new object of this class
134     //I choosen this way, because methods TClonesArray::Add* dont work
135     //so I have to use constraction: new (a[i]) Creator(params...);
136     //where 'a' is a TClonesArray 
137     //This method generate params - see AliITSmoduleSSD::SplitCluster;
138     Int_t tmp = fNDigits;
139     Int_t ind = 0;
140
141     outdigits[ind++]=(*fDigitsIndex)[where];
142     //coping border strip (it is shared by this two clusters)
143     for (Int_t i = (where+1); i < tmp; i++) {
144         outdigits[ind++]=(*fDigitsIndex)[i];  
145         //"moving" strips from this to the new one 
146         (*fDigitsIndex)[i]=-1;   
147         fNDigits--;   //deleting strips from this cluster
148     } 
149     return ind;         
150 }
151 //______________________________________________________________________
152 Int_t AliITSclusterSSD::GetDigitStripNo(Int_t digit){
153     // return strip no of a digit
154     if (digit<0) return -1;
155     return (digit>(fNDigits-1)) ? -1 :
156         ((AliITSdigitSSD*)(fDigits->At((*fDigitsIndex)[digit])))->GetStripNumber();
157 }
158 //______________________________________________________________________
159 Int_t AliITSclusterSSD::GetDigitSignal(Int_t digit){
160     // returns digit signal
161     Int_t index,signal;
162     if (digit<0||digit>=fNDigits) return -1;
163     index  = (*fDigitsIndex)[digit];
164     signal = ((AliITSdigitSSD*)(fDigits->At(index)))->GetSignal();
165     /*
166       if(signal>1.e5) printf("GetDigitSignal: digit %d index %d signal %d\n",
167       digit,index, signal);
168     */
169     return  signal;
170 }
171 //______________________________________________________________________
172 void  AliITSclusterSSD::AddCross(Int_t clIndex){
173     // add cluster cross to list of cluster crosses
174   
175     (*fCrossedClusterIndexes)[fNCrosses++] = clIndex;
176 }
177 //______________________________________________________________________
178 Int_t AliITSclusterSSD::GetCross(Int_t crIndex) const {
179     // return crossing cluster
180
181     return ((crIndex>-1)&&(crIndex<fNCrosses))?(*fCrossedClusterIndexes)[crIndex]:-1;
182 }
183 //______________________________________________________________________
184 Double_t AliITSclusterSSD::CentrOfGravity(){
185     // return center of gravity of the cluster
186     Float_t ret=0;
187   
188     if (fLeftNeighbour) ret+=(GetDigitStripNo(0)*0.5*GetDigitSignal(0));
189     else ret+=(GetDigitStripNo(0)*GetDigitSignal(0));
190     if (fRightNeighbour) ret+=(GetDigitStripNo(fNDigits -1)*0.5*GetDigitSignal(fNDigits -1));
191     else ret+=(GetDigitStripNo(fNDigits -1)*GetDigitSignal(fNDigits-1));
192     for (Int_t i=1;i<fNDigits-1;i++){
193         ret +=GetDigitStripNo(i)*GetDigitSignal(i);
194     }// end for i
195   
196     if (fTotalSignal<0) GetTotalSignal();
197         
198     return (ret/fTotalSignal);
199 }
200 //______________________________________________________________________
201 Float_t AliITSclusterSSD::GetTotalSignal(){
202     // return total signal
203   
204     if(fTotalSignal <0){
205         fTotalSignal=0;
206         if (fNDigits ==1)  {
207             fTotalSignal = (Float_t)GetDigitSignal(0);
208             //printf("1 digit: signal %d \n",GetDigitSignal(0)); 
209             return fTotalSignal;
210         }
211         if (fLeftNeighbour) fTotalSignal += (Float_t)(0.5*GetDigitSignal(0));
212         else fTotalSignal += (Float_t) GetDigitSignal(0);
213         //printf("GetTotalSignal :i DigitSignal %d %d \n",0,GetDigitSignal(0));
214         if (fRightNeighbour) fTotalSignal += (Float_t)(0.5*GetDigitSignal(
215                                                                  fNDigits -1));
216       else fTotalSignal += (Float_t)GetDigitSignal(fNDigits-1);
217         //printf("GetTotalSignal :i  DigitSignal %d %d \n",fNDigits -1,GetDigitSignal(fNDigits -1));
218         for (Int_t i = 1;i<fNDigits -1;i++){
219             fTotalSignal += (Float_t)GetDigitSignal(i);
220             //printf("GetTotalSignal :i  DigitSignal %d %d \n",i,GetDigitSignal(i)); 
221         }
222         //printf("GetTotalSignal: fNDigits %d fTotalSignal %.0f \n",fNDigits,fTotalSignal); 
223     }
224     return fTotalSignal;
225 }
226 //______________________________________________________________________
227 Float_t  AliITSclusterSSD::GetTotalSignalError(){
228     // return the error on the signal
229     Float_t err =0;
230     for (Int_t i =1; i<fNDigits -1; i++){
231         err+=0.1*GetDigitSignal(i);   
232     } 
233     if (GetLeftNeighbour()){
234         err+=GetDigitSignal(0);
235     }else{
236         err+=0.1*GetDigitSignal(0);
237     } 
238     if (GetRightNeighbour()){
239         err+=GetDigitSignal(fNDigits -1);
240     }else{
241         err+=0.1*GetDigitSignal(fNDigits -1);
242     }
243     return err;
244 }
245 //______________________________________________________________________
246 void AliITSclusterSSD::DelCross(Int_t index){
247     // remove cross clusters from the list of cross clusters
248     Int_t i,j; //iterators
249
250     for (i =0;i<fNCrosses;i++){
251         if ((*fCrossedClusterIndexes)[i] == index){
252             for (j=i;j<fNCrosses-1;j++){
253                 (*fCrossedClusterIndexes)[j]=(*fCrossedClusterIndexes)[j+1];
254             }
255             fNCrosses--;
256             return; 
257         }
258     }
259 }
260 //______________________________________________________________________
261 Int_t  *AliITSclusterSSD::GetTracks(Int_t &nt){
262     // return the track number of the cluster
263     Int_t ntrk = GetDigit(0)->GetNTracks();
264     Int_t ndig = GetNumOfDigits();
265     Int_t *idig = new Int_t[ndig];
266     Int_t *sdig = new Int_t[ndig];
267     Int_t *itrk = new Int_t[ndig*ntrk];
268     Int_t i,j,k,l,trk;
269     Bool_t b;
270
271     for(i=0;i<ndig;i++){idig[i] = i;sdig[i] = GetDigit(i)->GetSignal();}
272     TMath::Sort(ndig,sdig,idig,kTRUE);
273     for(i=0;i<ndig*ntrk;i++) itrk[i] = -3;
274     j = k = l = 0;
275     for(i=0;i<ndig;i++){ // fill itrk with track numbers in order of digit size
276         j = idig[i];
277         for(k=0;k<ntrk;k++) if((trk = GetDigit(j)->GetTrack(k))>=0) {
278             itrk[l] = trk;
279             l++;
280         } // end for k/if
281     } // end for i
282     for(i=0;i<10;i++) fTrack[i] = -3;
283     fTrack[0] = itrk[0]; // first element
284     k = 1;
285     b = kTRUE;
286     for(i=1;i<l;i++){
287         for(j=0;j<k;j++) if(fTrack[j]==itrk[i]) b = kFALSE;
288         if(b){fTrack[k] = itrk[i]; k++;}
289         if(k>9) break;
290     } // end for i
291     nt = k;
292
293     delete[] idig;
294     delete[] sdig;
295     delete[] itrk;
296
297     return fTrack;
298 /*
299     Int_t *tidx=0;
300     Int_t i, j,n;
301     Int_t bit =0;
302     Int_t ntracks=0;
303     nt=0;
304
305     for (i=0;i<10;i++) fTrack[i] = -3;
306    
307     //cout<<"GetTrack start -------: fNDigits ="<<fNDigits<<endl;
308
309     for (i = 0; i<fNDigits; i++) {
310         tidx = GetDigit(i)->GetTracks();
311         n    = GetDigit(i)->GetNTracks();
312         for (j = 0; j<n && j<10;j++) {
313             if (tidx[j] >= 0) {
314                 if(ntracks == 0){
315                     fTrack[ntracks] = tidx[j];
316                     ntracks++; 
317                 }else if(tidx[j] != fTrack[ntracks-1]){
318                     ntracks++; 
319                     if(ntracks > 9) {
320                         bit = 1;
321                         break;
322                     } // end if ntracks > 9
323                     fTrack[ntracks-1] = tidx[j];
324                 } // end if ntracke == 0
325             } // end if tidx[j] >=0
326         } // 3-tracks loop for the digit 
327         if(bit == 1) break;
328     } // digit loop
329
330     SetNTracks(ntracks); 
331     nt = ntracks;
332     return &(fTrack[0]);
333 */
334 }
335 //______________________________________________________________________
336 Double_t AliITSclusterSSD::GetPosition(){
337     // return position of the cluster
338     Float_t ret;
339
340     switch(fNDigits){
341     case  1:
342         ret = GetDigitStripNo(0);
343         break;
344     case  2:
345         ret = EtaAlgorithm();
346         break;       
347     default:
348         ret = CentrOfGravity();   
349     }
350     return ret;
351 }
352 //______________________________________________________________________
353 Double_t AliITSclusterSSD::EtaAlgorithm(){
354     // algorithm for determing cluster position
355     if (fNDigits != 2) return -1;
356
357     Int_t strip1  = GetDigit(0)->GetStripNumber(); 
358     Int_t strip2  = GetDigit(1)->GetStripNumber();
359     Int_t signal1 = GetDigit(0)->GetSignal();
360     Int_t signal2 = GetDigit(1)->GetSignal();
361
362     Double_t eta;
363   
364  
365     if (strip1<strip2){
366         eta = ((Double_t)signal2)/((Double_t)(signal1+signal2));
367         if (eta<0.04) return strip1;
368         if (eta>0.96) return strip2;
369         return (strip1 + 0.43478261*eta + 0.2826087);   
370     } else{
371         eta = ((Double_t)signal1)/((Double_t)(signal1+signal2));
372         if (eta<0.04) return strip2;
373         if (eta>0.96) return strip1;
374         return (strip2 + 0.43478261*eta + 0.2826087);   
375     }
376 }
377 //______________________________________________________________________
378 Double_t  AliITSclusterSSD::GetPositionError() const {
379     // return the position error
380     return (GetNumOfDigits()+1)/2;
381 }
382 //______________________________________________________________________
383 Bool_t AliITSclusterSSD::IsCrossingWith(Int_t idx) const{
384     // return the cluster to which he crosses
385
386     for (Int_t i =0; i< fNCrosses;i++){
387         if (GetCross(i) == idx) return kTRUE;
388     }
389     return kFALSE;
390 }