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