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