Separating well and badly reconstructed pileup vertices. Adding statistics of associa...
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinder.cxx
index 3ec86d3..aa3f4cf 100644 (file)
 // AliITSClusterFinderSDD  AliITSClusterFinderV2                          //
 ////////////////////////////////////////////////////////////////////////////
 
+#include "AliRun.h"
 #include "AliITSClusterFinder.h"
 #include "AliITSRecPoint.h"
 #include "AliITSdigit.h"
 #include "AliITSDetTypeRec.h"
 #include "AliITSMap.h"
 #include "AliITSgeomTGeo.h"
+#include <TParticle.h>
+#include <TArrayI.h>
+#include "AliMC.h"
+#include "AliLog.h"
+
+using std::endl;
 
 ClassImp(AliITSClusterFinder)
 
+extern AliRun *gAlice;
+
 //----------------------------------------------------------------------
 AliITSClusterFinder::AliITSClusterFinder():
 TObject(),
-fDebug(0),
 fModule(0),
 fDigits(0),
 fNdigits(0),
 fDetTypeRec(0),
 fClusters(0),
-fNRawClusters(0),
 fMap(0),
-fNperMax(0),
-fDeclusterFlag(0),
-fClusterSize(0),
-fNPeaks(-1){
+fNPeaks(-1),
+fNModules(AliITSgeomTGeo::GetNModules()),
+fEvent(0),
+fZmin(0),
+fZmax(0),
+fXmin(0),
+fXmax(0),
+fNClusters(0),
+fRawID2ClusID(0)
+{
     // default cluster finder
     // Input:
     //   none.
@@ -51,22 +64,31 @@ fNPeaks(-1){
     //   none.
     // Return:
     //   A default constructed AliITSCulsterFinder
+  for(Int_t i=0; i<2200; i++){
+    fNdet[i]=0;
+    fNlayer[i]=0;
+  }
 }
 //----------------------------------------------------------------------
 AliITSClusterFinder::AliITSClusterFinder(AliITSDetTypeRec* dettyp):
 TObject(),
-fDebug(0),
 fModule(0),
 fDigits(0),
 fNdigits(0),
 fDetTypeRec(dettyp),
 fClusters(0),
-fNRawClusters(0),
 fMap(0),
-fNperMax(0),
-fDeclusterFlag(0),
-fClusterSize(0),
-fNPeaks(-1){
+fNPeaks(-1),
+fNModules(AliITSgeomTGeo::GetNModules()),
+fEvent(0),
+fZmin(0),
+fZmax(0),
+fXmin(0),
+fXmax(0),
+fNClusters(0),
+fRawID2ClusID(0)
+{
+    // default cluster finder
     // Standard constructor for cluster finder
     // Input:
     //   AliITSsegmentation *seg  The segmentation class to be used
@@ -75,27 +97,32 @@ fNPeaks(-1){
     //   none.
     // Return:
     //   A Standard constructed AliITSCulsterFinder
-
-    SetNperMax();
-    SetClusterSize();
-    SetDeclusterFlag();
+  for(Int_t i=0; i<2200; i++){
+    fNdet[i]=0;
+    fNlayer[i]=0;
+  }
 }
 //----------------------------------------------------------------------
 AliITSClusterFinder::AliITSClusterFinder(AliITSDetTypeRec* dettyp,
                                         TClonesArray *digits):
 TObject(),
-fDebug(0),
 fModule(0),
 fDigits(digits),
 fNdigits(0),
 fDetTypeRec(dettyp),
 fClusters(0),
-fNRawClusters(0),
 fMap(0),
-fNperMax(0),
-fDeclusterFlag(0),
-fClusterSize(0),
-fNPeaks(-1){
+fNPeaks(-1),
+fNModules(AliITSgeomTGeo::GetNModules()),
+fEvent(0),
+fZmin(0),
+fZmax(0),
+fXmin(0),
+fXmax(0),
+fNClusters(0),
+fRawID2ClusID(0)
+{
+    // default cluster finder
     // Standard + cluster finder constructor
     // Input:
     //   AliITSsegmentation *seg  The segmentation class to be used
@@ -106,19 +133,37 @@ fNPeaks(-1){
     // Return:
     //   A Standard constructed AliITSCulsterFinder
 
-    fNdigits = fDigits->GetEntriesFast();
-    SetNperMax();
-    SetClusterSize();
-    SetDeclusterFlag();
+  fNdigits = fDigits->GetEntriesFast();
+  for(Int_t i=0; i<2200; i++){
+    fNdet[i]=0;
+    fNlayer[i]=0;
+  }
 }
-/*
+
 //______________________________________________________________________
-AliITSClusterFinder::AliITSClusterFinder(const AliITSClusterFinder &source) : TObject(source) {
+AliITSClusterFinder::AliITSClusterFinder(const AliITSClusterFinder &source) : 
+  TObject(source),
+  fModule(source.fModule),
+  fDigits(),
+  fNdigits(source.fNdigits),
+  fDetTypeRec(),
+  fClusters(),
+  fMap(),
+  fNPeaks(source.fNPeaks),
+  fNModules(source.fNModules),
+  fEvent(source.fEvent),
+  fZmin(source.fZmin),
+  fZmax(source.fZmax),
+  fXmin(source.fXmin),
+  fXmax(source.fXmax),
+  fNClusters(source.fNClusters),
+  fRawID2ClusID(source.fRawID2ClusID) 
+{
   // Copy constructor
   // Copies are not allowed. The method is protected to avoid misuse.
-  Fatal("AliITSClusterFinder","Copy constructor not allowed\n");
+  AliError("Copy constructor not allowed\n");
 }
-*/
+
 
 //______________________________________________________________________
 //AliITSClusterFinder& AliITSClusterFinder::operator=(const AliITSClusterFinder& /* source */){
@@ -143,10 +188,6 @@ AliITSClusterFinder::~AliITSClusterFinder(){
     fMap          = 0;
     fDigits       = 0;
     fNdigits      = 0;
-    fNRawClusters = 0;
-    fNperMax      = 0;
-    fDeclusterFlag= 0;
-    fClusterSize  = 0;
     fNPeaks       = 0;
     fDetTypeRec   = 0;
 
@@ -159,9 +200,6 @@ void AliITSClusterFinder::InitGeometry(){
   Int_t mmax=AliITSgeomTGeo::GetNModules();
   for (Int_t m=0; m<mmax; m++) {
     Int_t lay,lad,det; AliITSgeomTGeo::GetModuleId(m,lay,lad,det);
-    const TGeoHMatrix *tm=AliITSgeomTGeo::GetTracking2LocalMatrix(m);
-    fYshift[m] = (tm->Inverse()).GetTranslation()[1];
-    fZshift[m] = (tm->Inverse()).GetTranslation()[2];
     fNdet[m] = (lad-1)*AliITSgeomTGeo::GetNDetectors(lay) + (det-1);
     fNlayer[m] = lay-1;
   }
@@ -169,174 +207,7 @@ void AliITSClusterFinder::InitGeometry(){
 
 
 
-//----------------------------------------------------------------------
-void AliITSClusterFinder::AddCluster(Int_t branch, AliITSRawCluster *c){
-    // Add a raw cluster copy to the list
-    // Input:
-    //   Int_t       branch  The branch to which the cluster is to be added to
-    //   AliITSRawCluster *c The cluster to be added to the array of clusters
-    // Output:
-    //   none.
-    // Return:
-    //   none.
 
-   if(!fDetTypeRec) {
-    Error("AddCluster","fDetTypeRec is null!");
-    return;
-  }
-  fDetTypeRec->AddCluster(branch,c); 
-  fNRawClusters++;
-}
-//----------------------------------------------------------------------
-void AliITSClusterFinder::AddCluster(Int_t branch, AliITSRawCluster *c, 
-                                    AliITSRecPoint &rp){
-    // Add a raw cluster copy to the list and the RecPoint
-    // Input:
-    //   Int_t       branch  The branch to which the cluster is to be added to
-    //   AliITSRawCluster *c The cluster to be added to the array of clusters
-    //   AliITSRecPoint  &rp The RecPoint to be added to the array of RecPoints
-    // Output:
-    //   none.
-    // Return:
-    //   none.
-  if(!fDetTypeRec) {
-    Error("AddCluster","fDetTypeRec is null!");
-    return;
-  }
-
-  fDetTypeRec->AddCluster(branch,c); 
-  fNRawClusters++;
-  fDetTypeRec->AddRecPoint(rp); 
-
-}
-/*
-//______________________________________________________________________
-void AliITSClusterFinder::CheckLabels(Int_t lab[3]) {
-  //------------------------------------------------------------
-  // Tries to find mother's labels
-  //------------------------------------------------------------
-
-  if(lab[0]<0 && lab[1]<0 && lab[2]<0) return; // In case of no labels just exit
-  // Check if simulation
-  AliMC* mc = gAlice->GetMCApp();
-  if(!mc)return;
-
-  Int_t ntracks = mc->GetNtrack();
-  for (Int_t i=0;i<3;i++){
-    Int_t label = lab[i];
-    if (label>=0 && label<ntracks) {
-      TParticle *part=(TParticle*)mc->Particle(label);
-      if (part->P() < 0.005) {
-       Int_t m=part->GetFirstMother();
-       if (m<0) {      
-         continue;
-       }
-       if (part->GetStatusCode()>0) {
-         continue;
-       }
-       lab[i]=m;       
-      }
-    }    
-  }
-  
-}
-*/
-//______________________________________________________________________
-void AliITSClusterFinder::FindRawClusters(Int_t module){
-    // Default Cluster finder.
-    // Input:
-    //   Int_t module   Module number for which culster are to be found.
-    // Output:
-    //   none.
-    // Return:
-    //   none.
-    const Int_t kelms = 10;
-    Int_t ndigits = fDigits->GetEntriesFast();
-    TObjArray *digs = new TObjArray(ndigits);
-    TObjArray *clusts = new TObjArray(ndigits); // max # cluster
-    TObjArray *clust0=0; // A spacific cluster of digits
-    TObjArray *clust1=0; // A spacific cluster of digits
-    AliITSdigit *dig=0; // locat pointer to a digit
-    Int_t i=0,nc=0,j[4],k,k2=0;
-
-    // Copy all digits for this module into a local TObjArray.
-    for(i=0;i<ndigits;i++) digs->AddAt(new AliITSdigit(*(GetDigit(i))),i);
-    digs->Sort();
-    // First digit is a cluster.
-    i  = 0;
-    nc = 0;
-    clusts->AddAt(new TObjArray(kelms),nc);
-    clust0 = (TObjArray*)(clusts->At(nc));
-    clust0->AddAtFree(digs->At(i)); // move owner ship from digs to clusts
-    nc++;
-    for(i=1;i<ndigits;i++){
-        if(IsNeighbor(digs,i,j)){
-            dig = (AliITSdigit*)(digs->At(j[0]));
-            // Add to existing cluster. Find which cluster this digis 
-            for(k=0;k<nc;k++){
-                clust0 = ((TObjArray*)(clusts->At(k)));
-                if(clust0->IndexOf(dig)>=0) break;
-            } // end for k
-            if(k>=nc){
-                Fatal("FindRawClusters","Digit not found as expected");
-            } // end if
-            if(j[1]>=0){
-                dig = (AliITSdigit*)(digs->At(j[1]));
-                // Add to existing cluster. Find which cluster this digis 
-                for(k2=0;k2<nc;k2++){
-                    clust1 = ((TObjArray*)(clusts->At(k2)));
-                    if(clust1->IndexOf(dig)>=0) break;
-                } // end for k2
-                if(k2>=nc){
-                    Fatal("FindRawClusters","Digit not found as expected");
-                } // end if
-            } // end if j[1]>=0
-            // Found cluster with neighboring digits add this one to it.
-            if(clust0==clust1){ // same cluster
-                clust0->AddAtFree(digs->At(i));
-                clust0 = 0; // finished with cluster. zero for safty
-                clust1 = 0; // finished wit hcluster. zero for safty
-            }else{ // two different clusters which need to be merged.
-                clust0->AddAtFree(digs->At(i)); // Add digit to this cluster.
-                for(k=0;k<clust1->GetEntriesFast();k++){
-                    // move clust1 into clust0
-                    //move digit to this cluster
-                    clust0->AddAtFree(clust1->At(k));
-                    clust1->AddAt(0,k); // zero this one
-                } // end for k
-                delete clust1;
-                clusts->AddAt(0,k2); // zero array of clusters element clust1
-                clust0 = 0; // finished with cluster. zero for safty
-                clust1 = 0; // finished wit hcluster. zero for safty
-            } // end if clust0==clust1
-        }else{// New cluster
-            clusts->AddAt(new TObjArray(kelms),nc);
-            clust0 = ((TObjArray*)(clusts->At(nc)));
-            // move owner ship from digs to clusts
-            clust0->AddAtFree(digs->At(i));
-            clust0 = 0; // finished with cluster. zero for safty
-            nc++;
-        } // End if IsNeighbor
-    } // end for i
-    // There are now nc clusters in clusts. Each element of clust is an
-    // array of digits which are clustered together.
-
-    // For each cluster call detector specific CreateRecPoints
-    for(i=0;i<nc;i++) CreateRecPoints((TObjArray*)(clusts->At(i)),module);
-
-    // clean up at the end.
-    for(i=0;i<nc;i++){ 
-        clust0 =(TObjArray*)(clusts->At(i));
-        // Digits deleted below, so zero this TObjArray
-        for(k=0;k<clust0->GetEntriesFast();k++) clust0->AddAt(0,k);
-        delete clust0; // Delete this TObjArray
-        clusts->AddAt(0,i); // Contents deleted above, so zero it.
-    } // end for i
-    delete clusts; // Delete this TObjArray/
-    // Delete the digits then the TObjArray which containted them.
-    for(i=0;i<ndigits;i++) delete ((AliITSdigit*)(digs->At(i)));
-    delete digs;
-}
 //______________________________________________________________________
 Bool_t AliITSClusterFinder::IsNeighbor(TObjArray *digs,Int_t i,Int_t n[])const{
     // Locagical function which checks to see if digit i has a neighbor.
@@ -391,13 +262,8 @@ void AliITSClusterFinder::Print(ostream *os) const{
     // Return:
     //    none.
 
-    *os << fDebug<<",";
     *os << fModule<<",";
     *os << fNdigits<<",";
-    *os << fNRawClusters<<",";
-    *os << fNperMax<<",";
-    *os << fDeclusterFlag<<",";
-    *os << fClusterSize<<",";
     *os << fNPeaks<<endl;
 }
 //______________________________________________________________________
@@ -410,13 +276,8 @@ void AliITSClusterFinder::Read(istream *is)  {
     // Return:
     //    none.
 
-    *is >> fDebug;
     *is >> fModule;
     *is >> fNdigits;
-    *is >> fNRawClusters;
-    *is >> fNperMax;
-    *is >> fDeclusterFlag;
-    *is >> fClusterSize;
     *is >> fNPeaks;
 }
 //______________________________________________________________________
@@ -447,3 +308,192 @@ istream &operator>>(istream &is,AliITSClusterFinder &source){
     source.Read(&is);
     return is;
 }
+
+//______________________________________________________________________
+void AliITSClusterFinder::CheckLabels2(Int_t lab[10]) 
+{
+  //------------------------------------------------------------
+  // Tries to find mother's labels
+  //------------------------------------------------------------
+  AliRunLoader *rl = AliRunLoader::Instance();
+  if(!rl) return;
+  TTree *trK=(TTree*)rl->TreeK();
+  if (!trK) return;
+  //
+  int labS[10];
+  Int_t nlabels = 0; 
+  Int_t ntracks = gAlice->GetMCApp()->GetNtrack();
+  for (Int_t i=0;i<10;i++) if (lab[i]>=0) labS[nlabels++] = lab[i];
+  if (nlabels==0) return;
+  //
+  float mom[10];
+  for (Int_t i=0;i<nlabels;i++) {
+    Int_t label = labS[i];
+    mom[i] = 0;
+    if (label>=ntracks) continue;
+    TParticle *part=(TParticle*)gAlice->GetMCApp()->Particle(label);
+    mom[i] = part->P();
+    if (part->P() < 0.02) {    // reduce soft particles from the same cluster
+      Int_t m=part->GetFirstMother();
+      if (m<0) continue; // primary
+      //
+      if (part->GetStatusCode()>0) continue;
+      //
+      // if the parent is within the same cluster, reassign the label to it
+      for (int j=0;j<nlabels;j++) if (labS[j]==m) { labS[i] = m; break;        }
+    }
+  } 
+  //
+  if (nlabels>3) { // only 3 labels are stored in cluster, sort in decreasing momentum
+    int ind[10],labSS[10];
+    TMath::Sort(nlabels,mom,ind);
+    for (int i=nlabels;i--;) labSS[i] = labS[i];
+    for (int i=0;i<nlabels;i++) labS[i] = labSS[ind[i]]; 
+  }
+  //
+  //compress labels -- if multi-times the same
+  for (Int_t i=0;i<10;i++) lab[i]=-2;
+  int nlabFin=0,j=0;
+  for (int i=0;i<nlabels;i++) {
+    for (j=0;j<nlabFin;j++) if (labS[i]==lab[j]) break; // the label already there
+    if (j==nlabFin) lab[nlabFin++] = labS[i];
+  }
+  //
+}
+
+//______________________________________________________________________
+void AliITSClusterFinder::AddLabel(Int_t lab[10], Int_t label) {
+  //add label to the cluster
+  AliRunLoader *rl = AliRunLoader::Instance();
+  TTree *trK=(TTree*)rl->TreeK();
+  if(trK){
+    if(label<0) return; // In case of no label just exit
+
+    Int_t ntracks = gAlice->GetMCApp()->GetNtrack();
+    if (label>ntracks) return;
+    for (Int_t i=0;i<10;i++){
+      //    if (label<0) break;
+      if (lab[i]==label) break;
+      if (lab[i]<0) {
+       lab[i]= label;
+       break;
+      }
+    }
+  }
+}
+
+
+//______________________________________________________________________
+void AliITSClusterFinder:: 
+FindCluster(Int_t k,Int_t maxz,AliBin *bins,Int_t &n,Int_t *idx) {
+  //------------------------------------------------------------
+  // returns an array of indices of digits belonging to the cluster
+  // (needed when the segmentation is not regular) 
+  //------------------------------------------------------------
+  if (n<200) idx[n++]=bins[k].GetIndex();
+  bins[k].Use();
+
+  if (bins[k-maxz].IsNotUsed()) FindCluster(k-maxz,maxz,bins,n,idx);
+  if (bins[k-1   ].IsNotUsed()) FindCluster(k-1   ,maxz,bins,n,idx);
+  if (bins[k+maxz].IsNotUsed()) FindCluster(k+maxz,maxz,bins,n,idx);
+  if (bins[k+1   ].IsNotUsed()) FindCluster(k+1   ,maxz,bins,n,idx);
+  /*
+  if (bins[k-maxz-1].IsNotUsed()) FindCluster(k-maxz-1,maxz,bins,n,idx);
+  if (bins[k-maxz+1].IsNotUsed()) FindCluster(k-maxz+1,maxz,bins,n,idx);
+  if (bins[k+maxz-1].IsNotUsed()) FindCluster(k+maxz-1,maxz,bins,n,idx);
+  if (bins[k+maxz+1].IsNotUsed()) FindCluster(k+maxz+1,maxz,bins,n,idx);
+  */
+}
+
+//______________________________________________________________________
+Bool_t AliITSClusterFinder::IsMaximum(Int_t k,Int_t max,const AliBin *bins) {
+  //------------------------------------------------------------
+  //is this a local maximum ?
+  //------------------------------------------------------------
+  UShort_t q=bins[k].GetQ();
+  if (q==1023) return kFALSE;
+  if (bins[k-max].GetQ() > q) return kFALSE;
+  if (bins[k-1  ].GetQ() > q) return kFALSE; 
+  if (bins[k+max].GetQ() > q) return kFALSE; 
+  if (bins[k+1  ].GetQ() > q) return kFALSE; 
+  if (bins[k-max-1].GetQ() > q) return kFALSE;
+  if (bins[k+max-1].GetQ() > q) return kFALSE; 
+  if (bins[k+max+1].GetQ() > q) return kFALSE; 
+  if (bins[k-max+1].GetQ() > q) return kFALSE;
+  return kTRUE; 
+}
+
+//______________________________________________________________________
+void AliITSClusterFinder::
+FindPeaks(Int_t k,Int_t max,AliBin *b,Int_t *idx,UInt_t *msk,Int_t& n) {
+  //------------------------------------------------------------
+  //find local maxima
+  //------------------------------------------------------------
+  if (n<31)
+  if (IsMaximum(k,max,b)) {
+    idx[n]=k; msk[n]=(2<<n);
+    n++;
+  }
+  b[k].SetMask(0);
+  if (b[k-max].GetMask()&1) FindPeaks(k-max,max,b,idx,msk,n);
+  if (b[k-1  ].GetMask()&1) FindPeaks(k-1  ,max,b,idx,msk,n);
+  if (b[k+max].GetMask()&1) FindPeaks(k+max,max,b,idx,msk,n);
+  if (b[k+1  ].GetMask()&1) FindPeaks(k+1  ,max,b,idx,msk,n);
+}
+
+//______________________________________________________________________
+void AliITSClusterFinder::
+MarkPeak(Int_t k, Int_t max, AliBin *bins, UInt_t m) {
+  //------------------------------------------------------------
+  //mark this peak
+  //------------------------------------------------------------
+  UShort_t q=bins[k].GetQ();
+
+  bins[k].SetMask(bins[k].GetMask()|m); 
+
+  if (bins[k-max].GetQ() <= q)
+     if ((bins[k-max].GetMask()&m) == 0) MarkPeak(k-max,max,bins,m);
+  if (bins[k-1  ].GetQ() <= q)
+     if ((bins[k-1  ].GetMask()&m) == 0) MarkPeak(k-1  ,max,bins,m);
+  if (bins[k+max].GetQ() <= q)
+     if ((bins[k+max].GetMask()&m) == 0) MarkPeak(k+max,max,bins,m);
+  if (bins[k+1  ].GetQ() <= q)
+     if ((bins[k+1  ].GetMask()&m) == 0) MarkPeak(k+1  ,max,bins,m);
+}
+
+//______________________________________________________________________
+void AliITSClusterFinder::
+MakeCluster(Int_t k,Int_t max,AliBin *bins,UInt_t m,AliITSRecPoint &c) {
+  //------------------------------------------------------------
+  //make cluster using digits of this peak
+  //------------------------------------------------------------
+  Float_t q=(Float_t)bins[k].GetQ();
+  Int_t i=k/max, j=k-i*max;
+  if(c.GetQ()<0.01){ // first entry in cluster
+    fXmin=i;
+    fXmax=i;
+    fZmin=j;
+    fZmax=j;
+  }else{  // check cluster extension
+    if(i<fXmin) fXmin=i;
+    if(i>fXmax) fXmax=i;
+    if(j<fZmin) fZmin=j;
+    if(j>fZmax) fZmax=j;
+  }
+  c.SetQ(c.GetQ()+q);
+  c.SetY(c.GetY()+i*q);
+  c.SetZ(c.GetZ()+j*q);
+  c.SetSigmaY2(c.GetSigmaY2()+i*i*q);
+  c.SetSigmaZ2(c.GetSigmaZ2()+j*j*q);
+
+  bins[k].SetMask(0xFFFFFFFE);
+  if (fRawID2ClusID) { // RS: Register cluster id in raw words list
+    int rwid = bins[k].GetRawID();
+    if (fRawID2ClusID->GetSize()<=rwid) fRawID2ClusID->Set( (rwid+10)<<1 );
+    (*fRawID2ClusID)[rwid] = fNClusters+1; // RS: store clID+1 as a reference to the cluster
+  }
+  if (bins[k-max].GetMask() == m) MakeCluster(k-max,max,bins,m,c);
+  if (bins[k-1  ].GetMask() == m) MakeCluster(k-1  ,max,bins,m,c);
+  if (bins[k+max].GetMask() == m) MakeCluster(k+max,max,bins,m,c);
+  if (bins[k+1  ].GetMask() == m) MakeCluster(k+1  ,max,bins,m,c);
+}