]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSClusterFinderSSD.cxx
update version number
[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 <TArrayI.h>
23
24 #include "AliITSClusterFinderSSD.h"
25 #include "AliITSDetTypeRec.h"
26 #include "AliITSMapA1.h"
27 #include "AliITSRawClusterSSD.h"
28 #include "AliITSRecPoint.h"
29 #include "AliITSclusterSSD.h"
30 #include "AliITSdigitSSD.h"
31 #include "AliITSgeom.h"
32 #include "AliITSpackageSSD.h"
33 #include "AliITSsegmentationSSD.h"
34 #include "AliLog.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 fClusterP(0),
48 fNClusterP(0),
49 fClusterN(0),
50 fNClusterN(0),
51 fPackages(0),
52 fNPackages(0),
53 fDigitsIndexP(0),
54 fNDigitsP(0),
55 fDigitsIndexN(0),
56 fNDigitsN(0),
57 fPitch(0.0),
58 fTanP(0.0),
59 fTanN(0.0),
60 fPNsignalRatio(0.0),
61 fSFF(0),
62 fSFB(0){
63     //Default constructor
64 }
65 //______________________________________________________________________
66 AliITSClusterFinderSSD::AliITSClusterFinderSSD(AliITSDetTypeRec* dettyp,
67                                                TClonesArray *digits):
68 AliITSClusterFinder(dettyp,digits),
69 fClusterP(0),
70 fNClusterP(0),
71 fClusterN(0),
72 fNClusterN(0),
73 fPackages(0),
74 fNPackages(0),
75 fDigitsIndexP(0),
76 fNDigitsP(0),
77 fDigitsIndexN(0),
78 fNDigitsN(0),
79 fPitch(0.0),
80 fTanP(0.0),
81 fTanN(0.0),
82 fPNsignalRatio(0.0),
83 fSFF(0),
84 fSFB(0){
85     //Standard constructor
86
87     SetDigits(digits);
88     SetMap(new AliITSMapA1(GetSeg(),Digits()));
89     fClusterP     = new TClonesArray ("AliITSclusterSSD",200);    
90     fNClusterP    = 0;
91     fClusterN     = new TClonesArray ("AliITSclusterSSD",200);   
92     fNClusterN    = 0;
93     fPackages     = new TClonesArray ("AliITSpackageSSD",200);    //packages  
94     fNPackages    = 0;
95     fDigitsIndexP = new TArrayI(300);
96     fNDigitsP     = 0;
97     fDigitsIndexN = new TArrayI(300);
98     fNDigitsN     = 0;
99     fPitch        = GetSeg()->Dpx(0);
100     fPNsignalRatio= 7./8.;    // warning: hard-wired number
101 }
102 //______________________________________________________________________}
103 AliITSClusterFinderSSD::AliITSClusterFinderSSD(AliITSDetTypeRec* dettyp):
104 AliITSClusterFinder(dettyp),
105 fClusterP(0),
106 fNClusterP(0),
107 fClusterN(0),
108 fNClusterN(0),
109 fPackages(0),
110 fNPackages(0),
111 fDigitsIndexP(0),
112 fNDigitsP(0),
113 fDigitsIndexN(0),
114 fNDigitsN(0),
115 fPitch(0.0),
116 fTanP(0.0),
117 fTanN(0.0),
118 fPNsignalRatio(0.0),
119 fSFF(0),
120 fSFB(0){
121     //Standard constructor
122
123     fClusterP     = new TClonesArray ("AliITSclusterSSD",200);    
124     fNClusterP    = 0;
125     fClusterN     = new TClonesArray ("AliITSclusterSSD",200);   
126     fNClusterN    = 0;
127     fPackages     = new TClonesArray ("AliITSpackageSSD",200);    //packages  
128     fNPackages    = 0;
129     fDigitsIndexP = new TArrayI(300);
130     fNDigitsP     = 0;
131     fDigitsIndexN = new TArrayI(300);
132     fNDigitsN     = 0;
133     fPitch        = GetSeg()->Dpx(0);
134     fPNsignalRatio= 7./8.;    // warning: hard-wired number
135 }
136
137 //______________________________________________________________________
138 AliITSClusterFinderSSD::AliITSClusterFinderSSD(const AliITSClusterFinderSSD &source) : AliITSClusterFinder(source) {
139   // Copy constructor
140   // Copies are not allowed. The method is protected to avoid misuse.
141   Fatal("AliITSClusterFinderSSD","Copy constructor not allowed\n");
142 }
143
144 //______________________________________________________________________
145 AliITSClusterFinderSSD& AliITSClusterFinderSSD::operator=(const AliITSClusterFinderSSD& /* source */){
146   // Assignment operator
147   // Assignment is not allowed. The method is protected to avoid misuse.
148   Fatal("= operator","Assignment operator not allowed\n");
149   return *this;
150 }
151
152 //______________________________________________________________________
153 AliITSClusterFinderSSD::~AliITSClusterFinderSSD(){
154     // Default destructor
155
156     delete fClusterP;
157     delete fClusterN;        
158     delete fPackages;        
159     delete fDigitsIndexP;        
160     delete fDigitsIndexN; 
161 }
162 //______________________________________________________________________
163 void AliITSClusterFinderSSD::InitReconstruction(){
164     // initialization of the cluster finder
165
166     register Int_t i; //iterator
167
168     for (i=0;i<fNClusterP;i++) fClusterP->RemoveAt(i);
169     fNClusterP  =0;
170     for (i=0;i<fNClusterN;i++) fClusterN->RemoveAt(i);
171     fNClusterN=0;
172     for (i=0;i<fNPackages;i++) fPackages->RemoveAt(i);
173     fNPackages = 0;
174     fNDigitsP  = 0;
175     fNDigitsN  = 0;
176     Float_t stereoP,stereoN;
177     GetSeg()->Angles(stereoP,stereoN);
178     CalcStepFactor(stereoP,stereoN);
179     AliDebug(1,Form("fSFF = %d   fSFB = %d",fSFF,fSFB));
180 }
181 //______________________________________________________________________
182 void AliITSClusterFinderSSD::FindRawClusters(Int_t module){
183     // This function findes out all clusters belonging to one module
184     // 1. Zeroes all space after previous module reconstruction
185     // 2. Finds all neighbouring digits, create clusters
186     // 3. If necesery, resolves for each group of neighbouring digits 
187     //    how many clusters creates it.
188     // 4. Colculate the x and z coordinate  
189
190
191   if(!fDetTypeRec->GetITSgeom()) {
192     Error("FindRawClusters","ITS geom is null!");
193     return;
194   }
195   Int_t lay, lad, detect;
196   SetModule(module);
197   fDetTypeRec->GetITSgeom()->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         fDetTypeRec->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         fDetTypeRec->AddRecPoint(rnew);
662         return kTRUE;
663
664     } // end if
665     return kFALSE;  
666 }
667 //______________________________________________________________________
668 void  AliITSClusterFinderSSD::CalcStepFactor(Double_t Psteo, Double_t Nsteo){
669     // calculate the step factor for matching clusters
670     // 95 is the pitch, 4000 - dimension along z ?
671     Double_t dz=GetSeg()->Dz();
672
673     fSFF = ( (Int_t)  (Psteo*dz/fPitch ) );// +1;
674     fSFB = ( (Int_t)  (Nsteo*dz/fPitch ) );// +1;
675 }
676 //______________________________________________________________________
677 AliITSclusterSSD* AliITSClusterFinderSSD::GetPSideCluster(Int_t idx){
678     // get P side clusters
679
680     if((idx<0)||(idx>=fNClusterP)){
681         Info("GetPSideCluster","0<index=%d<=%d out of range",idx,fNClusterP);
682         return 0;
683     }else{
684         return (AliITSclusterSSD*)((*fClusterP)[idx]);
685     } // end if
686 }
687 //______________________________________________________________________
688 AliITSclusterSSD* AliITSClusterFinderSSD::GetNSideCluster(Int_t idx){
689     // get N side clusters
690
691     if((idx<0)||(idx>=fNClusterN)){
692         Info("GetNSideCluster","0<index=%d >= %d out of range",idx,fNClusterN);
693         return 0;
694     }else{
695         return (AliITSclusterSSD*)((*fClusterN)[idx]);
696     } // end if
697 }
698 //______________________________________________________________________
699 Bool_t AliITSClusterFinderSSD::GetCrossing (Double_t &P, Double_t &N){ 
700     // get crossing
701     // This function was rivised and changed by Boris Batiounia in March 2001
702     Double_t dx = GetSeg()->Dx(); // detector size in x direction, microns
703     Double_t dz = GetSeg()->Dz(); // detector size in z direction, microns
704     Double_t xL; // x local coordinate
705     Double_t zL; // z local coordinate
706     Double_t x;  // x = xL + dx/2
707     Double_t z;  // z = zL + dz/2
708     Double_t xP; // x coordinate in the P side from the first P strip
709     Double_t xN; // x coordinate in the N side from the first N strip
710     Float_t stereoP,stereoN;
711
712     GetSeg()->Angles(stereoP,stereoN);
713     fTanP=TMath::Tan(stereoP);
714     fTanN=TMath::Tan(stereoN);
715     Double_t kP = fTanP; // Tangent of 0.0075 mrad
716     Double_t kN = fTanN; // Tangent of 0.0275 mrad
717     P *= fPitch;
718     N *= fPitch; 
719
720     xP = N;      // change the mistake for the P/N
721     xN = P;      // coordinates correspondence in this function
722
723     x = xP + kP*(dz*kN-xP+xN)/(kP+kN);
724     z = (dz*kN-xP+xN)/(kP+kN); 
725     xL = x - dx/2;
726     zL = z - dz/2;
727     P = xL;
728     N = zL;  
729
730     if(TMath::Abs(xL) > dx/2 || TMath::Abs(zL) > dz/2) return kFALSE;
731     
732     // Check that xL and zL are inside the detector for the 
733     // correspondent xP and xN coordinates
734
735     return kTRUE;   
736 }
737 //______________________________________________________________________
738 void AliITSClusterFinderSSD::GetCrossingError(Double_t& dP, Double_t& dN){
739     // get crossing error
740     Double_t dz, dx;
741
742     dz = TMath::Abs(( dP + dN )*fPitch/(fTanP + fTanN) );
743     dx = fPitch*(TMath::Abs(dP*(1 - fTanP/(fTanP + fTanN))) +
744                  TMath::Abs(dN *fTanP/(fTanP + fTanN) ));
745     dN = dz;
746     dP = dx;
747 }