Splitting of the ITS libraries (M.Masera & E.Crescio)
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinder.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 // Base Class used to find                                                //
18 // the reconstructed points for ITS                                       //
19 // See also AliITSClusterFinderSPD, AliITSClusterFinderSDD,               //
20 // AliITSClusterFinderSDD  AliITSClusterFinderV2                          //
21 ////////////////////////////////////////////////////////////////////////////
22
23 #include "AliITSClusterFinder.h"
24 #include "AliITSRecPoint.h"
25 #include "AliITSdigit.h"
26 #include "AliITSDetTypeRec.h"
27 #include "AliITSgeom.h"
28 #include "AliITSMap.h"
29
30 ClassImp(AliITSClusterFinder)
31
32 //----------------------------------------------------------------------
33 AliITSClusterFinder::AliITSClusterFinder():
34 TObject(),
35 fDebug(0),
36 fModule(0),
37 fDigits(0),
38 fNdigits(0),
39 fResponse(0),
40 fSegmentation(0),
41 fClusters(0),
42 fNRawClusters(0),
43 fMap(0),
44 fNperMax(0),
45 fDeclusterFlag(0),
46 fClusterSize(0),
47 fNPeaks(-1){
48     // default cluster finder
49     // Input:
50     //   none.
51     // Output:
52     //   none.
53     // Return:
54     //   A default constructed AliITSCulsterFinder
55 }
56 //----------------------------------------------------------------------
57 AliITSClusterFinder::AliITSClusterFinder(AliITSsegmentation *seg, 
58                                          AliITSresponse *res):
59 TObject(),
60 fDebug(0),
61 fModule(0),
62 fDigits(0),
63 fNdigits(0),
64 fResponse(res),
65 fSegmentation(seg),
66 fClusters(0),
67 fNRawClusters(0),
68 fMap(0),
69 fNperMax(0),
70 fDeclusterFlag(0),
71 fClusterSize(0),
72 fNPeaks(-1){
73     // Standard constructor for cluster finder
74     // Input:
75     //   AliITSsegmentation *seg  The segmentation class to be used
76     //   AliITSresponse     *res  The response class to be used
77     // Output:
78     //   none.
79     // Return:
80     //   A Standard constructed AliITSCulsterFinder
81
82     SetNperMax();
83     SetClusterSize();
84     SetDeclusterFlag();
85 }
86 //----------------------------------------------------------------------
87 AliITSClusterFinder::AliITSClusterFinder(AliITSsegmentation *seg, 
88                                          AliITSresponse *response, 
89                                          TClonesArray *digits):
90 TObject(),
91 fDebug(0),
92 fModule(0),
93 fDigits(digits),
94 fNdigits(0),
95 fResponse(response),
96 fSegmentation(seg),
97 fClusters(0),
98 fNRawClusters(0),
99 fMap(0),
100 fNperMax(0),
101 fDeclusterFlag(0),
102 fClusterSize(0),
103 fNPeaks(-1){
104     // Standard + cluster finder constructor
105     // Input:
106     //   AliITSsegmentation *seg  The segmentation class to be used
107     //   AliITSresponse     *res  The response class to be used
108     //   TClonesArray    *digits  Array of digits to be used
109     // Output:
110     //   none.
111     // Return:
112     //   A Standard constructed AliITSCulsterFinder
113
114     fNdigits = fDigits->GetEntriesFast();
115     SetNperMax();
116     SetClusterSize();
117     SetDeclusterFlag();
118 }
119 //______________________________________________________________________
120 AliITSClusterFinder::AliITSClusterFinder(const AliITSClusterFinder &source) : TObject(source) {
121   // Copy constructor
122   // Copies are not allowed. The method is protected to avoid misuse.
123   Fatal("AliITSClusterFinder","Copy constructor not allowed\n");
124 }
125
126 //______________________________________________________________________
127 AliITSClusterFinder& AliITSClusterFinder::operator=(const AliITSClusterFinder& /* source */){
128   // Assignment operator
129   // Assignment is not allowed. The method is protected to avoid misuse.
130   Fatal("= operator","Assignment operator not allowed\n");
131   return *this;
132 }
133
134 //----------------------------------------------------------------------
135 AliITSClusterFinder::~AliITSClusterFinder(){
136     // destructor cluster finder
137     // Input:
138     //   none.
139     // Output:
140     //   none.
141     // Return:
142     //   none.
143
144     if(fMap) {delete fMap;}
145     // Zero local pointers. Other classes own these pointers.
146     fSegmentation = 0;
147     fResponse     = 0;
148     fMap          = 0;
149     fDigits       = 0;
150     fNdigits      = 0;
151     fNRawClusters = 0;
152     fNperMax      = 0;
153     fDeclusterFlag= 0;
154     fClusterSize  = 0;
155     fNPeaks       = 0;
156     // fITS          = 0;
157     fDetTypeRec   = 0;
158     fITSgeom      = 0;
159
160 }
161 //__________________________________________________________________________
162 void AliITSClusterFinder::InitGeometry(){
163
164
165  //Initialisation of ITS geometry
166   if(!fITSgeom) {
167     Error("InitGeometry","ITS geom is null!");
168     return;
169   }
170   Int_t mmax=fITSgeom->GetIndexMax();
171   if (mmax>2200) {
172     Fatal("AliITSClusterFinder","Too many ITS subdetectors !"); 
173   }
174   Int_t m;
175   for (m=0; m<mmax; m++) {
176     Int_t lay,lad,det; fITSgeom->GetModuleId(m,lay,lad,det);
177     Float_t x,y,z;     fITSgeom->GetTrans(lay,lad,det,x,y,z); 
178     Double_t rot[9];   fITSgeom->GetRotMatrix(lay,lad,det,rot);
179     Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
180     Double_t ca=TMath::Cos(alpha), sa=TMath::Sin(alpha);
181     fYshift[m] = x*ca + y*sa;
182     fZshift[m] = (Double_t)z;
183     fNdet[m] = (lad-1)*fITSgeom->GetNdetectors(lay) + (det-1);
184     fNlayer[m] = lay-1;
185   }
186 }
187
188
189
190 //----------------------------------------------------------------------
191 void AliITSClusterFinder::AddCluster(Int_t branch, AliITSRawCluster *c){
192     // Add a raw cluster copy to the list
193     // Input:
194     //   Int_t       branch  The branch to which the cluster is to be added to
195     //   AliITSRawCluster *c The cluster to be added to the array of clusters
196     // Output:
197     //   none.
198     // Return:
199     //   none.
200
201    if(!fDetTypeRec) {
202     Error("AddCluster","fDetTypeRec is null!");
203     return;
204   }
205   fDetTypeRec->AddCluster(branch,c); 
206   fNRawClusters++;
207 }
208 //----------------------------------------------------------------------
209 void AliITSClusterFinder::AddCluster(Int_t branch, AliITSRawCluster *c, 
210                                      AliITSRecPoint &rp){
211     // Add a raw cluster copy to the list and the RecPoint
212     // Input:
213     //   Int_t       branch  The branch to which the cluster is to be added to
214     //   AliITSRawCluster *c The cluster to be added to the array of clusters
215     //   AliITSRecPoint  &rp The RecPoint to be added to the array of RecPoints
216     // Output:
217     //   none.
218     // Return:
219     //   none.
220   if(!fDetTypeRec) {
221     Error("AddCluster","fDetTypeRec is null!");
222     return;
223   }
224
225   fDetTypeRec->AddCluster(branch,c); 
226   fNRawClusters++;
227   fDetTypeRec->AddRecPoint(rp); 
228
229 }
230 /*
231 //______________________________________________________________________
232 void AliITSClusterFinder::CheckLabels(Int_t lab[3]) {
233   //------------------------------------------------------------
234   // Tries to find mother's labels
235   //------------------------------------------------------------
236
237   if(lab[0]<0 && lab[1]<0 && lab[2]<0) return; // In case of no labels just exit
238   // Check if simulation
239   AliMC* mc = gAlice->GetMCApp();
240   if(!mc)return;
241
242   Int_t ntracks = mc->GetNtrack();
243   for (Int_t i=0;i<3;i++){
244     Int_t label = lab[i];
245     if (label>=0 && label<ntracks) {
246       TParticle *part=(TParticle*)mc->Particle(label);
247       if (part->P() < 0.005) {
248         Int_t m=part->GetFirstMother();
249         if (m<0) {      
250           continue;
251         }
252         if (part->GetStatusCode()>0) {
253           continue;
254         }
255         lab[i]=m;       
256       }
257     }    
258   }
259   
260 }
261 */
262 //______________________________________________________________________
263 void AliITSClusterFinder::FindRawClusters(Int_t module){
264     // Default Cluster finder.
265     // Input:
266     //   Int_t module   Module number for which culster are to be found.
267     // Output:
268     //   none.
269     // Return:
270     //   none.
271     const Int_t kelms = 10;
272     Int_t ndigits = fDigits->GetEntriesFast();
273     TObjArray *digs = new TObjArray(ndigits);
274     TObjArray *clusts = new TObjArray(ndigits); // max # cluster
275     TObjArray *clust0=0; // A spacific cluster of digits
276     TObjArray *clust1=0; // A spacific cluster of digits
277     AliITSdigit *dig=0; // locat pointer to a digit
278     Int_t i=0,nc=0,j[4],k,k2=0;
279
280     // Copy all digits for this module into a local TObjArray.
281     for(i=0;i<ndigits;i++) digs->AddAt(new AliITSdigit(*(GetDigit(i))),i);
282     digs->Sort();
283     // First digit is a cluster.
284     i  = 0;
285     nc = 0;
286     clusts->AddAt(new TObjArray(kelms),nc);
287     clust0 = (TObjArray*)(clusts->At(nc));
288     clust0->AddAtFree(digs->At(i)); // move owner ship from digs to clusts
289     nc++;
290     for(i=1;i<ndigits;i++){
291         if(IsNeighbor(digs,i,j)){
292             dig = (AliITSdigit*)(digs->At(j[0]));
293             // Add to existing cluster. Find which cluster this digis 
294             for(k=0;k<nc;k++){
295                 clust0 = ((TObjArray*)(clusts->At(k)));
296                 if(clust0->IndexOf(dig)>=0) break;
297             } // end for k
298             if(k>=nc){
299                 Fatal("FindRawClusters","Digit not found as expected");
300             } // end if
301             if(j[1]>=0){
302                 dig = (AliITSdigit*)(digs->At(j[1]));
303                 // Add to existing cluster. Find which cluster this digis 
304                 for(k2=0;k2<nc;k2++){
305                     clust1 = ((TObjArray*)(clusts->At(k2)));
306                     if(clust1->IndexOf(dig)>=0) break;
307                 } // end for k2
308                 if(k2>=nc){
309                     Fatal("FindRawClusters","Digit not found as expected");
310                 } // end if
311             } // end if j[1]>=0
312             // Found cluster with neighboring digits add this one to it.
313             if(clust0==clust1){ // same cluster
314                 clust0->AddAtFree(digs->At(i));
315                 clust0 = 0; // finished with cluster. zero for safty
316                 clust1 = 0; // finished wit hcluster. zero for safty
317             }else{ // two different clusters which need to be merged.
318                 clust0->AddAtFree(digs->At(i)); // Add digit to this cluster.
319                 for(k=0;k<clust1->GetEntriesFast();k++){
320                     // move clust1 into clust0
321                     //move digit to this cluster
322                     clust0->AddAtFree(clust1->At(k));
323                     clust1->AddAt(0,k); // zero this one
324                 } // end for k
325                 delete clust1;
326                 clusts->AddAt(0,k2); // zero array of clusters element clust1
327                 clust0 = 0; // finished with cluster. zero for safty
328                 clust1 = 0; // finished wit hcluster. zero for safty
329             } // end if clust0==clust1
330         }else{// New cluster
331             clusts->AddAt(new TObjArray(kelms),nc);
332             clust0 = ((TObjArray*)(clusts->At(nc)));
333             // move owner ship from digs to clusts
334             clust0->AddAtFree(digs->At(i));
335             clust0 = 0; // finished with cluster. zero for safty
336             nc++;
337         } // End if IsNeighbor
338     } // end for i
339     // There are now nc clusters in clusts. Each element of clust is an
340     // array of digits which are clustered together.
341
342     // For each cluster call detector specific CreateRecPoints
343     for(i=0;i<nc;i++) CreateRecPoints((TObjArray*)(clusts->At(i)),module);
344
345     // clean up at the end.
346     for(i=0;i<nc;i++){ 
347         clust0 =(TObjArray*)(clusts->At(i));
348         // Digits deleted below, so zero this TObjArray
349         for(k=0;k<clust0->GetEntriesFast();k++) clust0->AddAt(0,k);
350         delete clust0; // Delete this TObjArray
351         clusts->AddAt(0,i); // Contents deleted above, so zero it.
352     } // end for i
353     delete clusts; // Delete this TObjArray/
354     // Delete the digits then the TObjArray which containted them.
355     for(i=0;i<ndigits;i++) delete ((AliITSdigit*)(digs->At(i)));
356     delete digs;
357 }
358 //______________________________________________________________________
359 Bool_t AliITSClusterFinder::IsNeighbor(TObjArray *digs,Int_t i,Int_t n[])const{
360     // Locagical function which checks to see if digit i has a neighbor.
361     // If so, then it returns kTRUE and its neighbor index j.
362     // This routine checks if the digits are side by side or one before the
363     // other. Requires that the array of digits be in proper order.
364     // Returns kTRUE in the following cases.
365     //                 ji   0j   if kdiagonal  j0    0i
366     //                 00   0i   if kdiagonal  0i    j0
367     // Inputs:
368     //    TObjArray *digs   Array to search for neighbors in
369     //    Int_t      i      Index of digit for which we are searching for
370     //                      a neighbor of.
371     // Output:
372     //    Int_t      j[4]   Index of one or more of the digits which is a
373     //                      neighbor of digit a index i.
374     // Return:
375     //    Bool_t            kTRUE if a neighbor was found kFALSE otherwise.
376     Int_t ix,jx,iz,jz,j;
377     const Bool_t kdiagonal=kFALSE;
378     Bool_t nei[4];
379
380     // No neighbors found if array empty.
381     if(digs->GetEntriesFast()<=0) return kFALSE;
382     // can not be a digit with first element or elements out or range
383     if(i<=0 || i>=digs->GetEntriesFast()) return kFALSE;
384
385     for(j=0;j<4;j++){n[j] = -1;nei[j]=kFALSE;}
386     ix = ((AliITSdigit*)(digs->At(i)))->GetCoord1();
387     iz = ((AliITSdigit*)(digs->At(i)))->GetCoord2();
388     for(j=0;j<i;j++){
389         jx = ((AliITSdigit*)(digs->At(j)))->GetCoord1();
390         jz = ((AliITSdigit*)(digs->At(j)))->GetCoord2();
391         if(jx+1==ix && jz  ==iz){n[0] = j;nei[0] = kTRUE;}
392         if(jx  ==ix && jz+1==iz){n[1] = j;nei[1] = kTRUE;}
393         if(jx+1==ix && jz+1==iz){n[2] = j;nei[2] = kTRUE;}
394         if(jx+1==ix && jz-1==iz){n[3] = j;nei[3] = kTRUE;}
395     } // end for k
396     if(nei[0]||nei[1]) return kTRUE;
397     if(kdiagonal&&(nei[2]||nei[3])) return kTRUE;
398     // no Neighbors found.
399     return kFALSE;
400 }
401
402 //______________________________________________________________________
403 void AliITSClusterFinder::Print(ostream *os) const{
404     //Standard output format for this class
405     // Inputs:
406     //    ostream *os   Output stream
407     // Output:
408     //    ostream *os   Output stream
409     // Return:
410     //    none.
411
412     *os << fDebug<<",";
413     *os << fModule<<",";
414     *os << fNdigits<<",";
415     *os << fNRawClusters<<",";
416     *os << fNperMax<<",";
417     *os << fDeclusterFlag<<",";
418     *os << fClusterSize<<",";
419     *os << fNPeaks<<endl;
420 }
421 /*
422 //______________________________________________________________________
423 void AliITSClusterFinder::RecPoints2Clusters
424 (const TClonesArray *points, Int_t idx, TClonesArray *clusters) {
425   //------------------------------------------------------------
426   // Conversion AliITSRecPoint -> AliITSclusterV2 for the ITS 
427   // subdetector indexed by idx 
428   //------------------------------------------------------------
429   if(!fITSgeom) {
430     Error("RecPoints2Clusters","ITS geom is null!");
431     return;
432   }
433   Int_t lastSPD1=fITSgeom->GetModuleIndex(2,1,1)-1;
434   TClonesArray &cl=*clusters;
435   Int_t ncl=points->GetEntriesFast();
436   for (Int_t i=0; i<ncl; i++) {
437     AliITSRecPoint *p = (AliITSRecPoint *)points->UncheckedAt(i);
438     Float_t lp[5];
439     lp[0]=-(-p->GetX()+fYshift[idx]); if (idx<=lastSPD1) lp[0]*=-1; //SPD1
440     lp[1]=  -p->GetZ()+fZshift[idx];
441     lp[2]=p->GetSigmaX2();
442     lp[3]=p->GetSigmaZ2();
443     lp[4]=p->GetQ()*36./23333.;  //electrons -> ADC
444     Int_t lab[4]; 
445     lab[0]=p->GetLabel(0); lab[1]=p->GetLabel(1); lab[2]=p->GetLabel(2);
446     lab[3]=fNdet[idx];
447     CheckLabels(lab);
448     Int_t dummy[3]={0,0,0};
449     new (cl[i]) AliITSclusterV2(lab,lp, dummy);
450   }  
451
452 */
453 //______________________________________________________________________
454 void AliITSClusterFinder::Read(istream *is)  {
455     //Standard input for this class
456     // Inputs:
457     //    istream *is   Input stream
458     // Output:
459     //    istream *is   Input stream
460     // Return:
461     //    none.
462
463     *is >> fDebug;
464     *is >> fModule;
465     *is >> fNdigits;
466     *is >> fNRawClusters;
467     *is >> fNperMax;
468     *is >> fDeclusterFlag;
469     *is >> fClusterSize;
470     *is >> fNPeaks;
471 }
472 //______________________________________________________________________
473 ostream &operator<<(ostream &os,AliITSClusterFinder &source){
474     // Standard output streaming function.
475     // Inputs:
476     //    ostream             *os     Output stream
477     //    AliITSClusterFinder &source Class to be printed
478     // Output:
479     //    ostream             *os     Output stream
480     // Return:
481     //    none.
482
483     source.Print(&os);
484     return os;
485 }
486 //______________________________________________________________________
487 istream &operator>>(istream &is,AliITSClusterFinder &source){
488     // Standard output streaming function.
489     // Inputs:
490     //    istream              *is      Input stream
491     //     AliITSClusterFinder &source  Class to be read in.
492     // Output:
493     //    istream              *is      Input stream
494     // Return:
495     //    none.
496
497     source.Read(&is);
498     return is;
499 }
500 /*
501 void AliITSClusterFinder::RecPoints2Clusters
502 (const TClonesArray *points, Int_t idx, TClonesArray *clusters) {
503   //------------------------------------------------------------
504   // Conversion AliITSRecPoint -> AliITSclusterV2 for the ITS 
505   // subdetector indexed by idx 
506   //------------------------------------------------------------
507   TClonesArray &cl=*clusters;
508   Int_t ncl=points->GetEntriesFast();
509   for (Int_t i=0; i<ncl; i++) {
510     AliITSRecPoint *p = (AliITSRecPoint *)points->UncheckedAt(i);
511     Float_t lp[5];
512     lp[0]=-(-p->GetX()+fYshift[idx]); if (idx<=fLastSPD1) lp[0]*=-1; //SPD1
513     lp[1]=  -p->GetZ()+fZshift[idx];
514     lp[2]=p->GetSigmaX2();
515     lp[3]=p->GetSigmaZ2();
516     lp[4]=p->GetQ()*36./23333.;  //electrons -> ADC
517     Int_t lab[4]; 
518     lab[0]=p->GetLabel(0); lab[1]=p->GetLabel(1); lab[2]=p->GetLabel(2);
519     lab[3]=fNdet[idx];
520     CheckLabels(lab);
521     Int_t dummy[3]={0,0,0};
522     new (cl[i]) AliITSclusterV2(lab,lp, dummy);
523   }  
524
525 */