/************************************************************************** * 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 "AliITSRawCluster.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(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 = "<GetModule("ITS"); AliITSgeom *geom = aliITS->GetITSgeom(); geom->GetModuleId(module,lay, lad, detect); //cout<<"FindRawCl: layer,module ="<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 neighbour of previous, adds to last cluster 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 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 neighbour of previous, adds to last cluster 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 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 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;iGetNumOfDigits())==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; } } //-------------------------------------------------- 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; } } //------------------------------------------------ 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 N; Int_t i; N = fDigits->GetEntriesFast(); Int_t* PSidx = new Int_t [N*sizeof(Int_t)]; Int_t* NSidx = new Int_t [N*sizeof(Int_t)]; if (fDigitsIndexP==NULL) fDigitsIndexP = new TArrayI(N); if (fDigitsIndexN==NULL) fDigitsIndexN = new TArrayI(N); AliITSdigitSSD *dig; for ( i = 0 ; i< N; 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; } } else { bit=1; tmp=dig->GetStripNumber(); // same as above for( k=0;kAddAt(i,fNDigitsN++); NSidx[NNs++] =tmp; } } } 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]); } } //-------------------------------------------------------- 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; }