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