]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PHOS/AliPHOSClusterizerv1.cxx
Compilation warnings fixed
[u/mrichter/AliRoot.git] / PHOS / AliPHOSClusterizerv1.cxx
index 89568f2ed7b002543c451ce60cb2ef56e180c7ce..301f03900a14554dc152c9541b697480da6cefeb 100644 (file)
 
 /* History of cvs commits:
  *
- * $Log$
+ * $Log: AliPHOSClusterizerv1.cxx,v $
+ * Revision 1.118  2007/12/11 21:23:26  kharlov
+ * Added possibility to swith off unfolding
+ *
+ * Revision 1.117  2007/10/18 08:42:05  kharlov
+ * Bad channels cleaned before clusterization
+ *
+ * Revision 1.116  2007/10/01 20:24:08  kharlov
+ * Memory leaks fixed
+ *
  * Revision 1.115  2007/09/26 14:22:17  cvetan
  * Important changes to the reconstructor classes. Complete elimination of the run-loaders, which are now steered only from AliReconstruction. Removal of the corresponding Reconstruct() and FillESD() methods.
  *
 #include "AliPHOSCpvRecPoint.h"
 #include "AliPHOSDigit.h"
 #include "AliPHOSDigitizer.h"
-#include "AliPHOSCalibrationDB.h"
 #include "AliCDBManager.h"
 #include "AliCDBStorage.h"
 #include "AliCDBEntry.h"
 #include "AliPHOSRecoParam.h"
-#include "AliPHOSCalibData.h"
 #include "AliPHOSReconstructor.h"
+#include "AliPHOSCalibData.h"
 
 ClassImp(AliPHOSClusterizerv1)
   
@@ -185,17 +193,14 @@ ClassImp(AliPHOSClusterizerv1)
 AliPHOSClusterizerv1::AliPHOSClusterizerv1() :
   AliPHOSClusterizer(),
   fDefaultInit(0),            fEmcCrystals(0),          fToUnfold(0),
-  fWrite(0),                  fNumberOfEmcClusters(0),  fNumberOfCpvClusters(0),
-  fADCchanelEmc(0),         fADCpedestalEmc(0),
-  fADCchanelCpv(0),           fADCpedestalCpv(0),       fEmcClusteringThreshold(0),
-  fCpvClusteringThreshold(0), fEmcMinE(0),              fCpvMinE(0),
+  fWrite(0),                  
+  fNumberOfEmcClusters(0),    fNumberOfCpvClusters(0),
+  fEmcClusteringThreshold(0), fCpvClusteringThreshold(0), 
   fEmcLocMaxCut(0),           fW0(0),                   fCpvLocMaxCut(0),
-  fW0CPV(0),                  fEmcTimeGate(0),
-  fIsOldRCUFormat(0)
+  fW0CPV(0),                  fEmcTimeGate(0),          fEcoreRadius(0)
 {
   // default ctor (to be used mainly by Streamer)
   
-  InitParameters() ; 
   fDefaultInit = kTRUE ; 
 }
 
@@ -203,17 +208,14 @@ AliPHOSClusterizerv1::AliPHOSClusterizerv1() :
 AliPHOSClusterizerv1::AliPHOSClusterizerv1(AliPHOSGeometry *geom) :
   AliPHOSClusterizer(geom),
   fDefaultInit(0),            fEmcCrystals(0),          fToUnfold(0),
-  fWrite(0),                  fNumberOfEmcClusters(0),  fNumberOfCpvClusters(0),
-  fADCchanelEmc(0),         fADCpedestalEmc(0),
-  fADCchanelCpv(0),           fADCpedestalCpv(0),       fEmcClusteringThreshold(0),
-  fCpvClusteringThreshold(0), fEmcMinE(0),              fCpvMinE(0),
+  fWrite(0),                
+  fNumberOfEmcClusters(0),    fNumberOfCpvClusters(0),
+  fEmcClusteringThreshold(0), fCpvClusteringThreshold(0), 
   fEmcLocMaxCut(0),           fW0(0),                   fCpvLocMaxCut(0),
-  fW0CPV(0),                  fEmcTimeGate(0),
-  fIsOldRCUFormat(0)
+  fW0CPV(0),                  fEmcTimeGate(0),          fEcoreRadius(0)
 {
   // ctor with the indication of the file where header Tree and digits Tree are stored
   
-  InitParameters() ;
   Init() ;
   fDefaultInit = kFALSE ; 
 }
@@ -224,58 +226,6 @@ AliPHOSClusterizerv1::AliPHOSClusterizerv1(AliPHOSGeometry *geom) :
   // dtor
 
 }
-
-//____________________________________________________________________________
-Float_t  AliPHOSClusterizerv1::CalibrateEMC(Float_t amp, Int_t absId)
-{  
-  // Convert EMC measured amplitude into real energy.
-  // Calibration parameters are taken from calibration data base for raw data,
-  // or from digitizer parameters for simulated data.
-
-  if(fgCalibData){
-    Int_t relId[4];
-    fGeom->AbsToRelNumbering(absId,relId) ;
-    Int_t   module = relId[0];
-    Int_t   column = relId[3];
-    Int_t   row    = relId[2];
-    if(absId <= fEmcCrystals) { // this is EMC 
-      fADCchanelEmc   = fgCalibData->GetADCchannelEmc (module,column,row);
-      return amp*fADCchanelEmc ;        
-    }
-  }
-  else{ //simulation
-    if(absId <= fEmcCrystals) // this is EMC 
-      return fADCpedestalEmc + amp*fADCchanelEmc ;        
-  }
-  return 0;
-}
-
-//____________________________________________________________________________
-Float_t  AliPHOSClusterizerv1::CalibrateCPV(Int_t amp, Int_t absId)
-{  
-  // Convert digitized CPV amplitude into charge.
-  // Calibration parameters are taken from calibration data base for raw data,
-  // or from digitizer parameters for simulated data.
-
-  if(fgCalibData){
-    Int_t relId[4];
-    fGeom->AbsToRelNumbering(absId,relId) ;
-    Int_t   module = relId[0];
-    Int_t   column = relId[3];
-    Int_t   row    = relId[2];
-    if(absId > fEmcCrystals) { // this is CPV
-      fADCchanelCpv   = fgCalibData->GetADCchannelCpv (module,column,row);
-      fADCpedestalCpv = fgCalibData->GetADCpedestalCpv(module,column,row);
-      return fADCpedestalCpv + amp*fADCchanelCpv ;              
-    }     
-  }
-  else{ //simulation
-    if(absId > fEmcCrystals) // this is CPV
-      return fADCpedestalCpv+ amp*fADCchanelCpv ;       
-  }
-  return 0;
-}
-
 //____________________________________________________________________________
 void AliPHOSClusterizerv1::Digits2Clusters(Option_t *option)
 {
@@ -310,7 +260,9 @@ void AliPHOSClusterizerv1::Digits2Clusters(Option_t *option)
     gBenchmark->Stop("PHOSClusterizer");
     AliInfo(Form("took %f seconds for Clusterizing\n",
                 gBenchmark->GetCpuTime("PHOSClusterizer"))); 
-  } 
+  }
+  fEMCRecPoints->Delete();
+  fCPVRecPoints->Delete();
 }
 
 //____________________________________________________________________________
@@ -322,6 +274,8 @@ Bool_t AliPHOSClusterizerv1::FindFit(AliPHOSEmcRecPoint * emcRP, AliPHOSDigit **
   // Cluster will be fitted as a superposition of nPar/3 electromagnetic showers
 
   
+  if(!gMinuit) //it was deleted by someone else
+    gMinuit = new TMinuit(100) ;
   gMinuit->mncler();                     // Reset Minuit's list of paramters
   gMinuit->SetPrintLevel(-1) ;           // No Printout
   gMinuit->SetFCN(AliPHOSClusterizerv1::UnfoldingChiSquare) ;  
@@ -402,24 +356,6 @@ Bool_t AliPHOSClusterizerv1::FindFit(AliPHOSEmcRecPoint * emcRP, AliPHOSDigit **
 
 }
 
-//____________________________________________________________________________
-void AliPHOSClusterizerv1::GetCalibrationParameters() 
-{
-  // Set calibration parameters:
-  // if calibration database exists, they are read from database,
-  // otherwise, reconstruction stops in the constructor of AliPHOSCalibData
-  //
-  // It is a user responsilibity to open CDB before reconstruction, for example: 
-  // AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage("local://CalibDB");
-
-  if (!fgCalibData) 
-    fgCalibData = new AliPHOSCalibData(-1); //use AliCDBManager's run number
-  if (fgCalibData->GetCalibDataEmc() == 0)
-    AliFatal("Calibration parameters for PHOS EMC not found. Stop reconstruction.\n");
-  if (fgCalibData->GetCalibDataCpv() == 0)
-    AliFatal("Calibration parameters for PHOS CPV not found. Stop reconstruction.\n");
-
-}
 
 //____________________________________________________________________________
 void AliPHOSClusterizerv1::Init()
@@ -432,7 +368,12 @@ void AliPHOSClusterizerv1::Init()
   if(!gMinuit) 
     gMinuit = new TMinuit(100);
 
-  GetCalibrationParameters() ;
+  if (!fgCalibData) 
+    fgCalibData = new AliPHOSCalibData(-1); //use AliCDBManager's run number
+  if (fgCalibData->GetCalibDataEmc() == 0)
+    AliFatal("Calibration parameters for PHOS EMC not found. Stop reconstruction.\n");
+  if (fgCalibData->GetCalibDataCpv() == 0)   
+    AliFatal("Calibration parameters for PHOS CPV not found. Stop reconstruction.\n");   
 
 }
 
@@ -443,31 +384,26 @@ void AliPHOSClusterizerv1::InitParameters()
   fNumberOfCpvClusters     = 0 ; 
   fNumberOfEmcClusters     = 0 ; 
 
-  const AliPHOSRecoParam* parEmc = AliPHOSReconstructor::GetRecoParamEmc();
-  if(!parEmc) AliFatal("Reconstruction parameters for EMC not set!");
+  const AliPHOSRecoParam* recoParam = AliPHOSReconstructor::GetRecoParam();
+  if(!recoParam) AliFatal("Reconstruction parameters are not set!");
 
-  const AliPHOSRecoParam* parCpv = AliPHOSReconstructor::GetRecoParamCpv(); 
-  if(!parCpv) AliFatal("Reconstruction parameters for CPV not set!");
+  recoParam->Print();
 
-  fCpvClusteringThreshold  = parCpv->GetClusteringThreshold();
-  fEmcClusteringThreshold  = parEmc->GetClusteringThreshold();
+  fEmcClusteringThreshold  = recoParam->GetEMCClusteringThreshold();
+  fCpvClusteringThreshold  = recoParam->GetCPVClusteringThreshold();
   
-  fEmcLocMaxCut            = parEmc->GetLocalMaxCut();
-  fCpvLocMaxCut            = parCpv->GetLocalMaxCut();
-
-  fEmcMinE                 = parEmc->GetMinE();
-  fCpvMinE                 = parCpv->GetMinE();
+  fEmcLocMaxCut            = recoParam->GetEMCLocalMaxCut();
+  fCpvLocMaxCut            = recoParam->GetCPVLocalMaxCut();
 
-  fW0                      = parEmc->GetLogWeight();
-  fW0CPV                   = parCpv->GetLogWeight();
+  fW0                      = recoParam->GetEMCLogWeight();
+  fW0CPV                   = recoParam->GetCPVLogWeight();
 
-  fEmcTimeGate             = 1.e-8 ; 
+  fEmcTimeGate             = 1.e-6 ;  //10 sample steps
+  fEcoreRadius             = recoParam->GetEMCEcoreRadius();
   
-  fToUnfold                = kTRUE ;
+  fToUnfold                = recoParam->EMCToUnfold() ;
     
   fWrite                   = kTRUE ;
-
-  fIsOldRCUFormat          = kFALSE;
 }
 
 //____________________________________________________________________________
@@ -476,12 +412,11 @@ Int_t AliPHOSClusterizerv1::AreNeighbours(AliPHOSDigit * d1, AliPHOSDigit * d2)c
   // Gives the neighbourness of two digits = 0 are not neighbour but continue searching 
   //                                       = 1 are neighbour
   //                                       = 2 are not neighbour but do not continue searching
+  //                                       =-1 are not neighbour, continue searching, but do not look before d2 next time
   // neighbours are defined as digits having at least a common vertex 
   // The order of d1 and d2 is important: first (d1) should be a digit already in a cluster 
   //                                      which is compared to a digit (d2)  not yet in a cluster  
 
-  Int_t rv = 0 ; 
-
   Int_t relid1[4] ; 
   fGeom->AbsToRelNumbering(d1->GetId(), relid1) ; 
 
@@ -492,43 +427,30 @@ Int_t AliPHOSClusterizerv1::AreNeighbours(AliPHOSDigit * d1, AliPHOSDigit * d2)c
     Int_t rowdiff = TMath::Abs( relid1[2] - relid2[2] ) ;  
     Int_t coldiff = TMath::Abs( relid1[3] - relid2[3] ) ;  
     
-    if (( coldiff <= 1 )  && ( rowdiff <= 1 )){
+    if (( coldiff <= 1 )  && ( rowdiff <= 1 )){   //At least common vertex
+      //    if (( relid1[2]==relid2[2] && coldiff <= 1 )  || ( relid1[3]==relid2[3] &&  rowdiff <= 1 )){ //common side
       if((relid1[1] != 0) || (TMath::Abs(d1->GetTime() - d2->GetTime() ) < fEmcTimeGate))
-      rv = 1 ; 
+      return 1 ; 
     }
     else {
       if((relid2[2] > relid1[2]) && (relid2[3] > relid1[3]+1)) 
-        rv = 2; //  Difference in row numbers is too large to look further 
+        return 2; //  Difference in row numbers is too large to look further 
     }
+    return 0 ;
 
   } 
   else {
+    if(relid1[0] > relid2[0] && relid1[1]==relid2[1] ) //we switched to the next module
+      return -1 ;
+    if(relid1[1] < relid2[1]) //we switched from EMC(0) to CPV(-1)
+      return -1 ;
     
-    if( (relid1[0] < relid2[0]) || (relid1[1] != relid2[1]) )  
-      rv=2 ;
+    return 2 ;
 
   }
 
-  return rv ; 
+  return 0 ; 
 }
-//____________________________________________________________________________
-void AliPHOSClusterizerv1::CleanDigits(TClonesArray * digits)
-{
-  // Remove digits with amplitudes below threshold
-
-  for(Int_t i=0; i<digits->GetEntriesFast(); i++){
-    AliPHOSDigit * digit = static_cast<AliPHOSDigit*>(digits->At(i)) ;
-    if ( (IsInEmc(digit) && CalibrateEMC(digit->GetEnergy(),digit->GetId()) < fEmcMinE) ||
-        (IsInCpv(digit) && CalibrateCPV(digit->GetAmp()   ,digit->GetId()) < fCpvMinE) )
-      digits->RemoveAt(i) ;
-  }
-  digits->Compress() ;
-  for (Int_t i = 0 ; i < digits->GetEntriesFast() ; i++) { 
-    AliPHOSDigit *digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ; 
-    digit->SetIndexInList(i) ;     
-  }
-}
-
 //____________________________________________________________________________
 Bool_t AliPHOSClusterizerv1::IsInEmc(AliPHOSDigit * digit) const
 {
@@ -567,10 +489,12 @@ void AliPHOSClusterizerv1::WriteRecPoints()
   Int_t index ;
   //Evaluate position, dispersion and other RecPoint properties..
   Int_t nEmc = fEMCRecPoints->GetEntriesFast();
+  Float_t emcMinE= AliPHOSReconstructor::GetRecoParam()->GetEMCMinE(); //Minimal digit energy
+  TVector3 fakeVtx(0.,0.,0.) ;
   for(index = 0; index < nEmc; index++){
     AliPHOSEmcRecPoint * rp =
       dynamic_cast<AliPHOSEmcRecPoint *>( fEMCRecPoints->At(index) );
-    rp->Purify(fEmcMinE) ;
+    rp->Purify(emcMinE) ;
     if(rp->GetMultiplicity()==0){
       fEMCRecPoints->RemoveAt(index) ;
       delete rp ;
@@ -578,8 +502,8 @@ void AliPHOSClusterizerv1::WriteRecPoints()
     }
 
     // No vertex is available now, calculate corrections in PID
-    rp->EvalAll(fW0,fDigitsArr) ;
-    TVector3 fakeVtx(0.,0.,0.) ;
+    rp->EvalAll(fDigitsArr) ;
+    rp->EvalCoreEnergy(fW0,fEcoreRadius,fDigitsArr) ;
     rp->EvalAll(fW0,fakeVtx,fDigitsArr) ;
     rp->EvalLocal2TrackingCSTransform();
   }
@@ -596,7 +520,8 @@ void AliPHOSClusterizerv1::WriteRecPoints()
   //Now the same for CPV
   for(index = 0; index < fCPVRecPoints->GetEntries(); index++){
     AliPHOSCpvRecPoint * rp = dynamic_cast<AliPHOSCpvRecPoint *>( fCPVRecPoints->At(index) );
-    rp->EvalAll(fW0CPV,fDigitsArr) ;
+    rp->EvalAll(fDigitsArr) ;
+    rp->EvalAll(fW0CPV,fakeVtx,fDigitsArr) ;
     rp->EvalLocal2TrackingCSTransform();
   }
   fCPVRecPoints->Sort() ;
@@ -617,113 +542,101 @@ void AliPHOSClusterizerv1::MakeClusters()
   // Steering method to construct the clusters stored in a list of Reconstructed Points
   // A cluster is defined as a list of neighbour digits
 
-  //Remove digits below threshold
-  CleanDigits(fDigitsArr) ;
+  fNumberOfCpvClusters     = 0 ;
+  fNumberOfEmcClusters     = 0 ;
 
-  TClonesArray * digitsC =  static_cast<TClonesArray*>( fDigitsArr->Clone() ) ;
-  // Clusterization starts  
+  //Mark all digits as unused yet
+  const Int_t maxNDigits = 3584; // There is no clusters larger than PHOS module ;)
+  Int_t nDigits=fDigitsArr->GetEntriesFast() ;
 
-  TIter nextdigit(digitsC) ; 
+  for(Int_t i=0; i<nDigits; i++){
+    fDigitsUsed[i]=0 ;
+  }
+  Int_t iFirst = 0 ; //first index of digit which potentially can be a part of cluster
+                     //e.g. first digit in this module, first CPV digit etc.
   AliPHOSDigit * digit ; 
-  Bool_t notremoved = kTRUE ;
+  TArrayI clusterdigitslist(maxNDigits) ;   
+  AliPHOSRecPoint * clu = 0 ; 
+  for(Int_t i=0; i<nDigits; i++){
+    if(fDigitsUsed[i])
+      continue ;
 
-  while ( (digit = dynamic_cast<AliPHOSDigit *>( nextdigit()) ) ) { // scan over the list of digitsC
-    
+    digit=static_cast<AliPHOSDigit*>(fDigitsArr->At(i)) ;
 
-    AliPHOSRecPoint * clu = 0 ; 
+    clu=0 ;
 
-    TArrayI clusterdigitslist(1500) ;   
     Int_t index ;
 
-    if (( IsInEmc (digit) &&
-         CalibrateEMC(digit->GetEnergy(),digit->GetId()) > fEmcClusteringThreshold ) || 
-        ( IsInCpv (digit) &&
-         CalibrateCPV(digit->GetAmp()   ,digit->GetId()) > fCpvClusteringThreshold ) ) {
+    //is this digit so energetic that start cluster?
+    if (( IsInEmc(digit) &&  Calibrate(digit->GetEnergy(),digit->GetId()) > fEmcClusteringThreshold ) || 
+        ( IsInCpv(digit) &&  Calibrate(digit->GetEnergy(),digit->GetId()) > fCpvClusteringThreshold ) ) {
       Int_t iDigitInCluster = 0 ; 
-      
       if  ( IsInEmc(digit) ) {   
         // start a new EMC RecPoint
         if(fNumberOfEmcClusters >= fEMCRecPoints->GetSize()) 
           fEMCRecPoints->Expand(2*fNumberOfEmcClusters+1) ;
           
         fEMCRecPoints->AddAt(new  AliPHOSEmcRecPoint(""), fNumberOfEmcClusters) ;
-        clu = dynamic_cast<AliPHOSEmcRecPoint *>( fEMCRecPoints->At(fNumberOfEmcClusters) ) ; 
+        clu = static_cast<AliPHOSEmcRecPoint *>( fEMCRecPoints->At(fNumberOfEmcClusters) ) ; 
        fNumberOfEmcClusters++ ; 
-       clu->AddDigit(*digit, CalibrateEMC(digit->GetEnergy(),digit->GetId())) ;
+       clu->AddDigit(*digit, Calibrate(digit->GetEnergy(),digit->GetId()),CalibrateT(digit->GetTime(),digit->GetId())) ;
         clusterdigitslist[iDigitInCluster] = digit->GetIndexInList() ;
         iDigitInCluster++ ;
-        digitsC->Remove(digit) ; 
-
+        fDigitsUsed[i]=kTRUE ; 
       } else { 
-        
         // start a new CPV cluster
         if(fNumberOfCpvClusters >= fCPVRecPoints->GetSize()) 
           fCPVRecPoints->Expand(2*fNumberOfCpvClusters+1);
 
         fCPVRecPoints->AddAt(new AliPHOSCpvRecPoint(""), fNumberOfCpvClusters) ;
-
-        clu =  dynamic_cast<AliPHOSCpvRecPoint *>( fCPVRecPoints->At(fNumberOfCpvClusters) ) ;  
+        clu =  static_cast<AliPHOSCpvRecPoint *>( fCPVRecPoints->At(fNumberOfCpvClusters) ) ;  
         fNumberOfCpvClusters++ ; 
-        clu->AddDigit(*digit, CalibrateCPV(digit->GetAmp(),digit->GetId()) ) ;        
+        clu->AddDigit(*digit,  Calibrate(digit->GetEnergy(),digit->GetId()),0.) ; // no timing information in CPV
         clusterdigitslist[iDigitInCluster] = digit->GetIndexInList()  ;        
         iDigitInCluster++ ; 
-        digitsC->Remove(digit) ; 
-        nextdigit.Reset() ;
-        
-        // Here we remove remaining EMC digits, which cannot make a cluster
-        
-        if( notremoved ) { 
-          while( ( digit = dynamic_cast<AliPHOSDigit *>( nextdigit() ) ) ) {
-            if( IsInEmc(digit) ) 
-              digitsC->Remove(digit) ;
-            else 
-              break ;
-          }
-          notremoved = kFALSE ;
-        }
-        
+        fDigitsUsed[i]=kTRUE ;
       } // else        
-      
-      nextdigit.Reset() ;
-      
+
+      //Now scan remaining digits in list to find neigbours of our seed
       AliPHOSDigit * digitN ; 
       index = 0 ;
       while (index < iDigitInCluster){ // scan over digits already in cluster 
-        digit =  dynamic_cast<AliPHOSDigit*>( fDigitsArr->At(clusterdigitslist[index]) )  ;      
+        digit =  static_cast<AliPHOSDigit*>( fDigitsArr->At(clusterdigitslist[index]) )  ;      
         index++ ; 
-        while ( (digitN = dynamic_cast<AliPHOSDigit *>( nextdigit() ) ) ) { // scan over the reduced list of digits 
+        for(Int_t j=iFirst; j<nDigits; j++){
+         if (iDigitInCluster >= maxNDigits) {
+           AliError(Form("The number of digits in cluster is more than %d, skip the rest of event",
+                         maxNDigits));
+           return;
+         }
+          if(fDigitsUsed[j]) 
+            continue ;        //look through remaining digits
+          digitN = static_cast<AliPHOSDigit*>( fDigitsArr->At(j) ) ;
           Int_t ineb = AreNeighbours(digit, digitN);       // call (digit,digitN) in THAT oder !!!!!
           switch (ineb ) {
+          case -1:   //too early (e.g. previous module), do not look before j at subsequent passes
+            iFirst=j ;
+            break ;
           case 0 :   // not a neighbour
             break ;
           case 1 :   // are neighbours 
-           if (IsInEmc (digitN))
-             clu->AddDigit(*digitN, CalibrateEMC( digitN->GetEnergy(), digitN->GetId() ) );
-           else
-             clu->AddDigit(*digitN, CalibrateCPV( digitN->GetAmp()   , digitN->GetId() ) );
-
-            clusterdigitslist[iDigitInCluster] = digitN->GetIndexInList() ; 
+           clu->AddDigit(*digitN, Calibrate(digitN->GetEnergy(),digitN->GetId()),CalibrateT(digitN->GetTime(),digitN->GetId())) ;
+            clusterdigitslist[iDigitInCluster] = j ; 
             iDigitInCluster++ ; 
-            digitsC->Remove(digitN) ;
+            fDigitsUsed[j]=kTRUE ;
             break ;
           case 2 :   // too far from each other
-            goto endofloop;   
+            goto endOfLoop;   
           } // switch
           
-        } // while digitN
+        }
         
-      endofloop: ;
-        nextdigit.Reset() ; 
+        endOfLoop: ; //scanned all possible neighbours for this digit
         
       } // loop over cluster     
-
     } // energy theshold  
-
-    
-  } // while digit
-
-  delete digitsC ;
+  }
 
 }
 
@@ -753,6 +666,7 @@ void AliPHOSClusterizerv1::MakeUnfolding()
       
       if( nMax > 1 ) {     // if cluster is very flat (no pronounced maximum) then nMax = 0       
         UnfoldCluster(emcRecPoint, nMax, maxAt, maxAtEnergy) ;
+
         fEMCRecPoints->Remove(emcRecPoint); 
         fEMCRecPoints->Compress() ;
         index-- ;
@@ -835,6 +749,7 @@ void  AliPHOSClusterizerv1::UnfoldCluster(AliPHOSEmcRecPoint * iniEmc,
   Float_t * fitparameters = new Float_t[nPar] ;
 
   Bool_t rv = FindFit(iniEmc, maxAt, maxAtEnergy, nPar, fitparameters) ;
+
   if( !rv ) {
     // Fit failed, return and remove cluster
     iniEmc->SetNExMax(-1) ;
@@ -876,7 +791,6 @@ void  AliPHOSClusterizerv1::UnfoldCluster(AliPHOSEmcRecPoint * iniEmc,
     }
   }
   
-
   // Now create new RecPoints and fill energy lists with efit corrected to fluctuations
   // so that energy deposited in each cell is distributed betwin new clusters proportionally
   // to its contribution to efit
@@ -891,7 +805,7 @@ void  AliPHOSClusterizerv1::UnfoldCluster(AliPHOSEmcRecPoint * iniEmc,
     epar = fitparameters[iparam+2] ;
     iparam += 3 ;    
 //    fGeom->GetIncidentVector(fVtx,iniEmc->GetPHOSMod(),xpar,zpar,vIncid) ;
-    
+
     AliPHOSEmcRecPoint * emcRP = 0 ;  
 
     if(iniEmc->IsEmc()){ //create new entries in fEMCRecPoints...
@@ -921,7 +835,7 @@ void  AliPHOSClusterizerv1::UnfoldCluster(AliPHOSEmcRecPoint * iniEmc,
 //      ratio = epar * ShowerShape(xDigit - xpar,zDigit - zpar,vIncid) / efit[iDigit] ; 
       ratio = epar * ShowerShape(xDigit - xpar,zDigit - zpar) / efit[iDigit] ; 
       eDigit = emcEnergies[iDigit] * ratio ;
-      emcRP->AddDigit( *digit, eDigit ) ;
+      emcRP->AddDigit( *digit, eDigit,CalibrateT(digit->GetTime(),digit->GetId()) ) ;
     }        
   }
  
@@ -1065,7 +979,7 @@ void AliPHOSClusterizerv1::Print(const Option_t *)const
   else 
     message = " AliPHOSClusterizerv1 not initialized " ;
   
-  AliInfo(Form("%s, %s %s %s %s %s %s %s %s %s %s", message.Data(),  
+  AliInfo(Form("%s, %s %s %s %s %f %f %f %f %f %f", message.Data(),  
        taskName.Data(), 
        GetTitle(),
        taskName.Data(), 
@@ -1133,9 +1047,9 @@ void AliPHOSClusterizerv1::SetDistancesToBadChannels()
   //Author: Boris Polichtchouk 
 
   if(!fgCalibData->GetNumOfEmcBadChannels()) return;
-  AliInfo(Form("%d bad channel(s) found.\n",fgCalibData->GetNumOfEmcBadChannels()));
 
   Int_t badIds[8000];
+  memset(badIds,0,8000*sizeof(Int_t));
   fgCalibData->EmcBadChannelIds(badIds);
 
   AliPHOSEmcRecPoint* rp;
@@ -1146,12 +1060,22 @@ void AliPHOSClusterizerv1::SetDistancesToBadChannels()
   TVector3 dR;
 
   Float_t dist,minDist;
-
+  Int_t relid[4]={0,0,0,0} ;
+  TVector3 lpos ;
   for(Int_t iRP=0; iRP<fEMCRecPoints->GetEntries(); iRP++){
     rp = (AliPHOSEmcRecPoint*)fEMCRecPoints->At(iRP);
-    minDist = 1.e+07;
-
+    //evaluate distance to border
+    relid[0]=rp->GetPHOSMod() ;
+    relid[2]=1 ;
+    relid[3]=1 ;
+    Float_t xcorner,zcorner;
+    fGeom->RelPosInModule(relid,xcorner,zcorner) ; //coordinate of the corner cell
+    rp->GetLocalPosition(lpos) ;
+    minDist = 2.2+TMath::Min(-xcorner-TMath::Abs(lpos.X()),-zcorner-TMath::Abs(lpos.Z())); //2.2 - crystal size
     for(Int_t iBad=0; iBad<fgCalibData->GetNumOfEmcBadChannels(); iBad++) {
+      fGeom->AbsToRelNumbering(badIds[iBad],relid)  ;
+      if(relid[0]!=rp->GetPHOSMod()) //We can not evaluate global position directly since 
+        continue ;                   //bad channels can be in the module which does not exist in simulations.
       rp->GetGlobalPosition(gposRecPoint,gmat);
       fGeom->RelPosInAlice(badIds[iBad],gposBadChannel);
       AliDebug(2,Form("BC position:[%.3f,%.3f,%.3f], RP position:[%.3f,%.3f,%.3f]. E=%.3f\n",
@@ -1166,3 +1090,45 @@ void AliPHOSClusterizerv1::SetDistancesToBadChannels()
   }
 
 }
+//==================================================================================
+Float_t AliPHOSClusterizerv1::Calibrate(Float_t amp, Int_t absId) const{
+  // Calibrate EMC digit, i.e. multiply its Amp by a factor read from CDB
+
+  const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
+
+  //Determine rel.position of the cell absolute ID
+  Int_t relId[4];
+  geom->AbsToRelNumbering(absId,relId);
+  Int_t module=relId[0];
+  Int_t row   =relId[2];
+  Int_t column=relId[3];
+  if(relId[1]){ //CPV
+    Float_t calibration = fgCalibData->GetADCchannelCpv(module,column,row);
+    return amp*calibration ;
+  }   
+  else{ //EMC
+    Float_t calibration = fgCalibData->GetADCchannelEmc(module,column,row);
+    return amp*calibration ;
+  }
+}
+//==================================================================================
+Float_t AliPHOSClusterizerv1::CalibrateT(Float_t time, Int_t absId)const{
+  // Calibrate time in EMC digit
+
+  const AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance() ;
+
+  //Determine rel.position of the cell absolute ID
+  Int_t relId[4];
+  geom->AbsToRelNumbering(absId,relId);
+  Int_t module=relId[0];
+  Int_t row   =relId[2];
+  Int_t column=relId[3];
+  if(relId[1]){ //CPV
+    return 0. ;
+  }
+  else{ //EMC
+    time += fgCalibData->GetTimeShiftEmc(module,column,row);
+    return time ;
+  }
+}
+