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