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