]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ITS/AliITSClusterFinderV2SDD.cxx
Stupid bug fix in new superlight mode (from Zurich airport)
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinderV2SDD.cxx
index 9bc7e4ea465814348ac1f2f8565c9a0dd8a182ec..21a4880d2bb1b81d75b87936897875314369534f 100644 (file)
@@ -12,6 +12,9 @@
  * about the suitability of this software for any purpose. It is          *
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
+
+/* $Id$*/
+
 ////////////////////////////////////////////////////////////////////////////
 //            Implementation of the ITS clusterer V2 class                //
 //                                                                        //
 
 
 
+#include <TClonesArray.h>
+#include <TBits.h>
 #include "AliITSClusterFinderV2SDD.h"
-#include "AliITSclusterV2.h"
+#include "AliITSRecPoint.h"
+#include "AliITSRecPointContainer.h"
 #include "AliITSDetTypeRec.h"
 #include "AliRawReader.h"
 #include "AliITSRawStreamSDD.h"
-
-#include <TClonesArray.h>
+#include "AliITSRawStreamSDDCompressed.h"
+#include "AliITSCalibrationSDD.h"
+#include "AliITSresponseSDD.h"
+#include "AliITSDetTypeRec.h"
+#include "AliITSReconstructor.h"
+#include "AliITSsegmentationSDD.h"
 #include "AliITSdigitSDD.h"
+#include "AliITSgeomTGeo.h"
 
 ClassImp(AliITSClusterFinderV2SDD)
 
-extern AliRun *gAlice;
-
-AliITSClusterFinderV2SDD::AliITSClusterFinderV2SDD(AliITSgeom* geom):AliITSClusterFinderV2(geom){
-
+AliITSClusterFinderV2SDD::AliITSClusterFinderV2SDD(AliITSDetTypeRec* dettyp):AliITSClusterFinder(dettyp),
+  fNAnodes(0),
+  fNTimeBins(0),
+  fNZbins(0),
+  fNXbins(0),
+  fCutOnPeakLoose(0.),
+  fCutOnPeakTight(0.),
+  fMaxDrTimeForTightCut(0.)
+{
   //Default constructor
 
-  fNySDD=256; fNzSDD=256;
-  fYpitchSDD=0.01825;
-  fZpitchSDD=0.02940;
-  fHwSDD=3.5085; fHlSDD=3.7632;
-  fYoffSDD=0.0425;
-
-
-
+  fNAnodes = GetSeg()->NpzHalf();
+  fNZbins = fNAnodes+2;
+  fNTimeBins = GetSeg()->Npx();
+  fNXbins = fNTimeBins+2;
+  AliDebug(2,Form("Cells in SDD cluster finder: Andoes=%d  TimeBins=%d",fNAnodes,fNTimeBins));
+  const Int_t kMaxBin=fNZbins*fNXbins;
+  for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++){
+   fDDLBins[iHyb]=new AliBin[kMaxBin];
+  }
+  SetPeakSelection(15.,30.,2000.);
 }
  
 
+//______________________________________________________________________
+AliITSClusterFinderV2SDD::~AliITSClusterFinderV2SDD()
+{
+  //Destructor
+  for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++){ 
+    delete [] fDDLBins[iHyb];
+  }
+}
+
+//______________________________________________________________________
 void AliITSClusterFinderV2SDD::FindRawClusters(Int_t mod){
 
   //Find clusters V2
@@ -57,268 +85,429 @@ void AliITSClusterFinderV2SDD::FindRawClusters(Int_t mod){
 
 }
 
+//______________________________________________________________________
 void AliITSClusterFinderV2SDD::FindClustersSDD(TClonesArray *digits) {
   //------------------------------------------------------------
   // Actual SDD cluster finder
   //------------------------------------------------------------
-  Int_t kNzBins = fNzSDD + 2;
-  const Int_t kMAXBIN=kNzBins*(fNySDD+2);
 
+  const Int_t kMaxBin=fNZbins*fNXbins;
   AliBin *bins[2];
-  bins[0]=new AliBin[kMAXBIN];
-  bins[1]=new AliBin[kMAXBIN];
+  bins[0]=new AliBin[kMaxBin];
+  bins[1]=new AliBin[kMaxBin];
+  TBits *anodeFired[2];
+  anodeFired[0]=new TBits(fNAnodes);
+  anodeFired[1]=new TBits(fNAnodes);
+  anodeFired[0]->ResetAllBits();
+  anodeFired[1]->ResetAllBits();
+  AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(fModule);
+  if(cal==0){
+    AliError(Form("Calibration object not present for SDD module %d\n",fModule));
+    return;
+  }
 
   AliITSdigitSDD *d=0;
   Int_t i, ndigits=digits->GetEntriesFast();
   for (i=0; i<ndigits; i++) {
      d=(AliITSdigitSDD*)digits->UncheckedAt(i);
-     Int_t y=d->GetCoord2()+1;   //y
-     Int_t z=d->GetCoord1()+1;   //z
-     Int_t q=d->GetSignal();
-     if (q<3) continue;
-
-     if (z <= fNzSDD) {
-       bins[0][y*kNzBins+z].SetQ(q);
-       bins[0][y*kNzBins+z].SetMask(1);
-       bins[0][y*kNzBins+z].SetIndex(i);
-     } else {
-       z-=fNzSDD; 
-       bins[1][y*kNzBins+z].SetQ(q);
-       bins[1][y*kNzBins+z].SetMask(1);
-       bins[1][y*kNzBins+z].SetIndex(i);
+     Int_t ian=d->GetCoord1();
+     Int_t itb=d->GetCoord2();
+     //Int_t iSide=0;
+     //if (ian >= fNAnodes) iSide=1;    
+     Float_t gain=cal->GetChannelGain(ian)/fDetTypeRec->GetAverageGainSDD();
+     Float_t charge=d->GetSignal(); // returns expanded signal 
+                                    // (10 bit, low threshold already added)
+     Float_t baseline = cal->GetBaseline(ian);
+     if(charge>baseline) charge-=baseline;
+     else charge=0;
+
+     if(gain>0.){ // Bad channels have gain=0.
+       charge/=gain;
+       if(charge<cal->GetThresholdAnode(ian)) continue;
+       Int_t q=(Int_t)(charge+0.5);
+       Int_t y=itb+1;   
+       Int_t z=ian+1;   
+       if (z <= fNAnodes){
+        bins[0][y*fNZbins+z].SetQ(q);
+        bins[0][y*fNZbins+z].SetMask(1);
+        bins[0][y*fNZbins+z].SetIndex(i);
+        anodeFired[0]->SetBitNumber(ian);
+       } else {
+        z-=fNAnodes;
+        bins[1][y*fNZbins+z].SetQ(q);
+        bins[1][y*fNZbins+z].SetMask(1);
+        bins[1][y*fNZbins+z].SetIndex(i);
+        anodeFired[1]->SetBitNumber(ian-fNAnodes);
+       }
      }
   }
   
-  FindClustersSDD(bins, kMAXBIN, kNzBins, digits);
+  FindClustersSDD(bins, anodeFired, digits);
 
   delete[] bins[0];
   delete[] bins[1];
+  delete anodeFired[0];
+  delete anodeFired[1];
 
 }
 
+//______________________________________________________________________
 void AliITSClusterFinderV2SDD::
-FindClustersSDD(AliBin* bins[2], Int_t nMaxBin, Int_t nzBins, 
-               TClonesArray *digits, TClonesArray *clusters) {
+FindClustersSDD(AliBin* bins[2], TBits* anodeFired[2],  
+               TClonesArray *digits, TClonesArray *clusters, Int_t jitter) {
   //------------------------------------------------------------
   // Actual SDD cluster finder
   //------------------------------------------------------------
+
+  static AliITSRecoParam *repa = NULL;
+  if(!repa){
+    repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
+    if(!repa){
+      repa = AliITSRecoParam::GetHighFluxParam();
+      AliWarning("Using default AliITSRecoParam class");
+    }
+  }
+  const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(fModule);
+  AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(fModule);
+  if(cal==0){
+    AliError(Form("Calibration object not present for SDD module %d\n",fModule));
+    return;
+  }
+  const Int_t kMaxBin=fNZbins*fNXbins;
   Int_t ncl=0; 
   TClonesArray &cl=*clusters;
-  for (Int_t s=0; s<2; s++)
-    for (Int_t i=0; i<nMaxBin; i++) {
-      if (bins[s][i].IsUsed()) continue;
-      Int_t idx[32]; UInt_t msk[32]; Int_t npeaks=0;
-      FindPeaks(i, nzBins, bins[s], idx, msk, npeaks);
-
-      if (npeaks>30) continue;
-      if (npeaks==0) continue;
-
-      Int_t k,l;
-      for (k=0; k<npeaks-1; k++){//mark adjacent peaks
-        if (idx[k] < 0) continue; //this peak is already removed
-        for (l=k+1; l<npeaks; l++) {
-           if (idx[l] < 0) continue; //this peak is already removed
-           Int_t ki=idx[k]/nzBins, kj=idx[k] - ki*nzBins;
-           Int_t li=idx[l]/nzBins, lj=idx[l] - li*nzBins;
-           Int_t di=TMath::Abs(ki - li);
-           Int_t dj=TMath::Abs(kj - lj);
-           if (di>1 || dj>1) continue;
-           if (bins[s][idx[k]].GetQ() > bins[s][idx[l]].GetQ()) {
-              msk[l]=msk[k];
-              idx[l]*=-1;
-           } else {
-              msk[k]=msk[l];
-              idx[k]*=-1;
-              break;
-           } 
-        }
-      }
-
-      for (k=0; k<npeaks; k++) {
-        MarkPeak(TMath::Abs(idx[k]), nzBins, bins[s], msk[k]);
-      }
-        
-      for (k=0; k<npeaks; k++) {
-         if (idx[k] < 0) continue; //removed peak
-         AliITSclusterV2 c;
-         MakeCluster(idx[k], nzBins, bins[s], msk[k], c);
-        //mi change
-        Int_t milab[10];
-        for (Int_t ilab=0;ilab<10;ilab++){
-          milab[ilab]=-2;
-        }
-        Int_t maxi=0,mini=0,maxj=0,minj=0;
-        //AliBin *bmax=&bins[s][idx[k]];
-        //Float_t max = TMath::Max(TMath::Abs(bmax->GetQ())/5.,3.);
-        Float_t max=3;
-        for (Int_t di=-2; di<=2;di++)
-          for (Int_t dj=-3;dj<=3;dj++){
-            Int_t index = idx[k]+di+dj*nzBins;
-            if (index<0) continue;
-            if (index>=nMaxBin) continue;
-            AliBin *b=&bins[s][index];
-            if (TMath::Abs(b->GetQ())>max){
-              if (di>maxi) maxi=di;
-              if (di<mini) mini=di;
-              if (dj>maxj) maxj=dj;
-              if (dj<minj) minj=dj;
-              //
-              if(digits) {
-                if (TMath::Abs(di)<2&&TMath::Abs(dj)<2){
-                  AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-                  for (Int_t itrack=0;itrack<10;itrack++){
-                    Int_t track = (d->GetTracks())[itrack];
-                    if (track>=0) {
-                      AddLabel(milab, track); 
-                    }
-                  }
-                }
-              }
-            }
-          }
-        
-        /* 
-           Float_t s2 = c.GetSigmaY2()/c.GetQ() - c.GetY()*c.GetY();
-           Float_t w=par->GetPadPitchWidth(sec);
-           c.SetSigmaY2(s2);
-           if (s2 != 0.) {
-           c.SetSigmaY2(c.GetSigmaY2()*0.108);
-           if (sec<par->GetNInnerSector()) c.SetSigmaY2(c.GetSigmaY2()*2.07);
-           }    
-           s2 = c.GetSigmaZ2()/c.GetQ() - c.GetZ()*c.GetZ();
-           w=par->GetZWidth();
-           c.SetSigmaZ2(s2);
-           
-           if (s2 != 0.) {
-           c.SetSigmaZ2(c.GetSigmaZ2()*0.169);
-           if (sec<par->GetNInnerSector()) c.SetSigmaZ2(c.GetSigmaZ2()*1.77);
+  for (Int_t s=0; s<2; s++){
+    for(Int_t iAnode=0; iAnode<GetSeg()->NpzHalf(); iAnode++){
+      if(anodeFired[s]->TestBitNumber(iAnode)==kFALSE) continue;
+      for(Int_t iTimeBin=0; iTimeBin<GetSeg()->Npx(); iTimeBin++){
+       Int_t index=(iTimeBin+1)*fNZbins+(iAnode+1);
+       if (bins[s][index].IsUsed()) continue;
+       if(NoiseSuppress(index,s,bins[s],cal)) continue;
+       Int_t idx[32]; UInt_t msk[32]; Int_t npeaks=0;
+       FindPeaks(index, fNZbins, bins[s], idx, msk, npeaks);
+
+       if (npeaks>30) continue;
+       if (npeaks==0) continue;
+
+       Int_t k,l;
+       Int_t nClust;
+       if(repa->GetUseUnfoldingInClusterFinderSDD()){
+         for (k=0; k<npeaks-1; k++){//mark adjacent peaks          
+           if (idx[k] < 0) continue; //this peak is already removed
+           for (l=k+1; l<npeaks; l++) {
+             if (idx[l] < 0) continue; //this peak is already removed
+             Int_t ki=idx[k]/fNZbins, kj=idx[k] - ki*fNZbins;
+             Int_t li=idx[l]/fNZbins, lj=idx[l] - li*fNZbins;
+             Int_t di=TMath::Abs(ki - li);
+             Int_t dj=TMath::Abs(kj - lj);
+             if (di>1 || dj>1) continue;
+             if (bins[s][idx[k]].GetQ() > bins[s][idx[l]].GetQ()) {
+               msk[l]=msk[k];
+               idx[l]*=-1;
+             } else {
+               msk[k]=msk[l];
+               idx[k]*=-1;
+               break;
+             } 
+           }
+         }
+         nClust=npeaks;
+       }else{
+         for (k=1; k<npeaks; k++) msk[k]=msk[0];
+         nClust=1;
+       }
+       Float_t maxADC=0;
+       for (k=0; k<npeaks; k++) {
+         if(idx[k]>0. && bins[s][idx[k]].GetQ() > maxADC) maxADC=bins[s][idx[k]].GetQ();
+         MarkPeak(TMath::Abs(idx[k]), fNZbins, bins[s], msk[k]);
+       }
+       if(maxADC<fCutOnPeakLoose) continue;
+
+       for (k=0; k<nClust; k++) {
+         if (idx[k] < 0) continue; //removed peak
+         AliITSRecPoint c;
+         MakeCluster(idx[k], fNZbins, bins[s], msk[k], c);
+         //mi change
+         Int_t milab[10];
+         for (Int_t ilab=0;ilab<10;ilab++){
+           milab[ilab]=-2;
+         }
+         
+         if(digits) {
+           for (Int_t di=-2; di<=2;di++){
+             for (Int_t dj=-2;dj<=2;dj++){
+               index = idx[k]+di+dj*fNZbins;
+               if (index<0) continue;
+               if (index>=kMaxBin) continue;
+               AliBin *b=&bins[s][index];
+               if(b->GetQ()<0.1) continue;
+               AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
+               for (Int_t itrack=0;itrack<10;itrack++){
+                 Int_t track = (d->GetTracks())[itrack];
+                 if (track>=0) {
+                   AddLabel(milab, track); 
+                 }
+               }
+             }
            }
-        */
-
-         c.SetSigmaY2(0.0030*0.0030);
-         c.SetSigmaZ2(0.0020*0.0020);
-         c.SetDetectorIndex(fNdet[fModule]);
-
-         Float_t y=c.GetY(),z=c.GetZ(), q=c.GetQ();
-         y/=q; z/=q;
-        //
-        //Float_t s2 = c.GetSigmaY2()/c.GetQ() - y*y;
-        // c.SetSigmaY2(s2);
-        //s2 = c.GetSigmaZ2()/c.GetQ() - z*z;
-         //c.SetSigmaZ2(s2);
-        //
-         y=(y-0.5)*fYpitchSDD;
-         y-=fHwSDD;
-         y-=fYoffSDD;  //delay ?
-         if (s) y=-y;
-
-         z=(z-0.5)*fZpitchSDD;
-         z-=fHlSDD;
-
-         y=-(-y+fYshift[fModule]);
-         z=  -z+fZshift[fModule];
-         c.SetY(y);
-         c.SetZ(z);
-        c.SetNy(maxj-minj+1);
-        c.SetNz(maxi-mini+1);
-        c.SetType(npeaks);
-         c.SetQ(q/12.7);  //to be consistent with the SSD charges
-
-         if (c.GetQ() < 20.) continue; //noise cluster
-        
-        if (digits) {    
-          //      AliBin *b=&bins[s][idx[k]];
-          //      AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-          {
-            //Int_t lab[3];
-            //lab[0]=(d->GetTracks())[0];
-            //lab[1]=(d->GetTracks())[1];
-            //lab[2]=(d->GetTracks())[2];
-            //CheckLabels(lab);
-            CheckLabels2(milab); 
-            c.SetLabel(milab[0],0);
-            c.SetLabel(milab[1],1);
-            c.SetLabel(milab[2],2);
-            c.SetLayer(fNlayer[fModule]);
-          }
-        }
-        if(clusters) new (cl[ncl]) AliITSclusterV2(c); 
-        else {
-          fDetTypeRec->AddClusterV2(c);
-        }
-        ncl++;
+         } 
+         else { // raw data
+           if (fRawID2ClusID) milab[0] = fNClusters+1; // RS: store clID+1 as a reference to the cluster
+         }
+         
+
+         Int_t clSizAnode=fZmax-fZmin+1;
+         Int_t clSizTb=fXmax-fXmin+1;    
+         if(repa->GetUseSDDClusterSizeSelection()){
+           if(clSizTb==1) continue; // cut common mode noise spikes
+           if(clSizAnode>5)  continue; // cut common mode noise spikes
+           if(clSizTb>10)  continue; // cut clusters on noisy anodes
+           if(cal-> IsAMAt20MHz() && clSizTb>8)  continue; // cut clusters on noisy anodes
+         }
+         
+         AliITSresponseSDD* rsdd = fDetTypeRec->GetResponseSDD();
+         Float_t y=c.GetY(),z=c.GetZ(), q=c.GetQ();
+         y/=q; z/=q;
+         Float_t zAnode=z-0.5;  // to have anode in range 0.-255. and centered on the mid of the pitch
+         Float_t timebin=y-0.5;  // to have time bin in range 0.-255. amd centered on the mid of the bin
+         if(s==1) zAnode += GetSeg()->NpzHalf();  // right side has anodes from 256. to 511.
+         Float_t zdet = GetSeg()->GetLocalZFromAnode(zAnode);
+         Float_t driftTimeUncorr = GetSeg()->GetDriftTimeFromTb(timebin)+jitter*rsdd->GetCarlosRXClockPeriod();
+         Float_t driftTime=driftTimeUncorr-rsdd->GetTimeZero(fModule);
+         if(driftTime<fMaxDrTimeForTightCut && maxADC<fCutOnPeakTight) continue;
+
+         Float_t driftSpeed = cal->GetDriftSpeedAtAnode(zAnode) + rsdd->GetDeltaVDrift(fModule,zAnode>255);
+         Float_t driftPathMicron = driftTime*driftSpeed;
+         const Double_t kMicronTocm = 1.0e-4; 
+         Float_t xdet=(driftPathMicron-GetSeg()->Dx())*kMicronTocm; // xdet is negative
+         if (s==0) xdet=-xdet; // left side has positive local x
+         
+         if(repa->GetUseSDDCorrectionMaps()){
+           Float_t corrx=0, corrz=0;
+           cal->GetCorrections(zdet,xdet,corrz,corrx,GetSeg());
+           zdet+=corrz;
+           xdet+=corrx;
+         }
+         
+         Double_t loc[3]={xdet,0.,zdet},trk[3]={0.,0.,0.};
+         mT2L->MasterToLocal(loc,trk);
+         y=trk[1];
+         z=trk[2]; 
+         
+         q+=(driftTime*rsdd->GetADCvsDriftTime(fModule)); // correction for zero supp.
+         q/=rsdd->GetADCtokeV(fModule);
+         if(cal-> IsAMAt20MHz()) q*=2.; // account for 1/2 sampling freq.
+         if(q<repa->GetMinClusterChargeSDD()) continue; // remove noise clusters
+         
+         Float_t hit[6] = {y, z, 0.0030*0.0030, 0.0020*0.0020, q, 0.};
+         Int_t  info[3] = {clSizTb, clSizAnode, fNlayer[fModule]};
+         if (digits) CheckLabels2(milab);
+         milab[3]=fNdet[fModule];
+         AliITSRecPoint cc(milab,hit,info);
+         cc.SetType(nClust*100+npeaks);
+         cc.SetDriftTime(driftTimeUncorr);
+         cc.SetDriftSide(s);
+         cc.SetChargeRatio(maxADC);
+         if(clusters) new (cl[ncl]) AliITSRecPoint(cc); 
+         else {
+           fDetTypeRec->AddRecPoint(cc);
+         }
+         fNClusters++; // RS
+         ncl++;
+       }
       }
     }
-}
-
-
+  }
+  AliDebug(2,Form("Clusters found on SDD module %d (unfolding %d) = %d\n",fModule,repa->GetUseUnfoldingInClusterFinderSDD(),ncl));
 
-void AliITSClusterFinderV2SDD::RawdataToClusters(AliRawReader* rawReader,TClonesArray** clusters){
+} 
+//______________________________________________________________________
+void AliITSClusterFinderV2SDD::RawdataToClusters(AliRawReader* rawReader){
     //------------------------------------------------------------
   // This function creates ITS clusters from raw data
   //------------------------------------------------------------
-  rawReader->Reset();
-  AliITSRawStreamSDD inputSDD(rawReader);
-  FindClustersSDD(&inputSDD,clusters);
-
+  fNClusters = 0; //RS
+  AliITSRawStream* inputSDD=AliITSRawStreamSDD::CreateRawStreamSDD(rawReader);
+  AliDebug(1,Form("%s is used",inputSDD->ClassName()));
+
+  AliITSDDLModuleMapSDD *ddlmap=(AliITSDDLModuleMapSDD*)fDetTypeRec->GetDDLModuleMapSDD();
+  inputSDD->SetDDLModuleMap(ddlmap);
+  for(Int_t iddl=0; iddl<AliITSDDLModuleMapSDD::GetNDDLs(); iddl++){
+    for(Int_t icar=0; icar<AliITSDDLModuleMapSDD::GetNModPerDDL();icar++){
+      Int_t iMod=ddlmap->GetModuleNumber(iddl,icar);
+      if(iMod==-1) continue;
+      AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(iMod);
+      if(cal==0){
+       AliError(Form("Calibration object not present for SDD module %d\n",iMod));
+       continue;
+      }
+      Bool_t isZeroSupp=cal->GetZeroSupp();
+      if(isZeroSupp){ 
+       for(Int_t iSid=0; iSid<2; iSid++) inputSDD->SetZeroSuppLowThreshold(iMod-240,iSid,cal->GetZSLowThreshold(iSid));
+      }else{
+       for(Int_t iSid=0; iSid<2; iSid++) inputSDD->SetZeroSuppLowThreshold(iMod-240,iSid,0);
+      }
+    }
+  }
+  FindClustersSDD(inputSDD);
+  delete inputSDD;
 }
 
-void AliITSClusterFinderV2SDD::FindClustersSDD(AliITSRawStream* input, 
-                                       TClonesArray** clusters) 
+void AliITSClusterFinderV2SDD::FindClustersSDD(AliITSRawStream* input) 
 {
   //------------------------------------------------------------
   // Actual SDD cluster finder for raw data
   //------------------------------------------------------------
+  AliITSRecPointContainer* rpc = AliITSRecPointContainer::Instance();
   Int_t nClustersSDD = 0;
-  Int_t kNzBins = fNzSDD + 2;
-  Int_t kMaxBin = kNzBins * (fNySDD+2);
-  AliBin *binsSDDInit = new AliBin[kMaxBin];
-  AliBin *binsSDD1 = new AliBin[kMaxBin];
-  AliBin *binsSDD2 = new AliBin[kMaxBin];
-  AliBin* bins[2] = {NULL, NULL};
+  AliBin *bins[2];
+  TBits* anodeFired[2];
+  TBits* ddlAnodeFired[kHybridsPerDDL];
+  for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++){
+    ddlAnodeFired[iHyb]=new TBits(fNAnodes);
+    ddlAnodeFired[iHyb]->ResetAllBits();
+  }
+  Int_t vectModId[kModulesPerDDL];
+  for(Int_t iMod=0; iMod<kModulesPerDDL; iMod++) vectModId[iMod]=-1;
 
   // read raw data input stream
-  while (kTRUE) {
-    Bool_t next = input->Next();
-    if (!next || input->IsNewModule()) {
-      Int_t iModule = input->GetPrevModuleID();
-
-      // when all data from a module was read, search for clusters
-      if (bins[0]) { 
-       clusters[iModule] = new TClonesArray("AliITSclusterV2");
-       fModule = iModule;
-       FindClustersSDD(bins, kMaxBin, kNzBins, NULL, clusters[iModule]);
-       Int_t nClusters = clusters[iModule]->GetEntriesFast();
-       nClustersSDD += nClusters;
-       bins[0] = bins[1] = NULL;
-       
-      }
-
-      if (!next) break;
-      bins[0]=binsSDD1;
-      bins[1]=binsSDD2;
-      memcpy(binsSDD1,binsSDDInit,sizeof(AliBin)*kMaxBin);
-      memcpy(binsSDD2,binsSDDInit,sizeof(AliBin)*kMaxBin);
-
+  int countRW = 0; //RS
+  if (fRawID2ClusID) fRawID2ClusID->Reset(); //RS if array was provided, we shall store the rawID -> ClusterID
+  //
+  while (input->Next()) {
+    Int_t iModule = input->GetModuleID();
+    if(iModule<0){
+      AliWarning(Form("Invalid SDD module number %d\n", iModule));
+      continue;
     }
+    Int_t iCarlos =input->GetCarlosId();
+    Int_t iSide = input->GetChannel();
+    Int_t iHybrid=iCarlos*2+iSide;
 
+    if (input->IsCompletedModule()) {
+      // store the module number
+      vectModId[iCarlos]=iModule;
+    }
+    else if (input->IsCompletedDDL()) {
+      // when all data from a DDL was read, search for clusters
+      Int_t jitter=input->GetJitter();
+      for(Int_t iMod=0; iMod<kModulesPerDDL; iMod++){
+       if(vectModId[iMod]>=0){
+         fModule = vectModId[iMod];
+         TClonesArray* clusters = rpc->UncheckedGetClusters(fModule);
+         bins[0]=fDDLBins[iMod*2];   // first hybrid of the module
+         bins[1]=fDDLBins[iMod*2+1]; // second hybrid of the module
+         anodeFired[0]=ddlAnodeFired[iMod*2];
+         anodeFired[1]=ddlAnodeFired[iMod*2+1];
+         FindClustersSDD(bins, anodeFired, NULL, clusters,jitter);
+         Int_t nClusters = clusters->GetEntriesFast();
+         nClustersSDD += nClusters;
+         vectModId[iMod]=-1;
+       }
+       for (Int_t s=0; s<2; s++){
+         Int_t indexHyb=iMod*2+s;
+         for(Int_t iAnode=0; iAnode<GetSeg()->NpzHalf(); iAnode++){
+           if(ddlAnodeFired[indexHyb]->TestBitNumber(iAnode)==kFALSE) continue;
+           for(Int_t iTimeBin=0; iTimeBin<GetSeg()->Npx(); iTimeBin++){
+             Int_t index=(iTimeBin+1)*fNZbins+(iAnode+1);
+             fDDLBins[indexHyb][index].Reset();
+           }
+         }
+       }
+       ddlAnodeFired[iMod*2]->ResetAllBits();
+       ddlAnodeFired[iMod*2+1]->ResetAllBits();
+      }
+    }else{
     // fill the current digit into the bins array
-    if(input->GetSignal()>=3) {
-      Int_t iz = input->GetCoord1()+1;
-      Int_t side = ((iz <= fNzSDD) ? 0 : 1);
-      iz -= side*fNzSDD;
-      Int_t index = (input->GetCoord2()+1) * kNzBins + iz;
-      bins[side][index].SetQ(input->GetSignal());
-      bins[side][index].SetMask(1);
-      bins[side][index].SetIndex(index);
+      if(iHybrid<0 || iHybrid>=kHybridsPerDDL){ 
+       AliWarning(Form("Invalid SDD hybrid number %d on module %d\n", iHybrid,iModule));
+       continue;
+      }
+      AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(iModule);    
+      if(cal==0){
+       AliError(Form("Calibration object not present for SDD module %d\n",iModule));
+       continue;
+      }
+      Float_t charge=input->GetSignal();
+      Int_t chan=input->GetCoord1()+fNAnodes*iSide;
+      Float_t gain=cal->GetChannelGain(chan)/fDetTypeRec->GetAverageGainSDD();;
+      Float_t baseline = cal->GetBaseline(chan);
+      if(charge>baseline) charge-=baseline;
+      else charge=0;
+      if(gain>0.){ // Bad channels have gain=0
+       charge/=gain;
+       if(charge>=cal->GetThresholdAnode(chan)) {
+         Int_t q=(Int_t)(charge+0.5);
+         Int_t iz = input->GetCoord1();
+         Int_t itb = input->GetCoord2();
+         Int_t index = (itb+1) * fNZbins + (iz+1);
+         if((itb < fNTimeBins) && (iz < fNAnodes)) {
+           fDDLBins[iHybrid][index].SetQ(q);
+           fDDLBins[iHybrid][index].SetMask(1);
+           fDDLBins[iHybrid][index].SetIndex(index);
+           fDDLBins[iHybrid][index].SetRawID(countRW); //RS register raw id
+           ddlAnodeFired[iHybrid]->SetBitNumber(iz);
+         }else{
+           AliWarning(Form("Invalid SDD cell: Anode=%d   TimeBin=%d",iz,itb));   
+         }
+       }
+      }
     }
+    countRW++; //RS
   }
-  delete[] binsSDD1;
-  delete[] binsSDD2;
-  delete[] binsSDDInit;
-
-  Info("FindClustersSDD", "found clusters in ITS SDD: %d", nClustersSDD);
+  for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++){ 
+   delete ddlAnodeFired[iHyb];
+  }
+  AliDebug(1,Form("found clusters in ITS SDD: %d", nClustersSDD));
+}
 
+//______________________________________________________________________
+Bool_t AliITSClusterFinderV2SDD::NoiseSuppress(Int_t k, Int_t sid, AliBin* bins, const AliITSCalibrationSDD* cal) const {
+  // applies zero suppression using the measured noise of each anode
+  // threshold values from ALICE-INT-1999-28 V10
+  // returns kTRUE if the digit should eb noise suppressed, kFALSE if it should be kept
+  Float_t xfactL=2.2; 
+  Float_t xfactH=4.0;
+  //
+
+  Int_t iAn=(k%fNZbins)-1;
+  if(iAn<0 || iAn>255) return kTRUE;
+  if(sid==1) iAn+=256;
+  Int_t nLow=0, nHigh=0;
+  Float_t noise=cal->GetNoiseAfterElectronics(iAn);
+  Float_t noisem1=noise;
+  if(iAn>1) noisem1=cal->GetNoiseAfterElectronics(iAn-1);
+  Float_t noisep1=noise;
+  if(iAn<511) noisep1=cal->GetNoiseAfterElectronics(iAn+1);
+  Float_t tL=noise*xfactL;
+  Float_t tH=noise*xfactH;
+  Float_t tLp1=noisep1*xfactL;
+  Float_t tHp1=noisep1*xfactH;
+  Float_t tLm1=noisem1*xfactL;
+  Float_t tHm1=noisem1*xfactH;
+  Int_t cC=bins[k].GetQ();
+  if(cC<=tL){
+    bins[k].SetQ(0);
+    bins[k].SetMask(0xFFFFFFFE);
+    return kTRUE;;
+  }
+  nLow++; // cC is greater than tL
+  if(cC>tH) nHigh++;
+  Int_t sS=bins[k-1].GetQ();
+  if(sS>tLm1) nLow++;
+  if(sS>tHm1) nHigh++;
+  Int_t nN=bins[k+1].GetQ();
+  if(nN>tLp1) nLow++;
+  if(nN>tHp1) nHigh++;
+  Int_t eE=bins[k-fNZbins].GetQ();
+  if(eE>tL) nLow++;
+  if(eE>tH) nHigh++;
+  Int_t wW=bins[k+fNZbins].GetQ();
+  if(wW>tL) nLow++;
+  if(wW>tH) nHigh++;
+  if(nLow<2 || nHigh<1) return kTRUE;
+  else return kFALSE;
 }
 
 
+