]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ITS/AliITSclustererV2.cxx
speed optimization
[u/mrichter/AliRoot.git] / ITS / AliITSclustererV2.cxx
index db3d8c03ff673a7441d066950bdb0ae757792f17..3a72144719f5ea53533f7eb847ad2e231f1ad925 100644 (file)
 
 #include "AliITSclustererV2.h"
 #include "AliITSclusterV2.h"
+#include "AliRawReader.h"
+#include "AliITSRawStreamSPD.h"
+#include "AliITSRawStreamSDD.h"
+#include "AliITSRawStreamSSD.h"
 
-#include <Riostream.h>
 #include <TFile.h>
 #include <TTree.h>
 #include <TClonesArray.h>
 #include "AliITSgeom.h"
-#include "AliITSdigit.h"
+#include "AliITSdigitSPD.h"
+#include "AliITSdigitSDD.h"
+#include "AliITSdigitSSD.h"
+#include "AliMC.h"
 
 ClassImp(AliITSclustererV2)
 
@@ -32,16 +38,21 @@ AliITSclustererV2::AliITSclustererV2(const AliITSgeom *geom) {
   fI=0;
 
   Int_t mmax=geom->GetIndexMax();
-  if (mmax>2200) {cerr<<"Too many ITS subdetectors !\n"; exit(1);}
+  if (mmax>2200) {
+     Fatal("AliITSclustererV2","Too many ITS subdetectors !"); 
+  }
   Int_t m;
   for (m=0; m<mmax; m++) {
      Int_t lay,lad,det; g->GetModuleId(m,lay,lad,det);
      Float_t x,y,z;     g->GetTrans(lay,lad,det,x,y,z); 
      Double_t rot[9];   g->GetRotMatrix(lay,lad,det,rot);
-     fYshift[m] = x*rot[0] + y*rot[1];
+     Double_t alpha=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
+     Double_t ca=TMath::Cos(alpha), sa=TMath::Sin(alpha);
+     fYshift[m] = x*ca + y*sa;
      fZshift[m] = (Double_t)z;
      fNdet[m] = (lad-1)*g->GetNdetectors(lay) + (det-1);
   }
+  fNModules = g->GetIndexMax();
 
   //SPD geometry  
   fLastSPD1=g->GetModuleIndex(2,1,1)-1;
@@ -81,26 +92,16 @@ AliITSclustererV2::AliITSclustererV2(const AliITSgeom *geom) {
   fTanN=0.0075;
 }
 
-void AliITSclustererV2::Digits2Clusters(const TFile *in, TFile *out) {
+
+Int_t AliITSclustererV2::Digits2Clusters(TTree *dTree, TTree *cTree) {
   //------------------------------------------------------------
   // This function creates ITS clusters
   //------------------------------------------------------------
   Int_t ncl=0;
-  TDirectory *savedir=gDirectory;
-
-  if (!out->IsOpen()) {
-    cerr<<"AliITSclustererV2::Digits2Clusters(): output file not open !\n";
-    return;
-  }
 
-  Char_t name[100];
-  sprintf(name,"TreeD%d",fEvent);
-
-  //TTree *dTree=(TTree*)((TFile*)in)->Get(name);
-  TTree *dTree=gAlice->TreeD();
   if (!dTree) {
-    cerr<<"Input tree "<<name<<" not found !\n";
-    return;
+    Error("Digits2Clusters","Can't get the tree with digits !");
+    return 1;
   }
 
   TClonesArray *digitsSPD=new TClonesArray("AliITSdigitSPD",3000);
@@ -110,35 +111,35 @@ void AliITSclustererV2::Digits2Clusters(const TFile *in, TFile *out) {
   TClonesArray *digitsSSD=new TClonesArray("AliITSdigitSSD",3000);
   dTree->SetBranchAddress("ITSDigitsSSD",&digitsSSD);
 
-  Int_t mmax=(Int_t)dTree->GetEntries();
-
-  out->cd();
-
-  sprintf(name,"TreeC_ITS_%d",fEvent);
-  TTree cTree(name,"ITS clusters V2");
   TClonesArray *clusters=new TClonesArray("AliITSclusterV2",1000);
-  cTree.Branch("Clusters",&clusters);
+  TBranch *branch=cTree->GetBranch("Clusters");
+  if (!branch) cTree->Branch("Clusters",&clusters);
+  else branch->SetAddress(&clusters);
+
+  Int_t mmax=(Int_t)dTree->GetEntries();
 
   for (fI=0; fI<mmax; fI++) {
     dTree->GetEvent(fI);
 
     if     (digitsSPD->GetEntriesFast()!=0) 
-                          FindClustersSPD(digitsSPD,clusters);
-    else if(digitsSDD->GetEntriesFast()!=0) 
-                          FindClustersSDD(digitsSDD,clusters);
-    else if(digitsSSD->GetEntriesFast()!=0) 
-                          FindClustersSSD(digitsSSD,clusters);
-
+      FindClustersSPD(digitsSPD,clusters);
+    else 
+      if(digitsSDD->GetEntriesFast()!=0) 
+       FindClustersSDD(digitsSDD,clusters);
+      else if(digitsSSD->GetEntriesFast()!=0) 
+       FindClustersSSD(digitsSSD,clusters);
+    
     ncl+=clusters->GetEntriesFast();
 
-    cTree.Fill();
+    cTree->Fill();
 
     digitsSPD->Clear();
     digitsSDD->Clear();
     digitsSSD->Clear();
     clusters->Clear();
   }
-  cTree.Write();
+
+  //cTree->Write();
 
   delete clusters;
 
@@ -148,9 +149,70 @@ void AliITSclustererV2::Digits2Clusters(const TFile *in, TFile *out) {
 
   //delete dTree;
 
-  cerr<<"Number of found clusters : "<<ncl<<endl;
+  Info("Digits2Clusters","Number of found clusters : %d",ncl);
 
-  savedir->cd();
+  return 0;
+}
+
+void AliITSclustererV2::Digits2Clusters(AliRawReader* rawReader) {
+  //------------------------------------------------------------
+  // This function creates ITS clusters from raw data
+  //------------------------------------------------------------
+  AliRunLoader* runLoader = AliRunLoader::GetRunLoader();
+  if (!runLoader) {
+    Error("Digits2Clusters", "no run loader found");
+    return;
+  }
+  runLoader->LoadKinematics();
+  AliLoader* itsLoader = runLoader->GetLoader("ITSLoader");
+  if (!itsLoader) {
+    Error("Digits2Clusters", "no loader for ITS found");
+    return;
+  }
+  if (!itsLoader->TreeR()) itsLoader->MakeTree("R");
+  TTree* cTree = itsLoader->TreeR();
+
+  TClonesArray *array=new TClonesArray("AliITSclusterV2",1000);
+  cTree->Branch("Clusters",&array);
+  delete array;
+
+  TClonesArray** clusters = new TClonesArray*[fNModules]; 
+  for (Int_t iModule = 0; iModule < fNModules; iModule++) {
+    clusters[iModule] = NULL;
+  }
+  // one TClonesArray per module
+
+  rawReader->Reset();
+  AliITSRawStreamSPD inputSPD(rawReader);
+  FindClustersSPD(&inputSPD, clusters);
+
+  rawReader->Reset();
+  AliITSRawStreamSDD inputSDD(rawReader);
+  FindClustersSDD(&inputSDD, clusters);
+
+  rawReader->Reset();
+  AliITSRawStreamSSD inputSSD(rawReader);
+  FindClustersSSD(&inputSSD, clusters);
+
+  // write all clusters to the tree
+  Int_t nClusters = 0;
+  for (Int_t iModule = 0; iModule < fNModules; iModule++) {
+    array = clusters[iModule];
+    if (!array) {
+      Error("Digits2Clusters", "data for module %d missing!", iModule);
+      array = new TClonesArray("AliITSclusterV2");
+    }
+    cTree->SetBranchAddress("Clusters", &array);
+    cTree->Fill();
+    nClusters += array->GetEntriesFast();
+    delete array;
+  }
+  itsLoader->WriteRecPoints("OVERWRITE");
+
+  delete[] clusters;
+
+  Info("Digits2Clusters", "total number of found clusters in ITS: %d\n", 
+       nClusters);
 }
 
 //**** Fast clusters *******************************
@@ -162,28 +224,107 @@ void AliITSclustererV2::Digits2Clusters(const TFile *in, TFile *out) {
 #include "AliITSsimulationFastPoints.h"
 #include "AliITSRecPoint.h"
 
+/*
 static void CheckLabels(Int_t lab[3]) {
   //------------------------------------------------------------
   // Tries to find mother's labels
   //------------------------------------------------------------
     Int_t label=lab[0];
     if (label>=0) {
-       TParticle *part=(TParticle*)gAlice->Particle(label);
+       TParticle *part=(TParticle*)gAlice->GetMCApp()->Particle(label);
        label=-3;
        while (part->P() < 0.005) {
           Int_t m=part->GetFirstMother();
-          if (m<0) {cerr<<"Primary momentum: "<<part->P()<<endl; break;}
+          if (m<0) {
+             Info("CheckLabels","Primary momentum: %f",part->P()); 
+             break;
+          }
           if (part->GetStatusCode()>0) {
-             cerr<<"Primary momentum: "<<part->P()<<endl; break;
+             Info("CheckLabels","Primary momentum: %f",part->P()); 
+             break;
           }
           label=m;
-          part=(TParticle*)gAlice->Particle(label);
+          part=(TParticle*)gAlice->GetMCApp()->Particle(label);
         }
         if      (lab[1]<0) lab[1]=label;
         else if (lab[2]<0) lab[2]=label;
         else ;//cerr<<"CheckLabels : No empty labels !\n";
     }
 }
+*/
+static void CheckLabels(Int_t lab[3]) {
+  //------------------------------------------------------------
+  // Tries to find mother's labels
+  //------------------------------------------------------------
+
+  Int_t ntracks = gAlice->GetMCApp()->GetNtrack();
+  for (Int_t i=0;i<3;i++){
+    Int_t label = lab[i];
+    if (label>=0 && label<ntracks) {
+      TParticle *part=(TParticle*)gAlice->GetMCApp()->Particle(label);
+      if (part->P() < 0.005) {
+       Int_t m=part->GetFirstMother();
+       if (m<0) {      
+         continue;
+       }
+       if (part->GetStatusCode()>0) {
+         continue;
+       }
+       lab[i]=m;       
+      }
+    }    
+  }
+  
+}
+
+static void CheckLabels2(Int_t lab[10]) {
+  //------------------------------------------------------------
+  // Tries to find mother's labels
+  //------------------------------------------------------------
+
+  Int_t ntracks = gAlice->GetMCApp()->GetNtrack();
+  for (Int_t i=0;i<10;i++){
+    Int_t label = lab[i];
+    if (label>=0 && label<ntracks) {
+      TParticle *part=(TParticle*)gAlice->GetMCApp()->Particle(label);
+      if (part->P() < 0.005) {
+       Int_t m=part->GetFirstMother();
+       if (m<0) {      
+         continue;
+       }
+       if (part->GetStatusCode()>0) {
+         continue;
+       }
+       lab[i]=m;       
+      }
+    }    
+  }
+  //compress labels -- if multi-times the same
+  Int_t lab2[10];
+  for (Int_t i=0;i<10;i++) lab2[i]=-2;
+  for (Int_t i=0;i<10  ;i++){
+    if (lab[i]<0) continue;
+    for (Int_t j=0;j<10 &&lab2[j]!=lab[i];j++){
+      if (lab2[j]<0) {
+       lab2[j]= lab[i];
+       break;
+      }
+    }
+  }
+  for (Int_t j=0;j<10;j++) lab[j]=lab2[j];
+  
+}
+
+static void AddLabel(Int_t lab[10], Int_t label) {
+  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 AliITSclustererV2::RecPoints2Clusters
 (const TClonesArray *points, Int_t idx, TClonesArray *clusters) {
@@ -196,53 +337,44 @@ void AliITSclustererV2::RecPoints2Clusters
   for (Int_t i=0; i<ncl; i++) {
     AliITSRecPoint *p = (AliITSRecPoint *)points->UncheckedAt(i);
     Float_t lp[5];
-    lp[0]=-p->GetX()-fYshift[idx]; if (idx<=fLastSPD1) lp[0]*=-1; //SPD1
-    lp[1]=p->GetZ()+fZshift[idx];
+    lp[0]=-(-p->GetX()+fYshift[idx]); if (idx<=fLastSPD1) lp[0]*=-1; //SPD1
+    lp[1]=  -p->GetZ()+fZshift[idx];
     lp[2]=p->GetSigmaX2();
     lp[3]=p->GetSigmaZ2();
-    lp[4]=p->GetQ();
+    lp[4]=p->GetQ()*36./23333.;  //electrons -> ADC
     Int_t lab[4]; 
     lab[0]=p->GetLabel(0); lab[1]=p->GetLabel(1); lab[2]=p->GetLabel(2);
     lab[3]=fNdet[idx];
     CheckLabels(lab);
-    new (cl[i]) AliITSclusterV2(lab,lp);
+    Int_t dummy[3]={0,0,0};
+    new (cl[i]) AliITSclusterV2(lab,lp, dummy);
   }  
 } 
 
-void AliITSclustererV2::Hits2Clusters(const TFile *in, TFile *out) {
+Int_t AliITSclustererV2::Hits2Clusters(TTree *hTree, TTree *cTree) {
   //------------------------------------------------------------
   // This function creates ITS clusters
   //------------------------------------------------------------
-  TDirectory *savedir=gDirectory;
-
-  if (!out->IsOpen()) {
-    cerr<<"AliITSclustererV2::Hits2Clusters: output file not open !\n";
-    return;
-  }
-
   if (!gAlice) {
-     cerr<<"AliITSclustererV2::Hits2Clusters : gAlice==0 !\n";
-     return;
+     Error("Hits2Clusters","gAlice==0 !");
+     return 1;
   }
 
   AliITS *its  = (AliITS*)gAlice->GetModule("ITS");
   if (!its) { 
-     cerr<<"AliITSclustererV2::Hits2Clusters : Can't find the ITS !\n"
-     return; 
+     Error("Hits2Clusters","Can't find the ITS !")
+     return 2
   }
   AliITSgeom *geom=its->GetITSgeom();
   Int_t mmax=geom->GetIndexMax();
 
   its->InitModules(-1,mmax);
-  its->FillModules(gAlice->TreeH(),0);
-
-  out->cd();
+  its->FillModules(hTree,0);
 
-  Char_t name[100];
-  sprintf(name,"TreeC_ITS_%d",fEvent);
-  TTree cTree(name,"ITS clusters V2");
   TClonesArray *clusters=new TClonesArray("AliITSclusterV2",1000);
-  cTree.Branch("Clusters",&clusters);
+  TBranch *branch=cTree->GetBranch("Clusters");
+  if (!branch) cTree->Branch("Clusters",&clusters);
+  else branch->SetAddress(&clusters);
 
   static TClonesArray *points=its->RecPoints();
   AliITSsimulationFastPoints sim;
@@ -255,16 +387,17 @@ void AliITSclustererV2::Hits2Clusters(const TFile *in, TFile *out) {
     its->ResetRecPoints();
 
     ncl+=clusters->GetEntriesFast();
-    cTree.Fill();
+    cTree->Fill();
     clusters->Clear();
   }
-  cTree.Write();
 
-  cerr<<"Number of found fast clusters : "<<ncl<<endl;
+  Info("Hits2Clusters","Number of found fast clusters : %d",ncl);
+
+  //cTree->Write();
 
   delete clusters;
 
-  savedir->cd();
+  return 0;
 }
 
 //***********************************
@@ -297,7 +430,8 @@ FindClustersSPD(const TClonesArray *digits, TClonesArray *clusters) {
   //------------------------------------------------------------
   // Actual SPD cluster finder
   //------------------------------------------------------------
-  const Int_t kMAXBIN=(fNzSPD+2)*(fNySPD+2);
+  Int_t kNzBins = fNzSPD + 2;
+  const Int_t kMAXBIN=kNzBins*(fNySPD+2);
 
   Int_t ndigits=digits->GetEntriesFast();
   AliBin *bins=new AliBin[kMAXBIN];
@@ -308,22 +442,29 @@ FindClustersSPD(const TClonesArray *digits, TClonesArray *clusters) {
      d=(AliITSdigitSPD*)digits->UncheckedAt(k);
      Int_t i=d->GetCoord2()+1;   //y
      Int_t j=d->GetCoord1()+1;
-     bins[i*fNzSPD+j].SetIndex(k);
-     bins[i*fNzSPD+j].SetMask(1);
+     bins[i*kNzBins+j].SetIndex(k);
+     bins[i*kNzBins+j].SetMask(1);
   }
    
   Int_t n=0; TClonesArray &cl=*clusters;
   for (k=0; k<kMAXBIN; k++) {
      if (!bins[k].IsNotUsed()) continue;
      Int_t ni=0, idx[200];
-     FindCluster(k,fNzSPD,bins,ni,idx);
-     if (ni==200) {cerr<<"SPD: Too big cluster !\n"; continue;}
-
+     FindCluster(k,kNzBins,bins,ni,idx);
+     if (ni==200) {
+        Info("FindClustersSPD","Too big cluster !"); 
+        continue;
+     }
      Int_t lab[4]; 
      lab[0]=-2;
      lab[1]=-2;
      lab[2]=-2;
      lab[3]=fNdet[fI];
+     Int_t milab[10];
+     for (Int_t ilab=0;ilab<10;ilab++){
+       milab[ilab]=-2;
+     }
+
 
      d=(AliITSdigitSPD*)digits->UncheckedAt(idx[0]);
      Int_t ymin=d->GetCoord2(),ymax=ymin;
@@ -350,25 +491,145 @@ FindClustersSPD(const TClonesArray *digits, TClonesArray *clusters) {
         }
         Float_t qq=d->GetSignal();
         y+=qq*fYSPD[d->GetCoord2()]; z+=qq*fZSPD[d->GetCoord1()]; q+=qq;   
-     }
+       // MI addition - find all labels
+       for (Int_t dlab=0;dlab<3;dlab++){
+         Int_t digitlab = (d->GetTracks())[dlab];
+         if (digitlab<0) continue;
+         for (Int_t index=0;index<10;index++){
+           if (milab[index]<0)  {
+             milab[index] = digitlab;      
+             break;
+           }
+           if (milab[index]==digitlab) break;
+         }
+       }
+     }     
      y/=q; z/=q;
      y-=fHwSPD; z-=fHlSPD;
 
      Float_t lp[5];
-     lp[0]=-y-fYshift[fI]; if (fI<=fLastSPD1) lp[0]=-lp[0];
-     lp[1]= z+fZshift[fI];
-     lp[2]= fYpitchSPD*fYpitchSPD/12.;
-     lp[3]= fZ1pitchSPD*fZ1pitchSPD/12.;
+     lp[0]=-(-y+fYshift[fI]); if (fI<=fLastSPD1) lp[0]=-lp[0];
+     lp[1]=  -z+fZshift[fI];
+     // Float_t factor=TMath::Max(double(ni-3.),1.5);
+     Float_t factor=1.5;
+     lp[2]= (fYpitchSPD*fYpitchSPD/12.)*factor;
+     lp[3]= (fZ1pitchSPD*fZ1pitchSPD/12.)*factor;
      //lp[4]= q;
      lp[4]= (zmax-zmin+1)*100 + (ymax-ymin+1);
 
-     //CheckLabels(lab);
-     new (cl[n]) AliITSclusterV2(lab,lp); n++; 
+     CheckLabels(lab);
+     CheckLabels2(milab);
+     CheckLabels2(milab);
+     milab[3]=fNdet[fI];
+     d=(AliITSdigitSPD*)digits->UncheckedAt(idx[0]);
+     Int_t info[3] = {ni,0,1};
+     new (cl[n]) AliITSclusterV2(milab,lp,info); n++; 
   }
 
-  delete bins;
+  delete [] bins;
 }
 
+void AliITSclustererV2::FindClustersSPD(AliITSRawStream* input, 
+                                       TClonesArray** clusters) 
+{
+  //------------------------------------------------------------
+  // Actual SPD cluster finder for raw data
+  //------------------------------------------------------------
+
+  Int_t nClustersSPD = 0;
+  Int_t kNzBins = fNzSPD + 2;
+  Int_t kNyBins = fNySPD + 2;
+  Int_t kMaxBin = kNzBins * kNyBins;
+  AliBin* bins = NULL;
+
+  // 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) { 
+       clusters[iModule] = new TClonesArray("AliITSclusterV2");
+       Int_t nClusters = 0;
+
+       for (Int_t iBin = 0; iBin < kMaxBin; iBin++) {
+         if (bins[iBin].IsUsed()) continue;
+         Int_t nBins = 0;
+         Int_t idxBins[200];
+         FindCluster(iBin, kNzBins, bins, nBins, idxBins);
+         if (nBins == 200) {
+           Error("FindClustersSPD", "SPD: Too big cluster !\n"); 
+           continue;
+         }
+
+         Int_t label[4]; 
+         label[0] = -2;
+         label[1] = -2;
+         label[2] = -2;
+//       label[3] = iModule;
+         label[3] = fNdet[iModule];
+
+         Int_t ymin = (idxBins[0] / kNzBins) - 1;
+         Int_t ymax = ymin;
+         Int_t zmin = (idxBins[0] % kNzBins) - 1;
+         Int_t zmax = zmin;
+         Float_t y = 0.;
+         Float_t z = 0.;
+         Float_t q = 0.;
+         for (Int_t idx = 0; idx < nBins; idx++) {
+           Int_t iy = (idxBins[idx] / kNzBins) - 1;
+           Int_t iz = (idxBins[idx] % kNzBins) - 1;
+           if (ymin > iy) ymin = iy;
+           if (ymax < iy) ymax = iy;
+           if (zmin > iz) zmin = iz;
+           if (zmax < iz) zmax = iz;
+
+           Float_t qBin = bins[idxBins[idx]].GetQ();
+           y += qBin * fYSPD[iy]; 
+           z += qBin * fZSPD[iz]; 
+           q += qBin;   
+         }
+         y /= q; 
+         z /= q;
+         y -= fHwSPD; 
+         z -= fHlSPD;
+
+         Float_t hit[5];  // y, z, sigma(y)^2, sigma(z)^2, charge
+         hit[0] = -y-fYshift[iModule]; 
+         if (iModule <= fLastSPD1) hit[0] = -hit[0];
+         hit[1] = z+fZshift[iModule];
+         hit[2] = fYpitchSPD*fYpitchSPD/12.;
+         hit[3] = fZ1pitchSPD*fZ1pitchSPD/12.;
+//       hit[4] = q;
+         hit[4] = (zmax-zmin+1)*100 + (ymax-ymin+1);
+
+         CheckLabels(label);
+         Int_t info[3]={0,0,0};
+         new (clusters[iModule]->AddrAt(nClusters)) 
+           AliITSclusterV2(label, hit,info); 
+         nClusters++;
+       }
+
+       nClustersSPD += nClusters;
+       delete bins;
+      }
+
+      if (!next) break;
+      bins = new AliBin[kMaxBin];
+    }
+
+    // fill the current digit into the bins array
+    Int_t index = (input->GetCoord2()+1) * kNzBins + (input->GetCoord1()+1);
+    bins[index].SetIndex(index);
+    bins[index].SetMask(1);
+    bins[index].SetQ(1);
+  }
+
+  Info("FindClustersSPD", "found clusters in ITS SPD: %d", nClustersSPD);
+}
+
+
 Bool_t AliITSclustererV2::IsMaximum(Int_t k,Int_t max,const AliBin *bins) {
   //------------------------------------------------------------
   //is this a local maximum ?
@@ -445,41 +706,17 @@ MakeCluster(Int_t k,Int_t max,AliBin *bins,UInt_t m,AliITSclusterV2 &c) {
 }
 
 void AliITSclustererV2::
-FindClustersSDD(const TClonesArray *digits, TClonesArray *clusters) {
+FindClustersSDD(AliBin* bins[2], Int_t nMaxBin, Int_t nzBins, 
+               const TClonesArray *digits, TClonesArray *clusters) {
   //------------------------------------------------------------
   // Actual SDD cluster finder
   //------------------------------------------------------------
-  const Int_t kMAXBIN=(fNzSDD+2)*(fNySDD+2);
-
-  AliBin *bins[2];
-  bins[0]=new AliBin[kMAXBIN];
-  bins[1]=new AliBin[kMAXBIN];
-
-  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 (z <= fNzSDD) {
-       bins[0][y*fNzSDD+z].SetQ(q);
-       bins[0][y*fNzSDD+z].SetMask(1);
-       bins[0][y*fNzSDD+z].SetIndex(i);
-     } else {
-       z-=fNzSDD; 
-       bins[1][y*fNzSDD+z].SetQ(q);
-       bins[1][y*fNzSDD+z].SetMask(1);
-       bins[1][y*fNzSDD+z].SetIndex(i);
-     }
-  }
-  
   Int_t ncl=0; TClonesArray &cl=*clusters;
   for (Int_t s=0; s<2; s++)
-    for (i=0; i<kMAXBIN; i++) {
+    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, fNzSDD, bins[s], idx, msk, npeaks);
+      FindPeaks(i, nzBins, bins[s], idx, msk, npeaks);
 
       if (npeaks>30) continue;
 
@@ -488,8 +725,8 @@ FindClustersSDD(const TClonesArray *digits, TClonesArray *clusters) {
         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]/fNzSDD, kj=idx[k] - ki*fNzSDD;
-           Int_t li=idx[l]/fNzSDD, lj=idx[l] - li*fNzSDD;
+           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;
@@ -505,15 +742,18 @@ FindClustersSDD(const TClonesArray *digits, TClonesArray *clusters) {
       }
 
       for (k=0; k<npeaks; k++) {
-        MarkPeak(TMath::Abs(idx[k]), fNzSDD, bins[s], msk[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], fNzSDD, bins[s], msk[k], c);
-
-         //if (c.GetQ() < 200) continue; //noise cluster
+         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;
+        }
 
         /*
          Float_t s2 = c.GetSigmaY2()/c.GetQ() - c.GetY()*c.GetY();
@@ -548,93 +788,283 @@ FindClustersSDD(const TClonesArray *digits, TClonesArray *clusters) {
          z=(z-0.5)*fZpitchSDD;
          z-=fHlSDD;
 
-         y=-y-fYshift[fI];
-         z= z+fZshift[fI];
+         y=-(-y+fYshift[fI]);
+         z=  -z+fZshift[fI];
          c.SetY(y);
          c.SetZ(z);
 
-         c.SetQ(q/20.);  //to be consistent with the SSD charges
-
-         AliBin *b=&bins[s][idx[k]];
-         d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-         Int_t l0=(d->GetTracks())[0];
-         if (l0<0) {
-          b=&bins[s][idx[k]-1];
-           if (b->GetQ()>0) {
-             d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-             l0=(d->GetTracks())[0];
-           }
-         }
-         if (l0<0) {
-          b=&bins[s][idx[k]+1];
-           if (b->GetQ()>0) {
-             d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-             l0=(d->GetTracks())[0];
+         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 l0=(d->GetTracks())[0];
+          //if (l0<0) {
+            b=&bins[s][idx[k]-1];
+            if (b->GetQ()>0) {
+              d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
+              l0=(d->GetTracks())[0];
+              AddLabel(milab, (d->GetTracks())[0]); 
+              AddLabel(milab, (d->GetTracks())[1]); 
+              AddLabel(milab, (d->GetTracks())[2]); 
+            }
+            //}
+            //if (l0<0) {
+            b=&bins[s][idx[k]+1];
+            if (b->GetQ()>0) {
+              d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
+              l0=(d->GetTracks())[0];
+              AddLabel(milab, (d->GetTracks())[0]); 
+              AddLabel(milab, (d->GetTracks())[1]); 
+              AddLabel(milab, (d->GetTracks())[2]); 
+            }
+            // }
+            //if (l0<0) {
+            b=&bins[s][idx[k]-nzBins];
+            if (b->GetQ()>0) {
+              d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
+              l0=(d->GetTracks())[0];
+              AddLabel(milab, (d->GetTracks())[0]); 
+              AddLabel(milab, (d->GetTracks())[1]); 
+              AddLabel(milab, (d->GetTracks())[2]); 
+            }
+            //}
+            //if (l0<0) {
+            b=&bins[s][idx[k]+nzBins];
+            if (b->GetQ()>0) {
+              d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
+              l0=(d->GetTracks())[0];
+              AddLabel(milab, (d->GetTracks())[0]); 
+              AddLabel(milab, (d->GetTracks())[1]); 
+              AddLabel(milab, (d->GetTracks())[2]); 
+            }
+            //}
+
+            //if (l0<0) {
+            b=&bins[s][idx[k]+nzBins+1];
+            if (b->GetQ()>0) {
+              d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
+              l0=(d->GetTracks())[0];
+              AddLabel(milab, (d->GetTracks())[0]); 
+              AddLabel(milab, (d->GetTracks())[1]); 
+              AddLabel(milab, (d->GetTracks())[2]); 
+            }
+            //}
+            //if (l0<0) {
+            b=&bins[s][idx[k]+nzBins-1];
+            if (b->GetQ()>0) {
+              d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
+              l0=(d->GetTracks())[0];
+              AddLabel(milab, (d->GetTracks())[0]); 
+              AddLabel(milab, (d->GetTracks())[1]); 
+              AddLabel(milab, (d->GetTracks())[2]); 
+            }
+            //}
+            //if (l0<0) {
+            b=&bins[s][idx[k]-nzBins+1];
+            if (b->GetQ()>0) {
+              d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
+              l0=(d->GetTracks())[0];
+              AddLabel(milab, (d->GetTracks())[0]); 
+              AddLabel(milab, (d->GetTracks())[1]); 
+              AddLabel(milab, (d->GetTracks())[2]); 
+            }
+            //}
+            //if (l0<0) {
+            b=&bins[s][idx[k]-nzBins-1];
+            if (b->GetQ()>0) {
+              d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
+              l0=(d->GetTracks())[0];
+              AddLabel(milab, (d->GetTracks())[0]); 
+              AddLabel(milab, (d->GetTracks())[1]); 
+              AddLabel(milab, (d->GetTracks())[2]); 
+            }
+            //}
+
+          {
+            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(3);
           }
-         }
-         if (l0<0) {
-          b=&bins[s][idx[k]-fNzSDD];
-          if (b->GetQ()>0) {
-             d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-             l0=(d->GetTracks())[0];
-           }
-         }
-         if (l0<0) {
-          b=&bins[s][idx[k]+fNzSDD];
-           if (b->GetQ()>0) {
-             d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-             l0=(d->GetTracks())[0];
-           }
-         }
-
-         if (l0<0) {
-          b=&bins[s][idx[k]+fNzSDD+1];
-           if (b->GetQ()>0) {
-             d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-             l0=(d->GetTracks())[0];
-           }
-         }
-         if (l0<0) {
-          b=&bins[s][idx[k]+fNzSDD-1];
-           if (b->GetQ()>0) {
-             d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-             l0=(d->GetTracks())[0];
-           }
-         }
-         if (l0<0) {
-          b=&bins[s][idx[k]-fNzSDD+1];
-           if (b->GetQ()>0) {
-             d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-             l0=(d->GetTracks())[0];
-           }
-         }
-         if (l0<0) {
-          b=&bins[s][idx[k]-fNzSDD-1];
-           if (b->GetQ()>0) {
-             d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
-             l0=(d->GetTracks())[0];
-           }
-         }
-
-         {
-          Int_t lab[3];
-           lab[0]=(d->GetTracks())[0];
-           lab[1]=(d->GetTracks())[1];
-           lab[2]=(d->GetTracks())[2];
-           //CheckLabels(lab);
-           c.SetLabel(lab[0],0);
-           c.SetLabel(lab[1],1);
-           c.SetLabel(lab[2],2);
-         }
+        }
 
          new (cl[ncl]) AliITSclusterV2(c); ncl++;
       }
     }
+}
+
+void AliITSclustererV2::
+FindClustersSDD(const TClonesArray *digits, TClonesArray *clusters) {
+  //------------------------------------------------------------
+  // Actual SDD cluster finder
+  //------------------------------------------------------------
+  Int_t kNzBins = fNzSDD + 2;
+  const Int_t kMAXBIN=kNzBins*(fNySDD+2);
+
+  AliBin *bins[2];
+  bins[0]=new AliBin[kMAXBIN];
+  bins[1]=new AliBin[kMAXBIN];
+
+  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 (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);
+     }
+  }
+  
+  FindClustersSDD(bins, kMAXBIN, kNzBins, digits, clusters);
 
   delete[] bins[0];
   delete[] bins[1];
 }
 
+void AliITSclustererV2::FindClustersSDD(AliITSRawStream* input, 
+                                       TClonesArray** clusters) 
+{
+  //------------------------------------------------------------
+  // Actual SDD cluster finder for raw data
+  //------------------------------------------------------------
+  Int_t nClustersSDD = 0;
+  Int_t kNzBins = fNzSDD + 2;
+  Int_t kMaxBin = kNzBins * (fNySDD+2);
+  AliBin* bins[2] = {NULL, NULL};
+
+  // 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");
+       fI = iModule;
+       FindClustersSDD(bins, kMaxBin, kNzBins, NULL, clusters[iModule]);
+       Int_t nClusters = clusters[iModule]->GetEntriesFast();
+       nClustersSDD += nClusters;
+       delete[] bins[0];
+       delete[] bins[1];
+      }
+
+      if (!next) break;
+      bins[0] = new AliBin[kMaxBin];
+      bins[1] = new AliBin[kMaxBin];
+    }
+
+    // fill the current digit into the bins array
+    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);
+  }
+
+  Info("FindClustersSDD", "found clusters in ITS SDD: %d", nClustersSDD);
+}
+
+void AliITSclustererV2::
+FindClustersSSD(Ali1Dcluster* neg, Int_t nn, 
+               Ali1Dcluster* pos, Int_t np,
+               TClonesArray *clusters) {
+  //------------------------------------------------------------
+  // Actual SSD cluster finder
+  //------------------------------------------------------------
+  TClonesArray &cl=*clusters;
+
+  Int_t lab[4]={-2,-2,-2,-2};
+  Float_t tanp=fTanP, tann=fTanN;
+  if (fI>fLastSSD1) {tann=fTanP; tanp=fTanN;}
+
+  Int_t idet=fNdet[fI];
+  Int_t ncl=0;
+  for (Int_t i=0; i<np; i++) {
+    //Float_t dq_min=1.e+33;
+    Float_t ybest=1000,zbest=1000,qbest=0;
+    Float_t yp=pos[i].GetY()*fYpitchSSD; 
+    for (Int_t j=0; j<nn; j++) {
+      //if (pos[i].fTracks[0] != neg[j].fTracks[0]) continue;
+      Float_t yn=neg[j].GetY()*fYpitchSSD;
+      Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
+      Float_t yt=yn + tann*zt;
+      zt-=fHlSSD; yt-=fHwSSD;
+      if (TMath::Abs(yt)<fHwSSD+0.01)
+      if (TMath::Abs(zt)<fHlSSD+0.01) {
+      //if (TMath::Abs(pos[i].GetQ()-neg[j].GetQ())<dq_min) {
+       //dq_min=TMath::Abs(pos[i].GetQ()-neg[j].GetQ());
+        ybest=yt; zbest=zt; 
+        qbest=0.5*(pos[i].GetQ()+neg[j].GetQ());
+
+        lab[0]=pos[i].GetLabel(0);
+        lab[1]=pos[i].GetLabel(1);
+        lab[2]=neg[i].GetLabel(0);
+        lab[3]=(((i<<10) + j)<<10) + idet; // pos|neg|det
+        Float_t lp[5];
+        lp[0]=-(-ybest+fYshift[fI]);
+        lp[1]=  -zbest+fZshift[fI];
+        lp[2]=0.0025*0.0025*1.5;  //SigmaY2 - 1.5 safety factor
+        lp[3]=0.110*0.110*1.5;  //SigmaZ2   - 1.5 safety factor
+        if (pos[i].GetNd()+neg[j].GetNd() > 4) {
+           lp[2]*=9;
+           lp[3]*=9;
+        }
+        lp[4]=qbest;        //Q
+       Int_t milab[10];
+       for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
+       milab[0]=pos[i].GetLabel(0);
+        milab[1]=neg[j].GetLabel(0);
+       milab[2]=pos[i].GetLabel(1);
+        milab[3]=neg[j].GetLabel(1);
+       milab[4]=pos[i].GetLabel(2);
+        milab[5]=neg[j].GetLabel(2);
+       //
+        CheckLabels(lab);
+       CheckLabels2(milab);
+       milab[3]=(((i<<10) + j)<<10) + idet; // pos|neg|det
+       Int_t info[3] = {0,0,5};
+        new (cl[ncl]) AliITSclusterV2(milab,lp,info); ncl++;
+      }
+    }
+    /*
+    if (ybest<100) {
+       lab[3]=idet;
+       Float_t lp[5];
+       lp[0]=-ybest-fYshift[fI];
+       lp[1]= zbest+fZshift[fI];
+       lp[2]=0.002*0.002;  //SigmaY2
+       lp[3]=0.080*0.080;  //SigmaZ2
+       lp[4]=qbest;        //Q
+       //
+       new (cl[ncl]) AliITSclusterV2(lab,lp); ncl++;
+    }
+    */
+  }
+}
+
 void AliITSclustererV2::
 FindClustersSSD(const TClonesArray *digits, TClonesArray *clusters) {
   //------------------------------------------------------------
@@ -649,8 +1079,6 @@ FindClustersSSD(const TClonesArray *digits, TClonesArray *clusters) {
   Float_t y=0., q=0., qmax=0.; 
   Int_t lab[4]={-2,-2,-2,-2};
 
-  TClonesArray &cl=*clusters;
-
   AliITSdigitSSD *d=(AliITSdigitSSD*)digits->UncheckedAt(0);
   q += d->GetSignal();
   y += d->GetCoord2()*d->GetSignal();
@@ -660,7 +1088,7 @@ FindClustersSSD(const TClonesArray *digits, TClonesArray *clusters) {
   Int_t flag=d->GetCoord1();
   Int_t *n=&nn;
   Ali1Dcluster *c=neg;
-  Int_t nd=0;
+  Int_t nd=1;
   for (Int_t s=1; s<smax; s++) {
       d=(AliITSdigitSSD*)digits->UncheckedAt(s);
       Int_t strip=d->GetCoord2();
@@ -675,8 +1103,7 @@ FindClustersSSD(const TClonesArray *digits, TClonesArray *clusters) {
             c[*n].SetQ(0.5*q);
             (*n)++;
             if (*n==MAX) {
-              cerr<<
-              "AliITSclustererV2::FindClustersSSD: Too many 1D clusters !\n";
+              Error("FindClustersSSD","Too many 1D clusters !");
               return;
             }
             c[*n].SetY(y/q+0.5*nd);
@@ -686,7 +1113,7 @@ FindClustersSSD(const TClonesArray *digits, TClonesArray *clusters) {
          }
          (*n)++;
          if (*n==MAX) {
-          cerr<<"AliITSclustererV2::FindClustersSSD: Too many 1D clusters !\n";
+          Error("FindClustersSSD","Too many 1D clusters !");
           return;
          }
          y=q=qmax=0.;
@@ -714,7 +1141,7 @@ FindClustersSSD(const TClonesArray *digits, TClonesArray *clusters) {
      c[*n].SetQ(0.5*q);
      (*n)++;
      if (*n==MAX) {
-        cerr<<"AliITSclustererV2::FindClustersSSD: Too many 1D clusters !\n";
+        Error("FindClustersSSD","Too many 1D clusters !");
         return;
      }
      c[*n].SetY(y/q+0.5*nd);
@@ -724,65 +1151,93 @@ FindClustersSSD(const TClonesArray *digits, TClonesArray *clusters) {
   }
   (*n)++;
   if (*n==MAX) {
-     cerr<<"AliITSclustererV2::FindClustersSSD: Too many 1D clusters !\n";
+     Error("FindClustersSSD","Too many 1D clusters !");
      return;
   }
 
-  Float_t tanp=fTanP, tann=fTanN;
-  if (fI>fLastSSD1) {tann=fTanP; tanp=fTanN;}
-
-  Int_t idet=fNdet[fI];
-  Int_t ncl=0;
-  for (Int_t i=0; i<np; i++) {
-    //Float_t dq_min=1.e+33;
-    Float_t ybest=1000,zbest=1000,qbest=0;
-    Float_t yp=pos[i].GetY()*fYpitchSSD; 
-    for (Int_t j=0; j<nn; j++) {
-      //if (pos[i].fTracks[0] != neg[j].fTracks[0]) continue;
-      Float_t yn=neg[j].GetY()*fYpitchSSD;
-      Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
-      Float_t yt=yn + tann*zt;
-      zt-=fHlSSD; yt-=fHwSSD;
-      if (TMath::Abs(yt)<fHwSSD+0.01)
-      if (TMath::Abs(zt)<fHlSSD+0.01) {
-      //if (TMath::Abs(pos[i].GetQ()-neg[j].GetQ())<dq_min) {
-       //dq_min=TMath::Abs(pos[i].GetQ()-neg[j].GetQ());
-        ybest=yt; zbest=zt; 
-        qbest=0.5*(pos[i].GetQ()+neg[j].GetQ());
-
-        lab[0]=pos[i].GetLabel(0);
-        lab[1]=pos[i].GetLabel(1);
-        lab[2]=neg[i].GetLabel(0);
-        lab[3]=(((i<<10) + j)<<10) + idet; // pos|neg|det
-        Float_t lp[5];
-        lp[0]=-ybest-fYshift[fI];
-        lp[1]= zbest+fZshift[fI];
-        lp[2]=0.0025*0.0025;  //SigmaY2
-        lp[3]=0.110*0.110;  //SigmaZ2
-        if (pos[i].GetNd()+neg[j].GetNd() > 4) {
-           lp[2]*=9;
-           lp[3]*=9;
-        }
-        lp[4]=qbest;        //Q
+  FindClustersSSD(neg, nn, pos, np, clusters);
+}
 
-        //CheckLabels(lab);
-        new (cl[ncl]) AliITSclusterV2(lab,lp); ncl++;
+void AliITSclustererV2::FindClustersSSD(AliITSRawStream* input, 
+                                       TClonesArray** clusters) 
+{
+  //------------------------------------------------------------
+  // Actual SSD cluster finder for raw data
+  //------------------------------------------------------------
+  Int_t nClustersSSD = 0;
+  const Int_t MAX = 1000;
+  Ali1Dcluster clusters1D[2][MAX];
+  Int_t nClusters[2] = {0, 0};
+  Float_t q = 0.;
+  Float_t y = 0.;
+  Int_t nDigits = 0;
+  Int_t prevStrip = -1;
+  Int_t prevFlag = -1;
+
+  // read raw data input stream
+  while (kTRUE) {
+    Bool_t next = input->Next();
+
+    // check if a new cluster starts
+    Int_t strip = input->GetCoord2();
+    Int_t flag = input->GetCoord1();
+    if ((!next || input->IsNewModule() ||
+        (strip-prevStrip > 1) || (flag != prevFlag)) &&
+       (nDigits > 0)) {
+      if (nClusters[prevFlag] == MAX) {
+       Error("FindClustersSSD", "Too many 1D clusters !");
+       return;
       }
+      Ali1Dcluster& cluster = clusters1D[prevFlag][nClusters[prevFlag]++];
+      cluster.SetY(y/q);
+      cluster.SetQ(q);
+      cluster.SetNd(nDigits);
+
+      //Split suspiciously big cluster
+      if (nDigits > 3) {
+       cluster.SetY(y/q - 0.5*nDigits);
+        cluster.SetQ(0.5*q);
+       if (nClusters[prevFlag] == MAX) {
+         Error("FindClustersSSD", "Too many 1D clusters !");
+         return;
+       }
+       Ali1Dcluster& cluster2 = clusters1D[prevFlag][nClusters[prevFlag]++];
+       cluster2.SetY(y/q + 0.5*nDigits);
+       cluster2.SetQ(0.5*q);
+       cluster2.SetNd(nDigits);
+      }
+      y = q = 0.;
+      nDigits = 0;
     }
-    /*
-    if (ybest<100) {
-       lab[3]=idet;
-       Float_t lp[5];
-       lp[0]=-ybest-fYshift[fI];
-       lp[1]= zbest+fZshift[fI];
-       lp[2]=0.002*0.002;  //SigmaY2
-       lp[3]=0.080*0.080;  //SigmaZ2
-       lp[4]=qbest;        //Q
-       //
-       new (cl[ncl]) AliITSclusterV2(lab,lp); ncl++;
+
+    if (!next || input->IsNewModule()) {
+      Int_t iModule = input->GetPrevModuleID();
+
+      // when all data from a module was read, search for clusters
+      if (prevFlag >= 0) {
+       clusters[iModule] = new TClonesArray("AliITSclusterV2");
+       fI = iModule;
+       FindClustersSSD(&clusters1D[0][0], nClusters[0], 
+                       &clusters1D[1][0], nClusters[1], clusters[iModule]);
+       Int_t nClusters = clusters[iModule]->GetEntriesFast();
+       nClustersSSD += nClusters;
+      }
+
+      if (!next) break;
+      nClusters[0] = nClusters[1] = 0;
+      y = q = 0.;
+      nDigits = 0;
     }
-    */
+
+    // add digit to current cluster
+    q += input->GetSignal();
+    y += strip * input->GetSignal();
+    nDigits++;
+    prevStrip = strip;
+    prevFlag = flag;
   }
+
+  Info("FindClustersSSD", "found clusters in ITS SSD: %d", nClustersSSD);
 }
 
 #else   //V1
@@ -835,7 +1290,7 @@ FindClustersSDD(const TClonesArray *digits, TClonesArray *clusters) {
   Int_t nc=points->GetEntriesFast();
   while (nc--) { //To be consistent with the SSD cluster charges
      AliITSRecPoint *p=(AliITSRecPoint*)points->UncheckedAt(nc);
-     p->SetQ(p->GetQ/12.);
+     p->SetQ(p->GetQ()/12.);
   }
   RecPoints2Clusters(points, fI, clusters);
   its->ResetClusters(1);