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