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