]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSClusterFinderSSD.cxx
Transition to NewIO
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinderSSD.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 // **************************************************************************
17 //  * The package was revised and changed by Boris Batiounia in the time     *
18 //  * period of March - June 2001                                            *
19 // **************************************************************************/
20 //
21 #include <Riostream.h>
22 #include <TArrayI.h>
23 #include "AliRun.h"
24 #include "AliITS.h"
25 #include "AliITSdigit.h"
26 #include "AliITSRawCluster.h"
27 #include "AliITSRecPoint.h"
28 #include "AliITSMapA1.h"
29 #include "AliITSClusterFinderSSD.h"
30 #include "AliITSclusterSSD.h"
31 #include "AliITSpackageSSD.h"
32 #include "AliITSsegmentation.h"
33 #include "AliITSgeom.h"
34
35 const Bool_t AliITSClusterFinderSSD::fgkSIDEP=kTRUE;
36 const Bool_t AliITSClusterFinderSSD::fgkSIDEN=kFALSE;
37 const Int_t debug=0;
38
39 ClassImp(AliITSClusterFinderSSD)
40
41 //____________________________________________________________________
42 //
43 //  Constructor
44 //______________________________________________________________________
45 AliITSClusterFinderSSD::AliITSClusterFinderSSD(){
46     //Default constructor
47
48     fSegmentation = 0;
49     fDigits       = 0;
50     fMap          = 0;
51     fITS = (AliITS*)gAlice->GetModule("ITS");
52     fClusterP     = 0;    
53     fNClusterP    =0;
54     fClusterN     = 0;
55     fNClusterN    = 0;
56     fPackages     = 0;
57     fNPackages    = 0;
58     fDigitsIndexP = 0;
59     fNDigitsP     = 0;
60     fDigitsIndexN = 0;
61     fNDigitsN     = 0;
62     fPitch        = 0;
63     fPNsignalRatio= 0;
64 }
65 //______________________________________________________________________}
66 AliITSClusterFinderSSD::AliITSClusterFinderSSD(AliITSsegmentation *seg,
67                                                TClonesArray *digits){
68     //Standard constructor
69
70     fSegmentation = seg;
71     fDigits       = digits;
72     fMap          = new AliITSMapA1(fSegmentation,fDigits);
73     fITS          = (AliITS*)gAlice->GetModule("ITS");
74     fClusterP     = new TClonesArray ("AliITSclusterSSD",200);    
75     fNClusterP    = 0;
76     fClusterN     = new TClonesArray ("AliITSclusterSSD",200);   
77     fNClusterN    = 0;
78     fPackages     = new TClonesArray ("AliITSpackageSSD",200);    //packages  
79     fNPackages    = 0;
80     fDigitsIndexP = new TArrayI(300);
81     fNDigitsP     = 0;
82     fDigitsIndexN = new TArrayI(300);
83     fNDigitsN     = 0;
84     fPitch        = fSegmentation->Dpx(0);
85     fPNsignalRatio= 7./8.;    // warning: hard-wired number
86 }
87 //______________________________________________________________________
88 AliITSClusterFinderSSD::~AliITSClusterFinderSSD(){
89     // Default destructor
90
91     delete fClusterP;
92     delete fClusterN;        
93     delete fPackages;        
94     delete fDigitsIndexP;        
95     delete fDigitsIndexN; 
96     delete fMap;
97 }
98 //______________________________________________________________________
99 void AliITSClusterFinderSSD::InitReconstruction(){
100     // initialization of the cluster finder
101
102     register Int_t i; //iterator
103
104     for (i=0;i<fNClusterP;i++) fClusterP->RemoveAt(i);
105     fNClusterP  =0;
106     for (i=0;i<fNClusterN;i++) fClusterN->RemoveAt(i);
107     fNClusterN=0;
108     for (i=0;i<fNPackages;i++) fPackages->RemoveAt(i);
109     fNPackages = 0;
110     fNDigitsP  = 0;
111     fNDigitsN  = 0;
112     Float_t stereoP,stereoN;
113     fSegmentation->Angles(stereoP,stereoN);
114     CalcStepFactor(stereoP,stereoN);
115     if (debug) cout<<"fSFF = "<<fSFF<<"  fSFB = "<<fSFB<<"\n";
116 }
117 //______________________________________________________________________
118 void AliITSClusterFinderSSD::FindRawClusters(Int_t module){
119     // This function findes out all clusters belonging to one module
120     // 1. Zeroes all space after previous module reconstruction
121     // 2. Finds all neighbouring digits, create clusters
122     // 3. If necesery, resolves for each group of neighbouring digits 
123     //    how many clusters creates it.
124     // 4. Colculate the x and z coordinate  
125     Int_t lay, lad, detect;
126     AliITSgeom *geom = fITS->GetITSgeom();
127
128     geom->GetModuleId(module,lay, lad, detect);
129     if ( lay == 6 ) ((AliITSsegmentationSSD*)fSegmentation)->SetLayer(6);
130     if ( lay == 5 ) ((AliITSsegmentationSSD*)fSegmentation)->SetLayer(5);
131
132     InitReconstruction();  //ad. 1
133     fMap->FillMap();
134     FillDigitsIndex();
135     SortDigits();
136     FindNeighbouringDigits(); //ad. 2
137     //SeparateOverlappedClusters();  //ad. 3
138     ClustersToPackages();  //ad. 4
139     fMap->ClearMap();
140 }
141 //______________________________________________________________________
142 void AliITSClusterFinderSSD::FindNeighbouringDigits(){
143     //If there are any digits on this side, create 1st Cluster,
144     // add to it this digit, and increment number of clusters
145     register Int_t i;
146
147     if ((fNDigitsP>0 )  && (fNDigitsN > 0 )) {
148         Int_t currentstripNo;
149         Int_t *dbuffer = new Int_t [300];   //buffer for strip numbers
150         Int_t dnumber;    //curent number of digits in buffer
151         TArrayI      &lDigitsIndexP = *fDigitsIndexP;
152         TArrayI      &lDigitsIndexN = *fDigitsIndexN;
153         TObjArray    &lDigits       = *(Digits());
154         TClonesArray &lClusterP     = *fClusterP;
155         TClonesArray &lClusterN     = *fClusterN;
156         //process P side 
157         dnumber = 1;
158         dbuffer[0]=lDigitsIndexP[0];
159         //If next digit is a neigh. of previous, adds to last clust. this digit
160         for (i=1; i<fNDigitsP; i++) {
161             //reads new digit
162             currentstripNo = ((AliITSdigitSSD*)lDigits[lDigitsIndexP[i]])->
163                                                             GetStripNumber(); 
164             //check if it is a neighbour of a previous one
165             if((((AliITSdigitSSD*)lDigits[lDigitsIndexP[i-1]])->
166                                                             GetStripNumber()) 
167                ==  (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexP[i];
168             else{
169                 //create a new one side cluster
170                 new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,
171                                                               Digits(),
172                                                               fgkSIDEP); 
173                 dbuffer[0]=lDigitsIndexP[i];
174                 dnumber = 1;
175             } // end if else
176         } // end loop over fNDigitsP
177         new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,
178                                                       Digits(),fgkSIDEP);
179         //process N side 
180         //for comments, see above
181         dnumber = 1;
182         dbuffer[0]=lDigitsIndexN[0];
183         //If next digit is a neigh. of previous, adds to last clust. this digit
184         for (i=1; i<fNDigitsN; i++) { 
185             currentstripNo = ((AliITSdigitSSD*)(lDigits[lDigitsIndexN[i]]))->
186                                                             GetStripNumber();
187             if ( (((AliITSdigitSSD*)lDigits[lDigitsIndexN[i-1]])->
188                                                               GetStripNumber()) 
189                  == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexN[i];
190             else {
191                 new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,
192                                                               Digits(),
193                                                               fgkSIDEN);
194                 dbuffer[0]=lDigitsIndexN[i];
195                 dnumber = 1;
196             } // end if else
197         } // end loop over fNDigitsN
198         new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,
199                                                       Digits(),fgkSIDEN);
200         delete [] dbuffer;
201
202     } // end condition on  NDigits 
203
204     if (debug) cout<<"\n Found clusters: fNClusterP = "<<fNClusterP
205                    <<"  fNClusterN ="<<fNClusterN<<"\n";
206 }
207 //______________________________________________________________________
208 void AliITSClusterFinderSSD::SeparateOverlappedClusters(){
209     // overlapped clusters separation
210     register Int_t i; //iterator
211     Float_t  factor=0.75;            // How many percent must be lower signal 
212                                      // on the middle one digit
213                                      // from its neighbours
214     Int_t    signal0;              //signal on the strip before the current one
215     Int_t    signal1;              //signal on the current one signal
216     Int_t    signal2;              //signal on the strip after the current one
217     TArrayI *splitlist;              //  List of splits
218     Int_t    numerofsplits=0;        // number of splits
219     Int_t    initPsize = fNClusterP; //initial size of the arrays 
220     Int_t    initNsize = fNClusterN; //we have to keep it because it will grow 
221                                      // in this function and it doasn't make 
222                                      // sense to pass through it again
223     splitlist = new TArrayI(300);
224
225     for (i=0;i<initPsize;i++){
226         if (( ((AliITSclusterSSD*)(*fClusterP)[i])->
227               GetNumOfDigits())==1) continue;
228         if (( ((AliITSclusterSSD*)(*fClusterP)[i])->
229               GetNumOfDigits())==2) continue;
230         Int_t nj=(((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits()-1);
231         for (Int_t j=1; j<nj; j++){
232             signal1=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j);
233             signal0=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j-1);
234             signal2=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j+1);
235             //if signal is less then factor*signal of its neighbours
236             if (  (signal1<(factor*signal0)) && (signal1<(factor*signal2)) ){
237                 (*splitlist)[numerofsplits++]=j;
238             } // end if
239         } // end loop over number of digits
240         //split this cluster if necessary
241         if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEP);
242         numerofsplits=0;
243         //in signed places (splitlist)
244     } // end loop over clusters on Pside
245
246     for (i=0;i<initNsize;i++) {
247         if (( ((AliITSclusterSSD*)(*fClusterN)[i])->
248               GetNumOfDigits())==1) continue;
249         if (( ((AliITSclusterSSD*)(*fClusterN)[i])->
250               GetNumOfDigits())==2) continue;
251         Int_t nj=(((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits()-1);
252         for (Int_t j=1; j<nj; j++){
253             signal1=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j);
254             signal0=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j-1);
255             signal2=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j+1);
256             //if signal is less then factor*signal of its neighbours
257             if (  (signal1<(factor*signal0)) && (signal1<(factor*signal2)) ) 
258                 (*splitlist)[numerofsplits++]=j;  
259         } // end loop over number of digits 
260         //split this cluster into more clusters
261         if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEN);
262         numerofsplits=0;
263         //in signed places (splitlist)
264     } // end loop over clusters on Nside
265
266     delete splitlist;
267 }
268 //______________________________________________________________________
269 void AliITSClusterFinderSSD::SplitCluster(TArrayI *list, Int_t nsplits,
270                                           Int_t index, Bool_t side){
271     //This function splits one side cluster into more clusters
272     //number of splits is defined by "nsplits"
273     //Place of splits are defined in the TArray "list"
274     // For further optimisation: Replace this function by two 
275     // specialised ones (each for one side)
276     // save one "if"
277     //For comlete comments see AliITSclusterSSD::SplitCluster
278     register Int_t i; //iterator
279     AliITSclusterSSD* curentcluster;
280     Int_t   *tmpdigits = new Int_t[100];
281     Int_t    nn;
282
283     // side true means P side
284     if (side) {
285         curentcluster =((AliITSclusterSSD*)((*fClusterP)[index])) ;
286         for (i = nsplits; i>0 ;i--) {  
287             nn=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits);
288             new ((*fClusterP)[fNClusterP]) AliITSclusterSSD(nn,tmpdigits,
289                                                             Digits(),side);
290             ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )->
291                                                       SetLeftNeighbour(kTRUE);
292             //if left cluster had neighbour on the right before split 
293             //new should have it too
294             if ( curentcluster->GetRightNeighbour() ) 
295                 ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )->
296                                                      SetRightNeighbour(kTRUE);
297             else curentcluster->SetRightNeighbour(kTRUE); 
298             fNClusterP++;
299         } // end loop over nplits
300     } else {
301         curentcluster =((AliITSclusterSSD*)((*fClusterN)[index]));
302         for (i = nsplits; i>0 ;i--) {  
303             nn=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits);
304             new ((*fClusterN)[fNClusterN]) AliITSclusterSSD(nn,tmpdigits,
305                                                             Digits(),side);
306             ((AliITSclusterSSD*)((*fClusterN)[fNClusterN]))->
307                                                     SetRightNeighbour(kTRUE);
308             if (curentcluster->GetRightNeighbour())
309                 ( (AliITSclusterSSD*)( (*fClusterN)[fNClusterN]) )->
310                                                      SetRightNeighbour(kTRUE);
311             else curentcluster->SetRightNeighbour(kTRUE);      
312             fNClusterN++;
313         } // end loop over nplits
314     } // end if side
315     delete []tmpdigits;
316 }
317 //______________________________________________________________________
318 Int_t AliITSClusterFinderSSD::SortDigitsP(Int_t start, Int_t end){
319     // sort digits on the P side
320     Int_t right;
321     Int_t left;
322
323     if (start != (end - 1) ){
324         left=this->SortDigitsP(start,(start+end)/2);
325         right=this->SortDigitsP((start+end)/2,end);  
326         return (left || right);
327     }else{ 
328         left =  ((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexP)[start]]))->
329                                                               GetStripNumber();
330         right= ((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexP)[end]]))->
331                                                               GetStripNumber();
332         if( left > right ){
333             Int_t tmp = (*fDigitsIndexP)[start];
334             (*fDigitsIndexP)[start]=(*fDigitsIndexP)[end];
335             (*fDigitsIndexP)[end]=tmp;
336             return 1;
337         }else return 0;
338     } // end if
339 }
340 //______________________________________________________________________
341 Int_t AliITSClusterFinderSSD::SortDigitsN(Int_t start, Int_t end){
342     // sort digits on the N side
343     Int_t right;
344     Int_t left;
345
346     if (start != (end - 1)){
347         left=this->SortDigitsN(start,(start+end)/2);
348         right=this->SortDigitsN((start+end)/2,end);  
349         return (left || right);
350     }else{
351         left =((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexN)[start]]))->
352                                                               GetStripNumber();
353         right=((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexN)[end]]))->
354                                                               GetStripNumber();
355         if ( left > right ){
356             Int_t tmp = (*fDigitsIndexN)[start];
357             (*fDigitsIndexN)[start]=(*fDigitsIndexN)[end];
358             (*fDigitsIndexN)[end]=tmp;
359             return 1;
360         }else return 0;
361     } // end if
362 }
363 //______________________________________________________________________
364 void AliITSClusterFinderSSD::FillDigitsIndex(){
365     //Fill the indexes of the clusters belonging to a given ITS module
366     Int_t pns=0, nns=0;
367     Int_t tmp,bit,k;
368     Int_t noentries;
369     Int_t i;
370
371     noentries = fDigits->GetEntriesFast();
372
373     Int_t* psidx = new Int_t [noentries*sizeof(Int_t)];
374     Int_t* nsidx = new Int_t [noentries*sizeof(Int_t)]; 
375     if (fDigitsIndexP==NULL) fDigitsIndexP = new TArrayI(noentries);
376     if (fDigitsIndexN==NULL) fDigitsIndexN = new TArrayI(noentries);
377
378     AliITSdigitSSD *dig;
379
380     for ( i = 0 ; i< noentries; i++ ) {
381         dig = (AliITSdigitSSD*)GetDigit(i);
382         if(dig->IsSideP()) { 
383             bit=1;
384             tmp=dig->GetStripNumber();
385             // I find this totally unnecessary - it's just a 
386             // CPU consuming double check
387             for( k=0;k<pns;k++){
388                 if (tmp==psidx[k]){
389                     if (debug) cout<<"Such a digit exists \n";
390                     bit=0;
391                 } // end if
392             } // end for k
393             // end comment 
394             if(bit) {
395                 fDigitsIndexP->AddAt(i,fNDigitsP++);
396                 psidx[pns++]=tmp;
397             } // end if bit
398         } else {
399             bit=1;
400             tmp=dig->GetStripNumber();
401             // same as above
402             for( k=0;k<nns;k++){
403                 if (tmp==nsidx[k]){
404                     if (debug) cout<<"Such a digit exists \n";
405                     bit=0;
406                 } // end if
407             } // for k
408             // end comment
409             if (bit) {
410                 fDigitsIndexN->AddAt(i,fNDigitsN++);
411                 nsidx[nns++] =tmp;
412             } // end if bit
413         } // end if
414     } // end for i
415
416     delete [] psidx;
417     delete [] nsidx;
418
419     if (debug) cout<<"Digits :  P = "<<fNDigitsP<<"   N = "<<fNDigitsN<<endl;
420 }
421 //______________________________________________________________________
422 void AliITSClusterFinderSSD::SortDigits(){
423     // sort digits
424     Int_t i;
425
426     if(fNDigitsP>1) for (i=0;i<fNDigitsP-1;i++)
427         if (SortDigitsP(0,(fNDigitsP-1-i))==0) break;
428     if(fNDigitsN>1) for (i=0;i<fNDigitsN-1;i++)
429         if(SortDigitsN(0,(fNDigitsN-1-i))==0) break;
430 }
431 //______________________________________________________________________
432 void AliITSClusterFinderSSD::FillClIndexArrays(Int_t* arrayP, Int_t *arrayN) const{
433     // fill cluster index array
434     register Int_t i;
435
436     for (i=0; i<fNClusterP;i++) arrayP[i]=i;
437     for (i=0; i<fNClusterN;i++) arrayN[i]=i;
438 }
439 //______________________________________________________________________
440 void AliITSClusterFinderSSD::SortClusters(Int_t* arrayP, Int_t *arrayN){
441     // sort clusters
442     Int_t i;
443
444     if(fNClusterP>1) for (i=0;i<fNClusterP-1;i++)
445         if (SortClustersP(0,(fNClusterP-1),arrayP)==0)  break;
446   if(fNClusterN>1) for (i=0;i<fNClusterN-1;i++)
447       if (SortClustersN(0,(fNClusterN-1),arrayN)==0)  break;
448 }
449 //______________________________________________________________________
450 Int_t AliITSClusterFinderSSD::SortClustersP(Int_t start, Int_t end,
451                                             Int_t *array){
452     //Sort P side clusters
453     Int_t right;
454     Int_t left;
455
456     if (start != (end - 1) ) {
457         left=this->SortClustersP(start,(start+end)/2,array);
458         right=this->SortClustersP((start+end)/2,end,array);  
459         return (left || right);
460     } else {
461         left =((AliITSclusterSSD*)((*fClusterP)[array[start]]))->
462                                                          GetDigitStripNo(0);
463         right=((AliITSclusterSSD*)((*fClusterP)[array[ end ]]))->
464                                                          GetDigitStripNo(0);
465         if(left>right) {
466             Int_t tmp = array[start];
467             array[start]=array[end];
468             array[end]=tmp;
469             return 1;
470         } else return 0;
471     } // end if
472 }
473 //______________________________________________________________________
474 Int_t AliITSClusterFinderSSD::SortClustersN(Int_t start, Int_t end, 
475                                             Int_t *array){
476     //Sort N side clusters
477     Int_t right;
478     Int_t left;
479
480     if (start != (end - 1) ) {
481         left=this->SortClustersN(start,(start+end)/2,array);
482         right=this->SortClustersN((start+end)/2,end,array);  
483         return (left || right);
484     } else {
485         left =((AliITSclusterSSD*)((*fClusterN)[array[start]]))->
486                                                          GetDigitStripNo(0);
487         right=((AliITSclusterSSD*)((*fClusterN)[array[ end ]]))->
488                                                          GetDigitStripNo(0);
489         if( left > right) {
490             Int_t tmp = array[start];
491             array[start]=array[end];
492             array[end]=tmp;
493             return 1;
494         } else return 0;
495     } // end if
496 }
497 //______________________________________________________________________
498 void AliITSClusterFinderSSD::ClustersToPackages(){
499     // fill packages   
500     
501     Int_t *oneSclP = new Int_t[fNClusterP];//I want to have sorted 1 S clusters
502     Int_t *oneSclN = new Int_t[fNClusterN];//I can not sort it in TClonesArray
503                                            //so, I create table of indexes and 
504                                            //sort it
505                                            //I do not use TArrayI on purpose
506                                            //MB: well, that's not true that one
507                                            //cannot sort objs in TClonesArray
508     AliITSclusterSSD *currentP;
509     AliITSclusterSSD *currentN;
510     Int_t j1, j2;    
511
512     //Fills in One Side Clusters Index Array
513     FillClIndexArrays(oneSclP,oneSclN); 
514     //Sorts filled Arrays
515     //SortClusters(oneSclP,oneSclN);                   
516
517     fNPackages=1;      
518     new ((*fPackages)[0]) AliITSpackageSSD(fClusterP,fClusterN);
519
520     //This part was includede by Boris Batiounia in March 2001.
521     // Take all recpoint pairs (x coordinates) in both P and N sides  
522     // to calculate z coordinates of the recpoints
523
524     for (j1=0;j1<fNClusterP;j1++) {  
525         currentP = GetPSideCluster(oneSclP[j1]);
526         Double_t xP = currentP->GetPosition();
527         Float_t signalP = currentP->GetTotalSignal();
528         for (j2=0;j2<fNClusterN;j2++) {  
529             currentN = GetNSideCluster(oneSclN[j2]);
530             Double_t xN = currentN->GetPosition();
531             Float_t signalN = currentN->GetTotalSignal();
532             CreateNewRecPoint(xP,1,xN,1,signalP,signalN,currentP,currentN,
533                               0.75);
534         } // end for j2
535     } // end for j1
536
537     delete [] oneSclP;
538     delete [] oneSclN;
539 }
540 //______________________________________________________________________
541 Bool_t AliITSClusterFinderSSD::CreateNewRecPoint(Float_t P,Float_t dP,
542                                                  Float_t N, Float_t dN,
543                                                  Float_t SigP,Float_t SigN, 
544                                                  AliITSclusterSSD *clusterP,
545                                                  AliITSclusterSSD *clusterN,
546                                                  Stat_t prob){
547     // create the recpoints
548     const Float_t kADCtoKeV = 2.16; 
549     // 50 ADC units -> 30000 e-h pairs; 1e-h pair -> 3.6e-3 KeV;
550     // 1 ADC unit -> (30000/50)*3.6e-3 = 2.16 KeV 
551     const Float_t kconv = 1.0e-4;
552     const Float_t kRMSx = 20.0*kconv; 
553     const Float_t kRMSz = 800.0*kconv;
554     Int_t n=0;
555     Int_t *tr;
556     Int_t ntracks;
557
558     if (GetCrossing(P,N)) {
559         //GetCrossingError(dP,dN);
560         AliITSRawClusterSSD cnew;
561         Int_t nstripsP=clusterP->GetNumOfDigits();
562         Int_t nstripsN=clusterN->GetNumOfDigits();
563         Float_t signal = 0;
564         Float_t dedx = 0;
565         if(SigP>SigN) {
566             signal = SigP;
567             dedx = SigP*kADCtoKeV;
568         }else{
569             signal = SigN;
570             dedx = SigN*kADCtoKeV;
571         } // end if SigP>SigN
572      tr = (Int_t*) clusterP->GetTracks(n);
573      ntracks = clusterP->GetNTracks();
574      cnew.fSignalP=SigP;
575      cnew.fSignalN=SigN;
576      cnew.fMultiplicity=nstripsP;
577      cnew.fMultiplicityN=nstripsN;
578      cnew.fQErr=TMath::Abs(SigP-SigN);
579      cnew.fNtracks=ntracks;
580      fITS->AddCluster(2,&cnew);
581      AliITSRecPoint rnew;
582      rnew.SetX(P*kconv);
583      rnew.SetZ(N*kconv);
584      rnew.SetQ(signal);
585      rnew.SetdEdX(dedx);
586      rnew.SetSigmaX2( kRMSx* kRMSx); 
587      rnew.SetSigmaZ2( kRMSz* kRMSz);
588      rnew.fTracks[0]=tr[0];
589      rnew.fTracks[1]=tr[1];
590      rnew.fTracks[2]=tr[2];
591      fITS->AddRecPoint(rnew);
592      return kTRUE;
593     } // end if
594     return kFALSE;  
595 }
596 //______________________________________________________________________
597 void  AliITSClusterFinderSSD::CalcStepFactor(Float_t Psteo, Float_t Nsteo){
598     // calculate the step factor for matching clusters
599     // 95 is the pitch, 4000 - dimension along z ?
600     Float_t dz=fSegmentation->Dz();
601
602     fSFF = ( (Int_t)  (Psteo*dz/fPitch ) );// +1;
603     fSFB = ( (Int_t)  (Nsteo*dz/fPitch ) );// +1;
604 }
605 //______________________________________________________________________
606 AliITSclusterSSD* AliITSClusterFinderSSD::GetPSideCluster(Int_t idx){
607     // get P side clusters
608
609     if((idx<0)||(idx>=fNClusterP)){
610         printf("AliITSClusterFinderSSD::GetPSideCluster: index out of range\n");
611         return 0;
612     }else{
613         return (AliITSclusterSSD*)((*fClusterP)[idx]);
614     } // end if
615 }
616 //______________________________________________________________________
617 AliITSclusterSSD* AliITSClusterFinderSSD::GetNSideCluster(Int_t idx){
618     // get N side clusters
619
620     if((idx<0)||(idx>=fNClusterN)){
621         printf("AliITSClusterFinderSSD::GetNSideCluster: index out of range\n");
622         return 0;
623     }else{
624         return (AliITSclusterSSD*)((*fClusterN)[idx]);
625     } // end if
626 }
627 //______________________________________________________________________
628 AliITSclusterSSD* AliITSClusterFinderSSD::GetCluster(Int_t idx, Bool_t side){
629     // Get cluster
630
631     return (side) ? GetPSideCluster(idx) : GetNSideCluster(idx);
632 }
633 //______________________________________________________________________
634 Bool_t AliITSClusterFinderSSD::GetCrossing (Float_t &P, Float_t &N){ 
635     // get crossing
636     // This function was rivised and changed by Boris Batiounia in March 2001
637     Float_t dx = fSegmentation->Dx(); // detector size in x direction, microns
638     Float_t dz = fSegmentation->Dz(); // detector size in z direction, microns
639     Float_t xL; // x local coordinate
640     Float_t zL; // z local coordinate
641     Float_t x;  // x = xL + dx/2
642     Float_t z;  // z = zL + dz/2
643     Float_t xP; // x coordinate in the P side from the first P strip
644     Float_t xN; // x coordinate in the N side from the first N strip
645     Float_t stereoP,stereoN;
646
647     fSegmentation->Angles(stereoP,stereoN);
648     fTanP=TMath::Tan(stereoP);
649     fTanN=TMath::Tan(stereoN);
650     Float_t kP = fTanP; // Tangent of 0.0075 mrad
651     Float_t kN = fTanN; // Tangent of 0.0275 mrad
652     P *= fPitch;
653     N *= fPitch; 
654
655     xP = N;      // change the mistake for the P/N
656     xN = P;      // coordinates correspondence in this function
657
658     x = xP + kP*(dz*kN-xP+xN)/(kP+kN);
659     z = (dz*kN-xP+xN)/(kP+kN); 
660     xL = x - dx/2;
661     zL = z - dz/2;
662     P = xL;
663     N = zL;  
664
665     if(TMath::Abs(xL) > dx/2 || TMath::Abs(zL) > dz/2) return kFALSE;
666     
667     // Check that xL and zL are inside the detector for the 
668     // correspondent xP and xN coordinates
669
670     return kTRUE;   
671 }
672 //______________________________________________________________________
673 void AliITSClusterFinderSSD::GetCrossingError(Float_t& dP, Float_t& dN){
674     // get crossing error
675     Float_t dz, dx;
676
677     dz = TMath::Abs(( dP + dN )*fPitch/(fTanP + fTanN) );
678     dx = fPitch*(TMath::Abs(dP*(1 - fTanP/(fTanP + fTanN))) +
679                  TMath::Abs(dN *fTanP/(fTanP + fTanN) ));
680     dN = dz;
681     dP = dx;
682 }