/************************************************************************** * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * * Contributors are mentioned in the code where appropriate. * * * * Permission to use, copy, modify and distribute this software and its * * documentation strictly for non-commercial purposes is hereby granted * * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ // ************************************************************************** // * The package was revised and changed by Boris Batiounia in the time * // * period of March - June 2001 * // **************************************************************************/ // #include #include #include "AliRun.h" #include "AliITS.h" #include "AliITSdigit.h" #include "AliITSRawClusterSSD.h" #include "AliITSRecPoint.h" #include "AliITSMapA1.h" #include "AliITSClusterFinderSSD.h" #include "AliITSclusterSSD.h" #include "AliITSpackageSSD.h" #include "AliITSsegmentation.h" #include "AliITSgeom.h" const Bool_t AliITSClusterFinderSSD::fgkSIDEP=kTRUE; const Bool_t AliITSClusterFinderSSD::fgkSIDEN=kFALSE; const Int_t debug=0; ClassImp(AliITSClusterFinderSSD) //____________________________________________________________________ // // Constructor //______________________________________________________________________ AliITSClusterFinderSSD::AliITSClusterFinderSSD(){ //Default constructor fSegmentation = 0; fDigits = 0; fMap = 0; fITS = (AliITS*)gAlice->GetModule("ITS"); fClusterP = 0; fNClusterP =0; fClusterN = 0; fNClusterN = 0; fPackages = 0; fNPackages = 0; fDigitsIndexP = 0; fNDigitsP = 0; fDigitsIndexN = 0; fNDigitsN = 0; fPitch = 0; fPNsignalRatio= 0; } //______________________________________________________________________} AliITSClusterFinderSSD::AliITSClusterFinderSSD(AliITSsegmentation *seg, TClonesArray *digits){ //Standard constructor fSegmentation = seg; fDigits = digits; fMap = new AliITSMapA1(fSegmentation,fDigits); fITS = (AliITS*)gAlice->GetModule("ITS"); fClusterP = new TClonesArray ("AliITSclusterSSD",200); fNClusterP = 0; fClusterN = new TClonesArray ("AliITSclusterSSD",200); fNClusterN = 0; fPackages = new TClonesArray ("AliITSpackageSSD",200); //packages fNPackages = 0; fDigitsIndexP = new TArrayI(300); fNDigitsP = 0; fDigitsIndexN = new TArrayI(300); fNDigitsN = 0; fPitch = fSegmentation->Dpx(0); fPNsignalRatio= 7./8.; // warning: hard-wired number } //______________________________________________________________________ AliITSClusterFinderSSD::~AliITSClusterFinderSSD(){ // Default destructor delete fClusterP; delete fClusterN; delete fPackages; delete fDigitsIndexP; delete fDigitsIndexN; delete fMap; } //______________________________________________________________________ void AliITSClusterFinderSSD::InitReconstruction(){ // initialization of the cluster finder register Int_t i; //iterator for (i=0;iRemoveAt(i); fNClusterP =0; for (i=0;iRemoveAt(i); fNClusterN=0; for (i=0;iRemoveAt(i); fNPackages = 0; fNDigitsP = 0; fNDigitsN = 0; Float_t stereoP,stereoN; fSegmentation->Angles(stereoP,stereoN); CalcStepFactor(stereoP,stereoN); if (debug) cout<<"fSFF = "<GetITSgeom(); geom->GetModuleId(module,lay, lad, detect); if ( lay == 6 ) ((AliITSsegmentationSSD*)fSegmentation)->SetLayer(6); if ( lay == 5 ) ((AliITSsegmentationSSD*)fSegmentation)->SetLayer(5); InitReconstruction(); //ad. 1 fMap->FillMap(); FillDigitsIndex(); SortDigits(); FindNeighbouringDigits(); //ad. 2 //SeparateOverlappedClusters(); //ad. 3 ClustersToPackages(); //ad. 4 fMap->ClearMap(); } //______________________________________________________________________ void AliITSClusterFinderSSD::FindNeighbouringDigits(){ //If there are any digits on this side, create 1st Cluster, // add to it this digit, and increment number of clusters register Int_t i; if ((fNDigitsP>0 ) && (fNDigitsN > 0 )) { Int_t currentstripNo; Int_t *dbuffer = new Int_t [300]; //buffer for strip numbers Int_t dnumber; //curent number of digits in buffer TArrayI &lDigitsIndexP = *fDigitsIndexP; TArrayI &lDigitsIndexN = *fDigitsIndexN; TObjArray &lDigits = *(Digits()); TClonesArray &lClusterP = *fClusterP; TClonesArray &lClusterN = *fClusterN; //process P side dnumber = 1; dbuffer[0]=lDigitsIndexP[0]; //If next digit is a neigh. of previous, adds to last clust. this digit for (i=1; i GetStripNumber(); //check if it is a neighbour of a previous one if((((AliITSdigitSSD*)lDigits[lDigitsIndexP[i-1]])-> GetStripNumber()) == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexP[i]; else{ //create a new one side cluster new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer, Digits(), fgkSIDEP); dbuffer[0]=lDigitsIndexP[i]; dnumber = 1; } // end if else } // end loop over fNDigitsP new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer, Digits(),fgkSIDEP); //process N side //for comments, see above dnumber = 1; dbuffer[0]=lDigitsIndexN[0]; //If next digit is a neigh. of previous, adds to last clust. this digit for (i=1; i GetStripNumber(); if ( (((AliITSdigitSSD*)lDigits[lDigitsIndexN[i-1]])-> GetStripNumber()) == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexN[i]; else { new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer, Digits(), fgkSIDEN); dbuffer[0]=lDigitsIndexN[i]; dnumber = 1; } // end if else } // end loop over fNDigitsN new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer, Digits(),fgkSIDEN); delete [] dbuffer; } // end condition on NDigits if (debug) cout<<"\n Found clusters: fNClusterP = "< GetNumOfDigits())==1) continue; if (( ((AliITSclusterSSD*)(*fClusterP)[i])-> GetNumOfDigits())==2) continue; Int_t nj=(((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits()-1); for (Int_t j=1; jGetDigitSignal(j); signal0=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j-1); signal2=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j+1); //if signal is less then factor*signal of its neighbours if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) ){ (*splitlist)[numerofsplits++]=j; } // end if } // end loop over number of digits //split this cluster if necessary if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEP); numerofsplits=0; //in signed places (splitlist) } // end loop over clusters on Pside for (i=0;i GetNumOfDigits())==1) continue; if (( ((AliITSclusterSSD*)(*fClusterN)[i])-> GetNumOfDigits())==2) continue; Int_t nj=(((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits()-1); for (Int_t j=1; jGetDigitSignal(j); signal0=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j-1); signal2=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j+1); //if signal is less then factor*signal of its neighbours if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) ) (*splitlist)[numerofsplits++]=j; } // end loop over number of digits //split this cluster into more clusters if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEN); numerofsplits=0; //in signed places (splitlist) } // end loop over clusters on Nside delete splitlist; } //______________________________________________________________________ void AliITSClusterFinderSSD::SplitCluster(TArrayI *list, Int_t nsplits, Int_t index, Bool_t side){ //This function splits one side cluster into more clusters //number of splits is defined by "nsplits" //Place of splits are defined in the TArray "list" // For further optimisation: Replace this function by two // specialised ones (each for one side) // save one "if" //For comlete comments see AliITSclusterSSD::SplitCluster register Int_t i; //iterator AliITSclusterSSD* curentcluster; Int_t *tmpdigits = new Int_t[100]; Int_t nn; // side true means P side if (side) { curentcluster =((AliITSclusterSSD*)((*fClusterP)[index])) ; for (i = nsplits; i>0 ;i--) { nn=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits); new ((*fClusterP)[fNClusterP]) AliITSclusterSSD(nn,tmpdigits, Digits(),side); ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )-> SetLeftNeighbour(kTRUE); //if left cluster had neighbour on the right before split //new should have it too if ( curentcluster->GetRightNeighbour() ) ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )-> SetRightNeighbour(kTRUE); else curentcluster->SetRightNeighbour(kTRUE); fNClusterP++; } // end loop over nplits } else { curentcluster =((AliITSclusterSSD*)((*fClusterN)[index])); for (i = nsplits; i>0 ;i--) { nn=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits); new ((*fClusterN)[fNClusterN]) AliITSclusterSSD(nn,tmpdigits, Digits(),side); ((AliITSclusterSSD*)((*fClusterN)[fNClusterN]))-> SetRightNeighbour(kTRUE); if (curentcluster->GetRightNeighbour()) ( (AliITSclusterSSD*)( (*fClusterN)[fNClusterN]) )-> SetRightNeighbour(kTRUE); else curentcluster->SetRightNeighbour(kTRUE); fNClusterN++; } // end loop over nplits } // end if side delete []tmpdigits; } //______________________________________________________________________ Int_t AliITSClusterFinderSSD::SortDigitsP(Int_t start, Int_t end){ // sort digits on the P side Int_t right; Int_t left; if (start != (end - 1) ){ left=this->SortDigitsP(start,(start+end)/2); right=this->SortDigitsP((start+end)/2,end); return (left || right); }else{ left = ((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexP)[start]]))-> GetStripNumber(); right= ((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexP)[end]]))-> GetStripNumber(); if( left > right ){ Int_t tmp = (*fDigitsIndexP)[start]; (*fDigitsIndexP)[start]=(*fDigitsIndexP)[end]; (*fDigitsIndexP)[end]=tmp; return 1; }else return 0; } // end if } //______________________________________________________________________ Int_t AliITSClusterFinderSSD::SortDigitsN(Int_t start, Int_t end){ // sort digits on the N side Int_t right; Int_t left; if (start != (end - 1)){ left=this->SortDigitsN(start,(start+end)/2); right=this->SortDigitsN((start+end)/2,end); return (left || right); }else{ left =((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexN)[start]]))-> GetStripNumber(); right=((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexN)[end]]))-> GetStripNumber(); if ( left > right ){ Int_t tmp = (*fDigitsIndexN)[start]; (*fDigitsIndexN)[start]=(*fDigitsIndexN)[end]; (*fDigitsIndexN)[end]=tmp; return 1; }else return 0; } // end if } //______________________________________________________________________ void AliITSClusterFinderSSD::FillDigitsIndex(){ //Fill the indexes of the clusters belonging to a given ITS module Int_t pns=0, nns=0; Int_t tmp,bit,k; Int_t noentries; Int_t i; noentries = fDigits->GetEntriesFast(); Int_t* psidx = new Int_t [noentries*sizeof(Int_t)]; Int_t* nsidx = new Int_t [noentries*sizeof(Int_t)]; if (fDigitsIndexP==NULL) fDigitsIndexP = new TArrayI(noentries); if (fDigitsIndexN==NULL) fDigitsIndexN = new TArrayI(noentries); AliITSdigitSSD *dig; for ( i = 0 ; i< noentries; i++ ) { dig = (AliITSdigitSSD*)GetDigit(i); if(dig->IsSideP()) { bit=1; tmp=dig->GetStripNumber(); // I find this totally unnecessary - it's just a // CPU consuming double check for( k=0;kAddAt(i,fNDigitsP++); psidx[pns++]=tmp; } // end if bit } else { bit=1; tmp=dig->GetStripNumber(); // same as above for( k=0;kAddAt(i,fNDigitsN++); nsidx[nns++] =tmp; } // end if bit } // end if } // end for i delete [] psidx; delete [] nsidx; if (debug) cout<<"Digits : P = "<=fNClusterN)){ printf("AliITSClusterFinderSSD::GetNSideCluster: index out of range\n"); return 0; }else{ return (AliITSclusterSSD*)((*fClusterN)[idx]); } // end if } //______________________________________________________________________ AliITSclusterSSD* AliITSClusterFinderSSD::GetCluster(Int_t idx, Bool_t side){ // Get cluster return (side) ? GetPSideCluster(idx) : GetNSideCluster(idx); } //______________________________________________________________________ Bool_t AliITSClusterFinderSSD::GetCrossing (Float_t &P, Float_t &N){ // get crossing // This function was rivised and changed by Boris Batiounia in March 2001 Float_t dx = fSegmentation->Dx(); // detector size in x direction, microns Float_t dz = fSegmentation->Dz(); // detector size in z direction, microns Float_t xL; // x local coordinate Float_t zL; // z local coordinate Float_t x; // x = xL + dx/2 Float_t z; // z = zL + dz/2 Float_t xP; // x coordinate in the P side from the first P strip Float_t xN; // x coordinate in the N side from the first N strip Float_t stereoP,stereoN; fSegmentation->Angles(stereoP,stereoN); fTanP=TMath::Tan(stereoP); fTanN=TMath::Tan(stereoN); Float_t kP = fTanP; // Tangent of 0.0075 mrad Float_t kN = fTanN; // Tangent of 0.0275 mrad P *= fPitch; N *= fPitch; xP = N; // change the mistake for the P/N xN = P; // coordinates correspondence in this function x = xP + kP*(dz*kN-xP+xN)/(kP+kN); z = (dz*kN-xP+xN)/(kP+kN); xL = x - dx/2; zL = z - dz/2; P = xL; N = zL; if(TMath::Abs(xL) > dx/2 || TMath::Abs(zL) > dz/2) return kFALSE; // Check that xL and zL are inside the detector for the // correspondent xP and xN coordinates return kTRUE; } //______________________________________________________________________ void AliITSClusterFinderSSD::GetCrossingError(Float_t& dP, Float_t& dN){ // get crossing error Float_t dz, dx; dz = TMath::Abs(( dP + dN )*fPitch/(fTanP + fTanN) ); dx = fPitch*(TMath::Abs(dP*(1 - fTanP/(fTanP + fTanN))) + TMath::Abs(dN *fTanP/(fTanP + fTanN) )); dN = dz; dP = dx; }