1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 ////////////////////////////////////////////////////////////////////////////
17 // Base Class used to find //
18 // the reconstructed points for ITS //
19 // See also AliITSClusterFinderSPD, AliITSClusterFinderSDD, //
20 // AliITSClusterFinderSDD AliITSClusterFinderV2 //
21 ////////////////////////////////////////////////////////////////////////////
23 #include "AliITSClusterFinder.h"
24 #include "AliITSRecPoint.h"
25 #include "AliITSdigit.h"
26 #include "AliITSDetTypeRec.h"
27 #include "AliITSgeom.h"
28 #include "AliITSMap.h"
30 ClassImp(AliITSClusterFinder)
32 //----------------------------------------------------------------------
33 AliITSClusterFinder::AliITSClusterFinder():
48 // default cluster finder
54 // A default constructed AliITSCulsterFinder
56 //----------------------------------------------------------------------
57 AliITSClusterFinder::AliITSClusterFinder(AliITSsegmentation *seg,
73 // Standard constructor for cluster finder
75 // AliITSsegmentation *seg The segmentation class to be used
76 // AliITSresponse *res The response class to be used
80 // A Standard constructed AliITSCulsterFinder
86 //----------------------------------------------------------------------
87 AliITSClusterFinder::AliITSClusterFinder(AliITSsegmentation *seg,
88 AliITSresponse *response,
89 TClonesArray *digits):
104 // Standard + cluster finder constructor
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
112 // A Standard constructed AliITSCulsterFinder
114 fNdigits = fDigits->GetEntriesFast();
119 //______________________________________________________________________
120 AliITSClusterFinder::AliITSClusterFinder(const AliITSClusterFinder &source) : TObject(source) {
122 // Copies are not allowed. The method is protected to avoid misuse.
123 Fatal("AliITSClusterFinder","Copy constructor not allowed\n");
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");
134 //----------------------------------------------------------------------
135 AliITSClusterFinder::~AliITSClusterFinder(){
136 // destructor cluster finder
144 if(fMap) {delete fMap;}
145 // Zero local pointers. Other classes own these pointers.
161 //__________________________________________________________________________
162 void AliITSClusterFinder::InitGeometry(){
165 //Initialisation of ITS geometry
167 Error("InitGeometry","ITS geom is null!");
170 Int_t mmax=fITSgeom->GetIndexMax();
172 Fatal("AliITSClusterFinder","Too many ITS subdetectors !");
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);
190 //----------------------------------------------------------------------
191 void AliITSClusterFinder::AddCluster(Int_t branch, AliITSRawCluster *c){
192 // Add a raw cluster copy to the list
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
202 Error("AddCluster","fDetTypeRec is null!");
205 fDetTypeRec->AddCluster(branch,c);
208 //----------------------------------------------------------------------
209 void AliITSClusterFinder::AddCluster(Int_t branch, AliITSRawCluster *c,
211 // Add a raw cluster copy to the list and the RecPoint
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
221 Error("AddCluster","fDetTypeRec is null!");
225 fDetTypeRec->AddCluster(branch,c);
227 fDetTypeRec->AddRecPoint(rp);
231 //______________________________________________________________________
232 void AliITSClusterFinder::CheckLabels(Int_t lab[3]) {
233 //------------------------------------------------------------
234 // Tries to find mother's labels
235 //------------------------------------------------------------
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();
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();
252 if (part->GetStatusCode()>0) {
262 //______________________________________________________________________
263 void AliITSClusterFinder::FindRawClusters(Int_t module){
264 // Default Cluster finder.
266 // Int_t module Module number for which culster are to be found.
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;
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);
283 // First digit is a cluster.
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
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
295 clust0 = ((TObjArray*)(clusts->At(k)));
296 if(clust0->IndexOf(dig)>=0) break;
299 Fatal("FindRawClusters","Digit not found as expected");
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;
309 Fatal("FindRawClusters","Digit not found as expected");
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
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
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
337 } // End if IsNeighbor
339 // There are now nc clusters in clusts. Each element of clust is an
340 // array of digits which are clustered together.
342 // For each cluster call detector specific CreateRecPoints
343 for(i=0;i<nc;i++) CreateRecPoints((TObjArray*)(clusts->At(i)),module);
345 // clean up at the end.
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.
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)));
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
368 // TObjArray *digs Array to search for neighbors in
369 // Int_t i Index of digit for which we are searching for
372 // Int_t j[4] Index of one or more of the digits which is a
373 // neighbor of digit a index i.
375 // Bool_t kTRUE if a neighbor was found kFALSE otherwise.
377 const Bool_t kdiagonal=kFALSE;
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;
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();
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;}
396 if(nei[0]||nei[1]) return kTRUE;
397 if(kdiagonal&&(nei[2]||nei[3])) return kTRUE;
398 // no Neighbors found.
402 //______________________________________________________________________
403 void AliITSClusterFinder::Print(ostream *os) const{
404 //Standard output format for this class
406 // ostream *os Output stream
408 // ostream *os Output stream
414 *os << fNdigits<<",";
415 *os << fNRawClusters<<",";
416 *os << fNperMax<<",";
417 *os << fDeclusterFlag<<",";
418 *os << fClusterSize<<",";
419 *os << fNPeaks<<endl;
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 //------------------------------------------------------------
430 Error("RecPoints2Clusters","ITS geom is null!");
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);
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
445 lab[0]=p->GetLabel(0); lab[1]=p->GetLabel(1); lab[2]=p->GetLabel(2);
448 Int_t dummy[3]={0,0,0};
449 new (cl[i]) AliITSclusterV2(lab,lp, dummy);
453 //______________________________________________________________________
454 void AliITSClusterFinder::Read(istream *is) {
455 //Standard input for this class
457 // istream *is Input stream
459 // istream *is Input stream
466 *is >> fNRawClusters;
468 *is >> fDeclusterFlag;
472 //______________________________________________________________________
473 ostream &operator<<(ostream &os,AliITSClusterFinder &source){
474 // Standard output streaming function.
476 // ostream *os Output stream
477 // AliITSClusterFinder &source Class to be printed
479 // ostream *os Output stream
486 //______________________________________________________________________
487 istream &operator>>(istream &is,AliITSClusterFinder &source){
488 // Standard output streaming function.
490 // istream *is Input stream
491 // AliITSClusterFinder &source Class to be read in.
493 // istream *is Input stream
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);
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
518 lab[0]=p->GetLabel(0); lab[1]=p->GetLabel(1); lab[2]=p->GetLabel(2);
521 Int_t dummy[3]={0,0,0};
522 new (cl[i]) AliITSclusterV2(lab,lp, dummy);