]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONClusterFinderAZ.cxx
- Added new option (AliMUONVTrackReconstructor::fgkComplementTracks) to add
[u/mrichter/AliRoot.git] / MUON / AliMUONClusterFinderAZ.cxx
index d6f2322eb1fe2e02a0f421609b4debe5c36add85..f48cfe05b64e95c23a3308c357aa444c8c84d9d0 100644 (file)
 
 /* $Id$ */
 
-// Clusterizer class developed by A. Zinchenko (Dubna)
+//-----------------------------------------------------------------------------
+// Class AliMUONClusterFinderAZ
+// -------------------------------
+// Clusterizer class based on the Expectation-Maximization algorithm
+// Author: Alexander Zinchenko, JINR Dubna
+//-----------------------------------------------------------------------------
 
-#include <stdlib.h>
-#include <Riostream.h>
-//#include <TROOT.h>
+#include "AliMUONClusterFinderAZ.h"
+#include "AliMpVSegmentation.h"
+#include "AliMUONGeometryModuleTransformer.h"
+#include "AliMUONVDigit.h"
+#include "AliMUONCluster.h"
+#include "AliMUONPixel.h"
+#include "AliMUONMathieson.h"
+#include "AliMpDEManager.h"
+#include "AliMUONVDigitStore.h"
+#include "AliMUONConstants.h"
+#include "AliRunLoader.h"
+#include "AliLog.h"
+
+#include <TClonesArray.h>
 #include <TH2.h>
 #include <TMinuit.h>
 #include <TMatrixD.h>
+#include <TRandom.h>
+#include <TROOT.h>
+#include <TMath.h>
+#include <Riostream.h>
 
-#include "AliMUONClusterFinderAZ.h"
-#include "AliMUONClusterDrawAZ.h"
-#include "AliHeader.h"
-#include "AliRun.h"
-#include "AliMUON.h"
-//#include "AliMUONChamber.h"
-#include "AliMUONDigit.h"
-//#include "AliMUONHit.h"
-#include "AliMUONRawCluster.h"
-#include "AliMUONClusterInput.h"
-#include "AliMUONPixel.h"
-//#include "AliMC.h"
-//#include "AliMUONLoader.h"
-#include "AliLog.h"
+#include <stdlib.h>
 
+/// \cond CLASSIMP
 ClassImp(AliMUONClusterFinderAZ)
+/// \endcond
  
  const Double_t AliMUONClusterFinderAZ::fgkCouplMin = 1.e-3; // threshold on coupling 
+ const Double_t AliMUONClusterFinderAZ::fgkZeroSuppression = 6; // average zero suppression value
+ const Double_t AliMUONClusterFinderAZ::fgkSaturation = 3000; // average saturation level
  AliMUONClusterFinderAZ* AliMUONClusterFinderAZ::fgClusterFinder = 0x0;
  TMinuit* AliMUONClusterFinderAZ::fgMinuit = 0x0;
 //FILE *lun1 = fopen("nxny.dat","w");
 
 //_____________________________________________________________________________
 AliMUONClusterFinderAZ::AliMUONClusterFinderAZ(Bool_t draw)
-  : AliMUONClusterFinderVS()
+  : AliMUONVClusterFinder(),
+    fNpar(0),
+    fQtot(0),
+    fReco(1),
+    fCathBeg(0),
+//    fDraw(0x0),
+    fPixArray(0x0),
+    fnCoupled(0),
+    fDebug(0), // 0),
+fRawClusters(new TClonesArray("AliMUONCluster",100)),
+fDigitStore(0x0),
+fDetElemId(-1),
+fChamberId(-1),
+fMathieson(0x0),
+fCurrentCluster(-1)
 {
-// Constructor
+/// Constructor
   fnPads[0]=fnPads[1]=0;
   
   for (Int_t i=0; i<7; i++)
     for (Int_t j=0; j<fgkDim; j++)
       fXyq[i][j]= 9999.;
 
-  for (Int_t i=0; i<2; i++)
-    for (Int_t j=0; j<fgkDim; j++) {
+  for (Int_t i=0; i<4; i++)
+    for (Int_t j=0; j<fgkDim; j++) 
       fPadIJ[i][j]=-1;
-      fUsed[i][j] = 0;
-    }
 
-  fSegmentation[1] = fSegmentation[0] = 0;
-  fResponse = 0x0;
+  for (Int_t i=0; i<2; i++)
+    for (Int_t j=0; j<fgkDim; j++) 
+      fUsed[i][j] = 0;
 
-  fZpad = 100000;
-  fNpar = 0;
-  fQtot = 0;
-  fReco = 1;
+  fSegmentation[1] = fSegmentation[0] = 0x0; 
 
-  fCathBeg = 0;
   fPadBeg[0] = fPadBeg[1] = 0;
-  if (!fgMinuit) fgMinuit = new TMinuit(8);
 
+  if (!fgMinuit) fgMinuit = new TMinuit(8);
   if (!fgClusterFinder) fgClusterFinder = this;
-  fDraw = 0;
   fPixArray = new TObjArray(20); 
-  fnCoupled = 0;
-  fDebug = 0; //0;
 
   if (draw) {
     fDebug = 1;
     fReco = 0;
-    fDraw = new AliMUONClusterDrawAZ(this);
+    //    fDraw = new AliMUONClusterDrawAZ(this);
   }
-  cout << " *** Running AZ cluster finder *** " << endl;
+  AliInfo(" *** Running AZ cluster finder *** ");
 }
 
 //_____________________________________________________________________________
-AliMUONClusterFinderAZ::AliMUONClusterFinderAZ(const AliMUONClusterFinderAZ& rhs)
-  : AliMUONClusterFinderVS(rhs)
+AliMUONClusterFinderAZ::~AliMUONClusterFinderAZ()
 {
-// Protected copy constructor
-
-  AliFatal("Not implemented.");
+/// Destructor
+  delete fgMinuit; fgMinuit = 0; delete fPixArray; fPixArray = 0;
+  delete fMathieson;
+//  delete fDraw;
 }
 
 //_____________________________________________________________________________
-AliMUONClusterFinderAZ::~AliMUONClusterFinderAZ()
+Bool_t 
+AliMUONClusterFinderAZ::Prepare(const AliMpVSegmentation* segmentations[2],
+                                const AliMUONVDigitStore& digitStore)
 {
-  // Destructor
-  delete fgMinuit; fgMinuit = 0; delete fPixArray; fPixArray = 0;
-  delete fDraw;
+  /// Prepare for the clusterization of one detection element, which digits
+  /// are in digitStore
+  
+  fSegmentation[0] = segmentations[0];
+  fSegmentation[1] = segmentations[1];
+  fDigitStore = &digitStore;
+  fDetElemId = -1;
+  TIter next(digitStore.CreateIterator());
+  AliMUONVDigit* digit = static_cast<AliMUONVDigit*>(next());
+  if (digit) fDetElemId = digit->DetElemId();
+  fCurrentCluster = -1;
+  if ( fDetElemId > 0 ) 
+  {
+    fChamberId = AliMpDEManager::GetChamberId(fDetElemId);
+    AliMp::StationType stationType = AliMpDEManager::GetStationType(fDetElemId);
+    
+    Float_t kx3 = AliMUONConstants::SqrtKx3();
+    Float_t ky3 = AliMUONConstants::SqrtKy3();
+    Float_t pitch = AliMUONConstants::Pitch();
+    
+    if ( stationType == AliMp::kStation1 )
+    {
+      kx3 = AliMUONConstants::SqrtKx3St1();
+      ky3 = AliMUONConstants::SqrtKy3St1();
+      pitch = AliMUONConstants::PitchSt1();
+    }
+    
+    delete fMathieson;
+    fMathieson = new AliMUONMathieson;
+    
+    fMathieson->SetPitch(pitch);
+    fMathieson->SetSqrtKx3AndDeriveKx2Kx4(kx3);
+    fMathieson->SetSqrtKy3AndDeriveKy2Ky4(ky3);
+    
+    return kTRUE;
+  }
+  return kFALSE;
 }
 
 //_____________________________________________________________________________
-void AliMUONClusterFinderAZ::FindRawClusters()
+AliMUONCluster*
+AliMUONClusterFinderAZ::NextCluster()
 {
-// To provide the same interface as in AliMUONClusterFinderVS
+  /// Return the next cluster in the iteration
+  if ( fCurrentCluster == -1 )
+  {
+    FindRawClusters(0);
+  }
 
+  ++fCurrentCluster;
+  if ( fCurrentCluster <= fRawClusters->GetLast() )
+  {
+    return static_cast<AliMUONCluster*>(fRawClusters->At(fCurrentCluster));
+  }
+  return 0x0;
+}
+
+//_____________________________________________________________________________
+void AliMUONClusterFinderAZ::FindRawClusters(Int_t ch)
+{
+  /// To comply with old old old interface...
   ResetRawClusters(); 
-  EventLoop (gAlice->GetHeader()->GetEvent(), AliMUONClusterInput::Instance()->Chamber());
+  EventLoop (ch);
 }
 
 //_____________________________________________________________________________
-void AliMUONClusterFinderAZ::EventLoop(Int_t nev, Int_t ch)
+void AliMUONClusterFinderAZ::EventLoop(Int_t)
 {
-// Loop over digits
+/// Loop over digits
+  
+ // if (fDraw && !fDraw->FindEvCh(nev, ch)) return;
+
+//  AliInfo("");
+//  fDigitStore->Print();
   
-  if (fDraw && !fDraw->FindEvCh(nev, ch)) return;
-
-  AliMUON *pMuon = (AliMUON*) gAlice->GetModule("MUON");
-  AliMUONChamber *iChamber = &(pMuon->Chamber(ch));
-  fResponse = iChamber->ResponseModel();
-  fSegmentation[0] = AliMUONClusterInput::Instance()->Segmentation2(0);
-  fSegmentation[1] = AliMUONClusterInput::Instance()->Segmentation2(1);
-  //AZ fResponse = AliMUONClusterInput::Instance()->Response();
-    
   Int_t ndigits[2] = {9,9}, nShown[2] = {0};
   if (fReco != 2) { // skip initialization for the combined cluster / track
     fCathBeg = fPadBeg[0] = fPadBeg[1] = 0;
@@ -141,59 +207,44 @@ next:
   if (fReco == 2 && (nShown[0] || nShown[1])) return; // only one precluster for the combined finder
   if (ndigits[0] == nShown[0] && ndigits[1] == nShown[1]) return;
 
-  Float_t xpad, ypad, zpad, zpad0;
   Bool_t first = kTRUE;
-  if (fDebug) cout << " *** Event # " << nev << " chamber: " << ch << endl;
+  if (fDebug) cout << " *** Event # " << AliRunLoader::GetRunLoader()->GetEventNumber() << " det. elem.: " 
+                  << fDetElemId << endl;
   fnPads[0] = fnPads[1] = 0;
-  for (Int_t i = 0; i < fgkDim; i++) fPadIJ[1][i] = 0; 
-
-  for (Int_t iii = fCathBeg; iii < 2; iii++) { 
+  for (Int_t i = 0; i < fgkDim; i++) 
+  {
+    fPadIJ[1][i] = 0;
+    fDigitId[i] = 0;
+  }
+  
+  for (Int_t iii = fCathBeg; iii < 2; iii++) 
+  { 
     Int_t cath = TMath::Odd(iii);
-    ndigits[cath] = AliMUONClusterInput::Instance()->NDigits(cath); 
-    if (!ndigits[0] && !ndigits[1]) return;
-    if (ndigits[cath] == 0) continue;
-    if (fDebug) cout << " ndigits: " << ndigits[cath] << " " << cath << endl;
-
-    AliMUONDigit  *mdig;
-    Int_t digit;
+    TIter next(fDigitStore->CreateIterator(fDetElemId,fDetElemId,cath));
 
+    AliMUONVDigit  *mdig;
     Bool_t eEOC = kTRUE; // end-of-cluster
-    for (digit = fPadBeg[cath]; digit < ndigits[cath]; digit++) {
-      mdig = AliMUONClusterInput::Instance()->Digit(cath,digit); 
-      if (first) {
-       // Find first unused pad
-       if (fUsed[cath][digit]) continue;
-       if (!fSegmentation[cath]->GetPadC(fInput->DetElemId(),mdig->PadX(),mdig->PadY(),xpad,ypad,zpad0)) { 
-         // Handle "non-existing" pads
-         fUsed[cath][digit] = kTRUE; 
-         continue; 
-       } 
-      } else {
-       if (fUsed[cath][digit]) continue;
-       if (!fSegmentation[cath]->GetPadC(fInput->DetElemId(),mdig->PadX(),mdig->PadY(),xpad,ypad,zpad)) {
-         // Handle "non-existing" pads
-         fUsed[cath][digit] = kTRUE; 
-         continue; 
-       } 
-       if (TMath::Abs(zpad-zpad0) > 0.1) continue; // different slats
-       // Find a pad overlapping with the cluster
-       if (!Overlap(cath,mdig)) continue;
+    
+    while ( ( mdig = static_cast<AliMUONVDigit*>(next()) ) )
+    {
+      if (first)
+      {
+        // Find first unused pad
+        if (mdig->IsUsed()) continue;
+      } 
+      else 
+      {
+        if (mdig->IsUsed()) continue;
+        // Find a pad overlapping with the cluster
+        if (!Overlap(cath,*mdig)) continue;
       }
       // Add pad - recursive call
-      AddPad(cath,digit);
-      //AZ !!!!!! Temporary fix of St1 overlap regions !!!!!!!! 
-      if (cath && ch < 2) {
-       Int_t npads = fnPads[0] + fnPads[1] - 1;
-       Int_t cath1 = fPadIJ[0][npads];
-       Int_t idig = TMath::Nint (fXyq[5][npads]);
-       mdig = AliMUONClusterInput::Instance()->Digit(cath1,idig);
-       fSegmentation[cath1]->GetPadC(fInput->DetElemId(),mdig->PadX(),mdig->PadY(),xpad,ypad,zpad);
-       if (TMath::Abs(zpad-zpad0) > 0.1) zpad0 = zpad;
-      }        
+      AddPad(cath,*mdig);
       eEOC = kFALSE;
-      if (digit >= 0) break;
+      break;
     }
-    if (first && eEOC) {
+    if (first && eEOC) 
+    {
       // No more unused pads 
       if (cath == 0) continue; // on cathode #0 - check #1
       else return; // No more clusters
@@ -203,24 +254,38 @@ next:
     if (fDebug) cout << " nPads: " << fnPads[cath] << " " << nShown[cath]+fnPads[cath] << " " << cath << endl;
   } // for (Int_t iii = 0;
 
-  fZpad = zpad0;
-  if (fDraw) fDraw->DrawCluster(); 
+//  if (fDraw) fDraw->DrawCluster(); 
 
   // Use MLEM for cluster finder
   Int_t nMax = 1, localMax[100], maxPos[100];
   Double_t maxVal[100];
   
   if (CheckPrecluster(nShown)) {
+//    AliInfo("After CheckPrecluster");
+//    Print();
     BuildPixArray();
-    if (fnPads[0]+fnPads[1] > 50) nMax = FindLocalMaxima(localMax, maxVal);
+//    AliInfo("PixArray");
+//    fPixArray->Print();
+    //*
+    if (fnPads[0]+fnPads[1] > 50) nMax = FindLocalMaxima(fPixArray, localMax, maxVal);
     if (nMax > 1) TMath::Sort(nMax, maxVal, maxPos, kTRUE); // in decreasing order
     Int_t iSimple = 0, nInX = -1, nInY;
     PadsInXandY(nInX, nInY);
     if (fDebug) cout << "Pads in X and Y: " << nInX << " " << nInY << endl;
     if (nMax == 1 && nInX < 4 && nInY < 4) iSimple = 1; //1; // simple cluster
+    //*/
+    /* For test
+    Int_t iSimple = 0, nInX = -1, nInY;
+    PadsInXandY(nInX, nInY);
+    if (fDebug) cout << "Pads in X and Y: " << nInX << " " << nInY << endl;
+    if (nMax == 1 && nInX < 4 && nInY < 4) iSimple = 1; //1; // simple cluster
+    if (!iSimple) nMax = FindLocalMaxima(fPixArray, localMax, maxVal);
+    nMax = 1;
+    if (nMax > 1) TMath::Sort(nMax, maxVal, maxPos, kTRUE); // in decreasing order
+    */
     for (Int_t i=0; i<nMax; i++) {
       if (nMax > 1) FindCluster(localMax, maxPos[i]);
-      if (!MainLoop(iSimple)) cout << " MainLoop failed " << endl;
+      MainLoop(iSimple);
       if (i < nMax-1) {
        for (Int_t j=0; j<fnPads[0]+fnPads[1]; j++) {
          if (fPadIJ[1][j] == 0) continue; // pad charge was not modified
@@ -228,80 +293,88 @@ next:
          fXyq[2][j] = fXyq[6][j]; // use backup charge value
        }
       }
-    }
+    } // for (Int_t i=0; i<nMax;
+    delete gROOT->FindObject("anode");
+    TH2D *mlem = (TH2D*) gROOT->FindObject("mlem");
+    if (mlem) mlem->Delete();
   }
-  if (!fDraw || fDraw->Next()) goto next;
+//  if (!fDraw || fDraw->Next()) goto next;
+     goto next;
 }
 
 //_____________________________________________________________________________
-void AliMUONClusterFinderAZ::AddPad(Int_t cath, Int_t digit)
+void AliMUONClusterFinderAZ::AddPad(Int_t cath, AliMUONVDigit& mdig)
 {
-  // Add pad to the cluster
-  AliMUONDigit *mdig = AliMUONClusterInput::Instance()->Digit(cath,digit); //AZ
+/// Add pad to the cluster
 
-  Int_t charge = mdig->Signal();
+//  AliInfo("");
+//  StdoutToAliWarning(mdig.Print(););
+  
+  Float_t charge = mdig.Charge();
+
+  AliMpPad pad = fSegmentation[cath]->PadByIndices(AliMpIntPair(mdig.PadX(),mdig.PadY()));
+  
   // get the center of the pad
-  Float_t xpad, ypad, zpad0; //, zpad;
-  if (!fSegmentation[cath]->GetPadC(fInput->DetElemId(),mdig->PadX(),mdig->PadY(),xpad,ypad,zpad0)) {    // Handle "non-existing" pads
-    fUsed[cath][digit] = kTRUE; 
-    return; 
-  } 
-  Int_t isec = fSegmentation[cath]->Sector(fInput->DetElemId(), mdig->PadX(), mdig->PadY());
+  Float_t xpad = pad.Position().X();
+  Float_t ypad = pad.Position().Y();
+  
+//  Int_t isec = fSegmentation[cath]->Sector(mdig.PadX(), mdig.PadY());
   Int_t nPads = fnPads[0] + fnPads[1];
   fXyq[0][nPads] = xpad;
   fXyq[1][nPads] = ypad;
   fXyq[2][nPads] = charge;
-  fXyq[3][nPads] = fSegmentation[cath]->Dpx(fInput->DetElemId(),isec)/2;
-  fXyq[4][nPads] = fSegmentation[cath]->Dpy(fInput->DetElemId(),isec)/2;
-  fXyq[5][nPads] = digit;
+  fXyq[3][nPads] = pad.Dimensions().X();
+  fXyq[4][nPads] = pad.Dimensions().Y();
+  fXyq[5][nPads] = -1;
+  fDigitId[nPads] = mdig.GetUniqueID();
   fXyq[6][nPads] = 0;
   fPadIJ[0][nPads] = cath;
   fPadIJ[1][nPads] = 0;
-  fUsed[cath][digit] = kTRUE;
-  if (fDebug) printf(" bbb %d %d %f %f %f %f %f %4d %3d %3d\n", nPads, cath, xpad, ypad, zpad0, fXyq[3][nPads]*2, fXyq[4][nPads]*2, charge, mdig->PadX(), mdig->PadY());
+  fPadIJ[2][nPads] = mdig.PadX();
+  fPadIJ[3][nPads] = mdig.PadY();
+  mdig.Used(kTRUE);
+  if (fDebug) printf(" bbb %d %d %f %f %f %f %f %3d %3d \n", nPads, cath, 
+                     xpad, ypad, fXyq[3][nPads]*2, fXyq[4][nPads]*2, 
+                     charge, mdig.PadX(), mdig.PadY());
   fnPads[cath]++;
 
   // Check neighbours
-  Int_t nn, ix, iy, xList[10], yList[10];
-  AliMUONDigit  *mdig1;
-
-  Int_t ndigits = AliMUONClusterInput::Instance()->NDigits(cath); 
-  fSegmentation[cath]->Neighbours(fInput->DetElemId(),mdig->PadX(),mdig->PadY(),&nn,xList,yList); 
-  for (Int_t in=0; in<nn; in++) {
-    ix=xList[in];
-    iy=yList[in];
-    for (Int_t digit1 = 0; digit1 < ndigits; digit1++) {
-      if (digit1 == digit) continue;
-      mdig1 = AliMUONClusterInput::Instance()->Digit(cath,digit1); 
-      if (!fUsed[cath][digit1] && mdig1->PadX() == ix && mdig1->PadY() == iy) {
-       //AZ--- temporary fix on edges
-       //fSegmentation[cath]->GetPadC(mdig1->PadX(), mdig1->PadY(), xpad, ypad, zpad);
-       //if (TMath::Abs(zpad-zpad0) > 0.5) continue;
-       //AZ---
-       fUsed[cath][digit1] = kTRUE;
-       // Add pad - recursive call
-       AddPad(cath,digit1);
-      }
-    } //for (Int_t digit1 = 0;
-  } // for (Int_t in=0;
+  TObjArray neighbours;
+  Int_t nn = fSegmentation[cath]->GetNeighbours(pad,neighbours);
+  for (Int_t in = 0; in < nn; ++in) 
+  {
+    AliMpPad* p = static_cast<AliMpPad*>(neighbours.At(in));
+    AliMUONVDigit* mdig1 = static_cast<AliMUONVDigit*>
+      (fDigitStore->FindObject(fDetElemId,
+                               p->GetLocation().GetFirst(),
+                               p->GetLocation().GetSecond(),
+                               cath));
+    if ( mdig1 && !mdig1->IsUsed() )
+    {
+      AddPad(cath,*mdig1);
+    }
+  } // for (Int_t in = 0;
 }
 
 //_____________________________________________________________________________
-Bool_t AliMUONClusterFinderAZ::Overlap(Int_t cath, AliMUONDigit *mdig)
+Bool_t AliMUONClusterFinderAZ::Overlap(Int_t cath, const AliMUONVDigit& mdig)
 {
-  // Check if the pad from one cathode overlaps with a pad 
-  // in the precluster on the other cathode
+/// Check if the pad from one cathode overlaps with a pad 
+/// in the precluster on the other cathode
+
+  AliMpPad pad = fSegmentation[cath]->PadByIndices(AliMpIntPair(mdig.PadX(), mdig.PadY()));
 
-  Float_t xpad, ypad, zpad;
-  fSegmentation[cath]->GetPadC(fInput->DetElemId(),mdig->PadX(),mdig->PadY(),xpad,ypad,zpad);
-  Int_t   isec = fSegmentation[cath]->Sector(fInput->DetElemId(),mdig->PadX(), mdig->PadY());
+  Float_t xpad = pad.Position().X();
+  Float_t ypad = pad.Position().Y();
 
+  Float_t dx = pad.Dimensions().X();
+  Float_t dy = pad.Dimensions().Y();
+  
   Float_t xy1[4], xy12[4];
-  xy1[0] = xpad - fSegmentation[cath]->Dpx(fInput->DetElemId(),isec)/2;
-  xy1[1] = xy1[0] + fSegmentation[cath]->Dpx(fInput->DetElemId(),isec);
-  xy1[2] = ypad - fSegmentation[cath]->Dpy(fInput->DetElemId(),isec)/2;
-  xy1[3] = xy1[2] + fSegmentation[cath]->Dpy(fInput->DetElemId(),isec);
-  //cout << " ok " << fnPads[0]+fnPads[1] << xy1[0] << xy1[1] << xy1[2] << xy1[3] << endl;
+  xy1[0] = xpad - dx;
+  xy1[1] = xy1[0] + dx*2;
+  xy1[2] = ypad - dy;
+  xy1[3] = xy1[2] + dy*2;
 
   Int_t cath1 = TMath::Even(cath);
   for (Int_t i=0; i<fnPads[0]+fnPads[1]; i++) {
@@ -314,7 +387,7 @@ Bool_t AliMUONClusterFinderAZ::Overlap(Int_t cath, AliMUONDigit *mdig)
 //_____________________________________________________________________________
 Bool_t AliMUONClusterFinderAZ::Overlap(Float_t *xy1, Int_t iPad, Float_t *xy12, Int_t iSkip)
 {
-  // Check if the pads xy1 and iPad overlap and return overlap area
+/// Check if the pads xy1 and iPad overlap and return overlap area
 
   Float_t xy2[4];
   xy2[0] = fXyq[0][iPad] - fXyq[3][iPad];
@@ -331,13 +404,72 @@ Bool_t AliMUONClusterFinderAZ::Overlap(Float_t *xy1, Int_t iPad, Float_t *xy12,
   return kTRUE;
 }
 
+//_____________________________________________________________________________
+void
+AliMUONClusterFinderAZ::Used(Int_t indx, Bool_t value)
+{
+  /// Change the Used status of the pad at index indx
+  AliMUONVDigit* digit = static_cast<AliMUONVDigit*>
+  (fDigitStore->FindObject(fDigitId[indx]));
+  if (!digit)
+  {
+    AliError(Form("Did not find digit %d",fDigitId[indx]));
+  }
+  else
+  {
+    digit->Used(value);
+  }
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONClusterFinderAZ::PrintPixel(Int_t i) const
+{
+  /// Printout one pixel
+  AliMUONPixel* pixel = static_cast<AliMUONPixel*>(fPixArray->UncheckedAt(i));
+  if (pixel) pixel->Print();
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONClusterFinderAZ::PrintPad(Int_t i) const
+{
+  /// Printout one pad
+  Int_t cathode = fPadIJ[0][i];
+  UInt_t index = fDigitId[i];
+  Int_t ix = fPadIJ[2][i];
+  Int_t iy = fPadIJ[3][i];
+  
+  cout << Form("i=%4d status %1d cathode %1d index %u ix %3d iy %3d (x,y)=(%7.2f,%7.2f) (dx,dy)=(%7.2f,%7.2f) Q=%7.2f",
+               i,fPadIJ[1][i],cathode,index,ix,iy,fXyq[0][i],fXyq[1][i],
+               fXyq[3][i],fXyq[4][i],
+               fXyq[2][i]) << endl;
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONClusterFinderAZ::Print(Option_t*) const
+{
+  /// Print current state
+  Int_t nPads = fnPads[0] + fnPads[1];
+  cout << "PreCluster npads=" << nPads << "(" << fnPads[0] << "," 
+    << fnPads[1] << ")" << endl;
+  for ( Int_t i = 0; i < nPads; ++i )
+  {
+    PrintPad(i);
+  }
+}
+
 //_____________________________________________________________________________
 Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
 {
-  // Check precluster in order to attempt to simplify it (mostly for
-  // two-cathode preclusters)
+/// Check precluster in order to attempt to simplify it (mostly for
+/// two-cathode preclusters)
 
-  Int_t i1, i2, cath=0, digit=0;
+//  AliInfo("CheckPrecluster");
+//  Print();
+  
+  Int_t i1, i2, cath=0;
   Float_t xy1[4], xy12[4];
   
   Int_t npad = fnPads[0] + fnPads[1];
@@ -349,7 +481,9 @@ Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
   }
 
   // If pads have the same size take average of pads on both cathodes 
-  Int_t sameSize = (fnPads[0] && fnPads[1]) ? 1 : 0;
+  //Int_t sameSize = (fnPads[0] && fnPads[1]) ? 1 : 0;
+  Int_t sameSize = 0; //AZ - 17-01-06
+  
   if (sameSize) {
     Double_t xSize = -1, ySize = 0;
     for (Int_t i=0; i<npad; i++) {
@@ -388,16 +522,19 @@ Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
        fXyq[2][fnPads[0]] += fXyq[2][j];
        div = 2;
        fXyq[2][j] = -2;
-       if (cath) fXyq[5][fnPads[0]] = fXyq[5][j]; // save digit number for cath 0
+       if (cath) fDigitId[fnPads[0]] = fDigitId[j]; // save digit number for cath 0
        break;
       }
       // Flag that the digit from the other cathode
-      if (cath && div == 1) fXyq[5][fnPads[0]] = -fXyq[5][i] - 1; 
+      // LA commented  if (cath && div == 1) fXyq[5][fnPads[0]] = -fXyq[5][i] - 1; 
+      if (cath && div == 1) fDigitId[fnPads[0]] = fDigitId[i]; 
       // If low pad charge take the other equal to 0 
-      if (div == 1 && fXyq[2][fnPads[0]] < fResponse->ZeroSuppression() + 1.5*3) div = 2;
+      //if (div == 1 && fXyq[2][fnPads[0]] < fgkZeroSuppression + 1.5*3) div = 2;
       fXyq[2][fnPads[0]] /= div;
       fXyq[0][fnPads[0]] = fXyq[0][i];
       fXyq[1][fnPads[0]] = fXyq[1][i];
+      fPadIJ[2][fnPads[0]] = fPadIJ[2][i];
+      fPadIJ[3][fnPads[0]] = fPadIJ[3][i];
       fPadIJ[0][fnPads[0]++] = 0;
     }
   } // if (sameSize)
@@ -434,21 +571,23 @@ Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
     }
     if (fDebug && nFlags) cout << " nFlags = " << nFlags << endl;
     //if (nFlags > 2 || (Float_t)nFlags / npad > 0.2) { // why 2 ??? - empirical choice
-    if (nFlags > 1) {
+    if (nFlags > 0) {
       for (Int_t i=0; i<npad; i++) {
-       if (flags[i]) continue;
-       digit = TMath::Nint (fXyq[5][i]);
-       cath = fPadIJ[0][i];
-       // Check for edge effect (missing pads on the other cathode)
-       Int_t cath1 = TMath::Even(cath), ix, iy;
-       if (!fSegmentation[cath1]->GetPadI(fInput->DetElemId(),fXyq[0][i],fXyq[1][i],fZpad,ix,iy)) continue;
-       fUsed[cath][digit] = kFALSE; // release pad
-       fXyq[2][i] = -2;
-       fnPads[cath]--;
+        if (flags[i]) continue;
+        cath = fPadIJ[0][i];
+        // Check for edge effect (missing pads on the other cathode)
+        Int_t cath1 = TMath::Even(cath), ix, iy;
+        ix = iy = 0;
+        AliMpPad pad = fSegmentation[cath1]->PadByPosition(TVector2(fXyq[0][i], fXyq[1][i]));
+        if (!pad.IsValid()) continue;
+        if (nFlags == 1 && fXyq[2][i] < fgkZeroSuppression * 3) continue;
+        Used(i,kFALSE);
+        fXyq[2][i] = -2;
+        fnPads[cath]--;
       }
-      if (fDraw) fDraw->UpdateCluster(npad);
+      //      if (fDraw) fDraw->UpdateCluster(npad);
     } // if (nFlags > 2)
-
+    
     // Check correlations of cathode charges
     if (fnPads[0] && fnPads[1]) { // two-cathode
       Double_t sum[2]={0};
@@ -456,8 +595,7 @@ Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
       for (Int_t i=0; i<npad; i++) {
        cath = fPadIJ[0][i];
        if (fXyq[2][i] > 0) sum[cath] += fXyq[2][i];
-       //AZ if (fXyq[2][i] > fResponse->MaxAdc()-1) over[cath] = 0;
-       if (fXyq[2][i] > fResponse->Saturation()-1) over[cath] = 0;
+       if (fXyq[2][i] > fgkSaturation-1) over[cath] = 0;
       }
       if (fDebug) cout << " Total charge: " << sum[0] << " " << sum[1] << endl;
       if ((over[0] || over[1]) && TMath::Abs(sum[0]-sum[1])/(sum[0]+sum[1])*2 > 1) { // 3 times difference
@@ -514,8 +652,7 @@ Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
                 cmax = TMath::Max((Double_t)(fXyq[2][indx]),cmax);
            else cmax = fXyq[2][indx];
            xmax = dist[indx];
-           digit = TMath::Nint (fXyq[5][indx]);
-           fUsed[cath][digit] = kFALSE; 
+      Used(indx,kFALSE);
            fXyq[2][indx] = -2;
            fnPads[cath]--;
          } 
@@ -550,7 +687,7 @@ Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
          }
        }
        delete [] dist; dist = 0;
-       if (fDraw) fDraw->UpdateCluster(npad);
+//     if (fDraw) fDraw->UpdateCluster(npad);
       } // TMath::Abs(sum[0]-sum[1])...
     } // if (fnPads[0] && fnPads[1])
     delete [] flags; flags = 0;
@@ -566,7 +703,7 @@ Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
     for (Int_t j=end; j>beg; j--) {
       if (fXyq[2][j] < 0) continue;
       end = j - 1;
-      for (Int_t j1=0; j1<2; j1++) {
+      for (Int_t j1=0; j1<4; j1++) {
        padij = fPadIJ[j1][beg]; 
        fPadIJ[j1][beg] = fPadIJ[j1][j];
        fPadIJ[j1][j] = padij;
@@ -581,7 +718,10 @@ Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
     beg++;
   } // while
   npad = fnPads[0] + fnPads[1];
-  if (npad > 500) { cout << " ***** Too large cluster. Give up. " << npad << endl; return kFALSE; }
+  if (npad > 500) { 
+    AliWarning(Form(" *** Too large cluster. Give up. %d ", npad));
+    return kFALSE; 
+  }
   // Back up charge value
   for (Int_t j = 0; j < npad; j++) fXyq[6][j] = fXyq[2][j];
 
@@ -591,7 +731,7 @@ Bool_t AliMUONClusterFinderAZ::CheckPrecluster(Int_t *nShown)
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::BuildPixArray()
 {
-  // Build pixel array for MLEM method
+/// Build pixel array for MLEM method
   
   Int_t nPix=0, i1, i2;
   Float_t xy1[4], xy12[4];
@@ -698,7 +838,7 @@ void AliMUONClusterFinderAZ::BuildPixArray()
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::AdjustPixel(Float_t width, Int_t ixy)
 {
-  // Check if some pixels have small size (adjust if necessary)
+/// Check if some pixels have small size (adjust if necessary)
 
   AliMUONPixel *pixPtr, *pixPtr1 = 0;
   Int_t ixy1 = TMath::Even(ixy);
@@ -717,7 +857,6 @@ void AliMUONClusterFinderAZ::AdjustPixel(Float_t width, Int_t ixy)
        if (TMath::Abs(pixPtr1->Coord(ixy1)-pixPtr->Coord(ixy1)) > 1.e-4) continue; // different rows/columns
        if (TMath::Abs(pixPtr1->Coord(ixy)-pixPtr->Coord(ixy)) < 2*width) {
          // merge
-         //AZ-problem in slats for new segment. pixPtr->SetCoord(ixy, (pixPtr->Coord(ixy)+pixPtr1->Coord(ixy))/2);
          Double_t tmp = pixPtr->Coord(ixy) + pixPtr1->Size(ixy) * 
            TMath::Sign (1., pixPtr1->Coord(ixy) - pixPtr->Coord(ixy));
          pixPtr->SetCoord(ixy, tmp);
@@ -753,11 +892,11 @@ void AliMUONClusterFinderAZ::AdjustPixel(Float_t width, Int_t ixy)
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::AdjustPixel(Float_t wxmin, Float_t wymin)
 {
-  // Check if some pixels have large size (adjust if necessary)
+/// Check if some pixels have large size (adjust if necessary)
 
   Int_t n1[2], n2[2], iOK = 1, nPix = fPixArray->GetEntriesFast();
   AliMUONPixel *pixPtr, pix;
-  Double_t xy0[2] = {9999, 9999}, wxy[2], dist[2];
+  Double_t xy0[2] = {9999, 9999}, wxy[2], dist[2] = {0};
 
   // Check if large pixel size
   for (Int_t i = 0; i < nPix; i++) {
@@ -795,7 +934,11 @@ void AliMUONClusterFinderAZ::AdjustPixel(Float_t wxmin, Float_t wymin)
     if (fDebug) cout << " Different " << pixPtr->Size(0) << " " << wxy[0] << " "
                     << pixPtr->Size(1) << " " << wxy[1] <<endl;
     
-    if (n2[0] > 2 || n2[1] > 2) { cout << n2[0] << " " << n2[1] << endl; AliFatal("Too large pixel."); }
+    if (n2[0] > 2 || n2[1] > 2) { 
+      //cout << n2[0] << " " << n2[1] << endl; 
+      if (n2[0] > 2 && n1[0] < 999) n1[0]--;
+      if (n2[1] > 2 && n1[1] < 999) n1[1]--;
+    }
     //cout << n1[0] << " " << n2[0] << " " << n1[1] << " " << n2[1] << endl;
     pix = *pixPtr;
     pix.SetSize(0, wxy[0]); pix.SetSize(1, wxy[1]);
@@ -812,10 +955,27 @@ void AliMUONClusterFinderAZ::AdjustPixel(Float_t wxmin, Float_t wymin)
   } // for (Int_t i = 0; i < nPix;
 }
 
+//_____________________________________________________________________________
+Float_t
+AliMUONClusterFinderAZ::ChargeIntegration(Double_t x, Double_t y,
+                                          Double_t padX, Double_t padY,
+                                          Double_t padDX, Double_t padDY)
+{
+  /// Compute the Mathieson integral on pad area, assuming the center
+  /// of the Mathieson is at (x,y)
+  
+  Double_t llx = x - padX - padDX;
+  Double_t lly = y - padY - padDY;
+  Double_t urx = llx + 2.0*padDX;
+  Double_t ury = lly + 2.0*padDY;
+  
+  return fMathieson->IntXY(llx,lly,urx,ury);
+}
+
 //_____________________________________________________________________________
 Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
 {
-  // Repeat MLEM algorithm until pixel size becomes sufficiently small
+/// Repeat MLEM algorithm until pixel size becomes sufficiently small
   
   TH2D *mlem;
 
@@ -827,7 +987,7 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
   AddVirtualPad(); // add virtual pads if necessary
   Int_t npadTot = fnPads[0] + fnPads[1], npadOK = 0;
   for (Int_t i = 0; i < npadTot; i++) if (fPadIJ[1][i] == 0) npadOK++;
-  if (fDraw) fDraw->ResetMuon();
+//  if (fDraw) fDraw->ResetMuon();
 
   while (1) {
 
@@ -840,33 +1000,42 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
     coef = new Double_t [npadTot*nPix];
     probi = new Double_t [nPix];
     for (Int_t ipix=0; ipix<nPix; ipix++) probi[ipix] = 0;
-    Int_t indx = 0, indx1 = 0, cath = 0;
+    Int_t indx = 0, indx1 = 0;
 
-    for (Int_t j=0; j<npadTot; j++) {
+    for (Int_t j=0; j<npadTot; j++) 
+    {
       indx = j*nPix;
-      if (fPadIJ[1][j] == 0) {
-       cath = fPadIJ[0][j];
-       fSegmentation[cath]->GetPadI(fInput->DetElemId(),fXyq[0][j],fXyq[1][j],fZpad,ix,iy);
-       fSegmentation[cath]->SetPad(fInput->DetElemId(),ix,iy);
-       /*
-         fSegmentation[cath]->Neighbours(fInput->DetElemId(),ix,iy,&nn,xList,yList); 
-         if (nn != 4) {
-         cout << nn << ": ";
-         for (Int_t i=0; i<nn; i++) {cout << xList[i] << " " << yList[i] << ", ";}
-         cout << endl;
-         }
-       */
-      }
-
-      for (Int_t ipix=0; ipix<nPix; ipix++) {
-       indx1 = indx + ipix;
-       if (fPadIJ[1][j] < 0) { coef[indx1] = 0; continue; }
-       pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(ipix);
-       fSegmentation[cath]->SetHit(fInput->DetElemId(),pixPtr->Coord(0),pixPtr->Coord(1),fZpad);
-       coef[indx1] = fResponse->IntXY(fInput->DetElemId(),fSegmentation[cath]);
-       probi[ipix] += coef[indx1];
+      
+//      if (fPadIJ[1][j] == 0) 
+//      {
+//        cath = fPadIJ[0][j];
+//        ix = fPadIJ[2][j];
+//        iy = fPadIJ[3][j];
+//        fSegmentation[cath]->SetPad(ix, iy);
+//      }
+      
+      for (Int_t ipix=0; ipix<nPix; ipix++) 
+      {
+        indx1 = indx + ipix;
+        if (fPadIJ[1][j] < 0) { coef[indx1] = 0; continue; }
+        pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(ipix);
+
+        Float_t q = ChargeIntegration(pixPtr->Coord(0),pixPtr->Coord(1),
+                                      fXyq[0][j],fXyq[1][j],  
+                                      TMath::Abs(fXyq[3][j]),fXyq[4][j]);
+        
+//        AliInfo(Form("pad %d pixel %d",j,ipix));
+//        PrintPad(j);
+//        PrintPixel(ipix);
+        
+        coef[indx1] = q;
+        probi[ipix] += coef[indx1];
+        
+//        AliInfo(Form("indx1=%d q=%e",indx1,q));
+        
       } // for (Int_t ipix=0;
     } // for (Int_t j=0;
+    
     for (Int_t ipix=0; ipix<nPix; ipix++) if (probi[ipix] < 0.01) pixPtr->SetCharge(0); // "invisible" pixel
 
     // MLEM algorithm
@@ -877,7 +1046,7 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
       pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(ipix);
       //cout << ipix+1; pixPtr->Print();
       for (Int_t i=0; i<4; i++) 
-       xylim[i] = TMath::Min (xylim[i], (i%2 ? -1 : 1)*pixPtr->Coord(i/2));
+        xylim[i] = TMath::Min (xylim[i], (i%2 ? -1 : 1)*pixPtr->Coord(i/2));
     }
     for (Int_t i=0; i<4; i++) {
       xylim[i] -= pixPtr->Size(i/2); if (fDebug) cout << (i%2 ? -1 : 1)*xylim[i] << " "; }
@@ -885,7 +1054,7 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
 
     // Adjust histogram to approximately the same limits as for the pads
     // (for good presentation)
-    if (fDraw) fDraw->AdjustHist(xylim, pixPtr);
+//    if (fDraw) fDraw->AdjustHist(xylim, pixPtr);
 
     Int_t nx = TMath::Nint ((-xylim[1]-xylim[0])/pixPtr->Size(0)/2);
     Int_t ny = TMath::Nint ((-xylim[3]-xylim[2])/pixPtr->Size(1)/2);
@@ -895,7 +1064,7 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
       pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(ipix);
       mlem->Fill(pixPtr->Coord(0),pixPtr->Coord(1),pixPtr->Charge());
     }
-    if (fDraw) fDraw->DrawHist("c2", mlem);
+//    if (fDraw) fDraw->DrawHist("c2", mlem);
 
     // Check if the total charge of pixels is too low
     Double_t qTot = 0;
@@ -903,7 +1072,6 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
       pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(i);
       qTot += pixPtr->Charge();
     }
-    //AZ if (qTot < 1.e-4 || npadOK < 3 && qTot < 50) {
     if (qTot < 1.e-4 || npadOK < 3 && qTot < 7) {
       delete [] coef; delete [] probi; coef = 0; probi = 0;
       fPixArray->Delete(); 
@@ -921,8 +1089,7 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
        pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(i);
        sum1 += pixPtr->Charge()*coef[j*nPix+i];
       }
-      //AZsum1 = TMath::Min (sum1,(Double_t)fResponse->MaxAdc());
-      sum1 = TMath::Min (sum1,(Double_t)fResponse->Saturation());
+      sum1 = TMath::Min (sum1,fgkSaturation);
       x = fXyq[0][j];
       y = fXyq[1][j];
       cath = fPadIJ[0][j];
@@ -948,7 +1115,6 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
 
     if (iSimple) {
       // Simple cluster - skip further passes thru EM-procedure
-      //fxyMu[0][6] = fxyMu[1][6] = 9999;
       Simple();
       delete [] coef; delete [] probi; coef = 0; probi = 0;
       fPixArray->Delete(); 
@@ -1070,7 +1236,7 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
     //  if (probi[i] < 1.9) pixPtr->SetCharge(-charge);
     //}
     //AZ else if (probi[i] < cmax*0.9) pixPtr->SetCharge(-charge);
-    else if (probi[i] < cmax*0.8) pixPtr->SetCharge(-charge);
+    //18-01-06 else if (probi[i] < cmax*0.8) pixPtr->SetCharge(-charge);
     //cout << i << " " << pixPtr->Coord(0) << " " << pixPtr->Coord(1) << " " << charge << " " << probi[i] << endl;
   }
   // Move charge of removed pixels to their nearest neighbour (to keep total charge the same)
@@ -1093,9 +1259,8 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
     iy = mlem->GetYaxis()->FindBin(pixPtr->Coord(1));
     mlem->SetBinContent(ix, iy, pixPtr->Charge());
   }
-  if (fDraw) fDraw->DrawHist("c2", mlem);
+//  if (fDraw) fDraw->DrawHist("c2", mlem);
 
-  //fxyMu[0][6] = fxyMu[1][6] = 9999;
   // Try to split into clusters
   Bool_t ok = kTRUE;
   if (mlem->GetSum() < 1) ok = kFALSE;
@@ -1108,16 +1273,21 @@ Bool_t AliMUONClusterFinderAZ::MainLoop(Int_t iSimple)
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::Mlem(Double_t *coef, Double_t *probi, Int_t nIter)
 {
-  // Use MLEM to find pixel charges
+/// Use MLEM to find pixel charges
   
   Int_t nPix = fPixArray->GetEntriesFast();
   Int_t npad = fnPads[0] + fnPads[1];
   Double_t *probi1 = new Double_t [nPix];
+  Double_t *chargeNew = new Double_t [nPix];
   Double_t probMax = 0;
   Int_t indx, indx1;
   AliMUONPixel *pixPtr;
 
-  for (Int_t ipix=0; ipix<nPix; ipix++) if (probi[ipix] > probMax) probMax = probi[ipix];
+  for (Int_t ipix=0; ipix<nPix; ++ipix) {
+    if (probi[ipix] > probMax) probMax = probi[ipix];
+    chargeNew[ipix] = 0;
+  }
+
   for (Int_t iter=0; iter<nIter; iter++) {
     // Do iterations
     for (Int_t ipix=0; ipix<nPix; ipix++) {
@@ -1136,23 +1306,28 @@ void AliMUONClusterFinderAZ::Mlem(Double_t *coef, Double_t *probi, Int_t nIter)
          pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(i);
          sum1 += pixPtr->Charge()*coef[indx1+i];
        } // for (Int_t i=0;
-       //AZ if (fXyq[2][j] > fResponse->MaxAdc()-1 && sum1 > fResponse->MaxAdc()) { probi1[ipix] -= coef[indx]; continue; } // correct for pad charge overflows
-       if (fXyq[2][j] > fResponse->Saturation()-1 && sum1 > fResponse->Saturation()) { probi1[ipix] -= coef[indx]; continue; } // correct for pad charge overflows
+       if (fXyq[2][j] > fgkSaturation-1 && sum1 > fXyq[2][j]) { probi1[ipix] -= coef[indx]; continue; } // correct for pad charge overflows
        //cout << sum1 << " " << fXyq[2][j] << " " << coef[j*nPix+ipix] << endl;
-       if (coef[indx] > 1.e-6) sum += fXyq[2][j]*coef[indx]/sum1;
+       if (sum1 > 1.e-6) sum += fXyq[2][j]*coef[indx]/sum1;
       } // for (Int_t j=0;
       pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(ipix);
-      if (probi1[ipix] > 1.e-6) pixPtr->SetCharge(pixPtr->Charge()*sum/probi1[ipix]);
+      if (probi1[ipix] > 1.e-6) chargeNew[ipix] = pixPtr->Charge() * sum / probi1[ipix];
+      else chargeNew[ipix] = 0.;
     } // for (Int_t ipix=0;
+    for (Int_t i = 0; i < nPix; ++i) {
+      pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(i);
+      pixPtr->SetCharge(chargeNew[i]);
+    }
   } // for (Int_t iter=0;
   delete [] probi1;
+  delete [] chargeNew;
   return;
 }
 
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::FindCOG(TH2D *mlem, Double_t *xyc)
 {
-  // Calculate position of the center-of-gravity around the maximum pixel
+/// Calculate position of the center-of-gravity around the maximum pixel
 
   Int_t ixmax, iymax, ix, nsumx=0, nsumy=0, nsum=0;
   Int_t i1 = -9, j1 = -9;
@@ -1163,10 +1338,8 @@ void AliMUONClusterFinderAZ::FindCOG(TH2D *mlem, Double_t *xyc)
   Double_t x, y, cont, xq=0, yq=0, qq=0;
 
   for (Int_t i=TMath::Max(1,iymax-1); i<=TMath::Min(ny,iymax+1); i++) {
-  //for (Int_t i=TMath::Max(1,iymax-9); i<=TMath::Min(ny,iymax+9); i++) {
     y = mlem->GetYaxis()->GetBinCenter(i);
     for (Int_t j=TMath::Max(1,ixmax-1); j<=TMath::Min(nx,ixmax+1); j++) {
-    //for (Int_t j=TMath::Max(1,ixmax-9); j<=TMath::Min(nx,ixmax+9); j++) {
       cont = mlem->GetCellContent(j,i);
       if (cont < thresh) continue;
       if (i != i1) {i1 = i; nsumy++;}
@@ -1237,8 +1410,8 @@ void AliMUONClusterFinderAZ::FindCOG(TH2D *mlem, Double_t *xyc)
 //_____________________________________________________________________________
 Int_t AliMUONClusterFinderAZ::FindNearest(AliMUONPixel *pixPtr0)
 {
-  // Find the pixel nearest to the given one
-  // (algorithm may be not very efficient)
+/// Find the pixel nearest to the given one
+/// (algorithm may be not very efficient)
 
   Int_t nPix = fPixArray->GetEntriesFast(), imin = 0;
   Double_t rmin = 99999, dx = 0, dy = 0, r = 0;
@@ -1259,9 +1432,9 @@ Int_t AliMUONClusterFinderAZ::FindNearest(AliMUONPixel *pixPtr0)
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::Split(TH2D *mlem, Double_t *coef)
 {
-  // The main steering function to work with clusters of pixels in anode
-  // plane (find clusters, decouple them from each other, merge them (if
-  // necessary), pick up coupled pads, call the fitting function)
+/// The main steering function to work with clusters of pixels in anode
+/// plane (find clusters, decouple them from each other, merge them (if
+/// necessary), pick up coupled pads, call the fitting function)
   
   Int_t nx = mlem->GetNbinsX();
   Int_t ny = mlem->GetNbinsY();
@@ -1321,12 +1494,10 @@ void AliMUONClusterFinderAZ::Split(TH2D *mlem, Double_t *coef)
       yhig[cath] = fXyq[1][j]; 
     }
   }
-  //if (lun1) fprintf(lun1," %4d %2d %3d %3d %3d %3d \n",gAlice->GetHeader()->GetEvent(),AliMUONClusterInput::Instance()->Chamber(), npadx[0], npadx[1], npady[0], npady[1]);
 
   // Exclude pads with overflows
   for (Int_t j=0; j<npad; j++) {
-    //AZ if (fXyq[2][j] > fResponse->MaxAdc()-1) fPadIJ[1][j] = -5;
-    if (fXyq[2][j] > fResponse->Saturation()-1) fPadIJ[1][j] = -5;
+    if (fXyq[2][j] > fgkSaturation-1) fPadIJ[1][j] = -5;
     else fPadIJ[1][j] = 0;
   }
 
@@ -1424,7 +1595,7 @@ void AliMUONClusterFinderAZ::Split(TH2D *mlem, Double_t *coef)
        Merge(nForFit, nCoupled, clustNumb, clustFit, clusters, aijcluclu, aijclupad);
       } else {
        // Do the fit
-       nfit = Fit(nForFit, clustFit, clusters, parOk);
+       nfit = Fit(0, nForFit, clustFit, clusters, parOk);
       }
 
       // Subtract the fitted charges from pads with strong coupling and/or
@@ -1485,7 +1656,6 @@ void AliMUONClusterFinderAZ::Split(TH2D *mlem, Double_t *coef)
     } // while (nCoupled > 0)
   } // for (Int_t igroup=0; igroup<nclust;
 
-  //delete aij_clu; aij_clu = 0; delete aijclupad; aijclupad = 0;
   aijcluclu->Delete(); aijclupad->Delete();
   for (Int_t iclust=0; iclust<nclust; iclust++) {
     pix = clusters[iclust]; 
@@ -1498,7 +1668,7 @@ void AliMUONClusterFinderAZ::Split(TH2D *mlem, Double_t *coef)
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::AddBin(TH2D *mlem, Int_t ic, Int_t jc, Int_t mode, Bool_t *used, TObjArray *pix)
 {
-  // Add a bin to the cluster
+/// Add a bin to the cluster
 
   Int_t nx = mlem->GetNbinsX();
   Int_t ny = mlem->GetNbinsY();
@@ -1527,13 +1697,13 @@ void AliMUONClusterFinderAZ::AddBin(TH2D *mlem, Int_t ic, Int_t jc, Int_t mode,
 //_____________________________________________________________________________
 TObject* AliMUONClusterFinderAZ::BinToPix(TH2D *mlem, Int_t jc, Int_t ic)
 {
-  // Translate histogram bin to pixel 
+/// Translate histogram bin to pixel 
   
   Double_t yc = mlem->GetYaxis()->GetBinCenter(ic);
   Double_t xc = mlem->GetXaxis()->GetBinCenter(jc);
   
   Int_t nPix = fPixArray->GetEntriesFast();
-  AliMUONPixel *pixPtr;
+  AliMUONPixel *pixPtr = NULL;
 
   // Compare pixel and bin positions
   for (Int_t i=0; i<nPix; i++) {
@@ -1541,14 +1711,14 @@ TObject* AliMUONClusterFinderAZ::BinToPix(TH2D *mlem, Int_t jc, Int_t ic)
     if (pixPtr->Charge() < 0.5) continue;
     if (TMath::Abs(pixPtr->Coord(0)-xc)<1.e-4 && TMath::Abs(pixPtr->Coord(1)-yc)<1.e-4) return (TObject*) pixPtr;
   }
-  AliWarning(Form(" Something wrong ??? %f %f ", xc, yc));
+  AliError(Form(" Something wrong ??? %f %f ", xc, yc));
   return NULL;
 }
 
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::AddCluster(Int_t ic, Int_t nclust, TMatrixD *aijcluclu, Bool_t *used, Int_t *clustNumb, Int_t &nCoupled)
 {
-  // Add a cluster to the group of coupled clusters
+/// Add a cluster to the group of coupled clusters
 
   for (Int_t i=0; i<nclust; i++) {
     if (used[i]) continue;
@@ -1562,7 +1732,7 @@ void AliMUONClusterFinderAZ::AddCluster(Int_t ic, Int_t nclust, TMatrixD *aijclu
 //_____________________________________________________________________________
 Double_t AliMUONClusterFinderAZ::MinGroupCoupl(Int_t nCoupled, Int_t *clustNumb, TMatrixD *aijcluclu, Int_t *minGroup)
 {
-  // Find group of clusters with minimum coupling to all the others
+/// Find group of clusters with minimum coupling to all the others
 
   Int_t i123max = TMath::Min(3,nCoupled/2); 
   Int_t indx, indx1, indx2, indx3, nTot = 0;
@@ -1644,8 +1814,8 @@ Double_t AliMUONClusterFinderAZ::MinGroupCoupl(Int_t nCoupled, Int_t *clustNumb,
 //_____________________________________________________________________________
 Int_t AliMUONClusterFinderAZ::SelectPad(Int_t nCoupled, Int_t nForFit, Int_t *clustNumb, Int_t *clustFit, TMatrixD *aijclupad)
 {
-  // Select pads for fit. If too many coupled clusters, find pads giving 
-  // the strongest coupling with the rest of clusters and exclude them from the fit.
+/// Select pads for fit. If too many coupled clusters, find pads giving 
+/// the strongest coupling with the rest of clusters and exclude them from the fit.
 
   Int_t npad = fnPads[0] + fnPads[1];
   Double_t *padpix = 0;
@@ -1691,7 +1861,7 @@ Int_t AliMUONClusterFinderAZ::SelectPad(Int_t nCoupled, Int_t nForFit, Int_t *cl
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::Merge(Int_t nForFit, Int_t nCoupled, Int_t *clustNumb, Int_t *clustFit, TObjArray **clusters, TMatrixD *aijcluclu, TMatrixD *aijclupad)
 {
-  // Merge the group of clusters with the one having the strongest coupling with them
+/// Merge the group of clusters with the one having the strongest coupling with them
 
   Int_t indx, indx1, npxclu, npxclu1, imax=0;
   TObjArray *pix, *pix1;
@@ -1742,34 +1912,32 @@ void AliMUONClusterFinderAZ::Merge(Int_t nForFit, Int_t nCoupled, Int_t *clustNu
 }
 
 //_____________________________________________________________________________
-Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clusters, Double_t *parOk)
+Int_t AliMUONClusterFinderAZ::Fit(Int_t iSimple, Int_t nfit, Int_t *clustFit, TObjArray **clusters, Double_t *parOk)
 {
-  // Find selected clusters to selected pad charges
+/// Find selected clusters to selected pad charges
   
   TH2D *mlem = (TH2D*) gROOT->FindObject("mlem");
-  //Int_t nx = mlem->GetNbinsX();
-  //Int_t ny = mlem->GetNbinsY();
   Double_t xmin = mlem->GetXaxis()->GetXmin() - mlem->GetXaxis()->GetBinWidth(1);
   Double_t xmax = mlem->GetXaxis()->GetXmax() + mlem->GetXaxis()->GetBinWidth(1);
   Double_t ymin = mlem->GetYaxis()->GetXmin() - mlem->GetYaxis()->GetBinWidth(1);
   Double_t ymax = mlem->GetYaxis()->GetXmax() + mlem->GetYaxis()->GetBinWidth(1);
-  //Double_t qmin = 0, qmax = 1;
   Double_t step[3]={0.01,0.002,0.02}, xPad = 0, yPad = 99999;
-  Double_t qPad[2] = {0}, xyqPad[2] = {0};
 
   // Number of pads to use and number of virtual pads
-  Int_t npads = 0, nVirtual = 0;
+  Int_t npads = 0, nVirtual = 0, nfit0 = nfit;
   for (Int_t i=0; i<fnPads[0]+fnPads[1]; i++) {
-    if (fPadIJ[1][i] == -9 || fPadIJ[1][i] == 1) {
-      if (fPadIJ[0][i]) xyqPad[1] += fXyq[0][i] * fXyq[2][i];
-      else xyqPad[0] += fXyq[1][i] * fXyq[2][i];
-      qPad[fPadIJ[0][i]] += fXyq[2][i];
-    }
     if (fXyq[3][i] < 0) nVirtual++;
     if (fPadIJ[1][i] != 1) continue;
-    if (fXyq[3][i] > 0) npads++;
-    if (yPad > 9999) { xPad = fXyq[0][i]; yPad = fXyq[1][i]; }
-    //if (fPadIJ[0][i]) xPad = fXyq[0][i];
+    if (fXyq[3][i] > 0) {
+      npads++;
+      if (yPad > 9999) { 
+       xPad = fXyq[0][i]; 
+       yPad = fXyq[1][i]; 
+      } else {
+       if (fXyq[4][i] < fXyq[3][i]) yPad = fXyq[1][i]; 
+       else xPad = fXyq[0][i]; 
+      }
+    }
   }
   if (fDebug) {
     for (Int_t i=0; i<nfit; i++) {cout << i+1 << " " << clustFit[i] << " ";}
@@ -1779,33 +1947,29 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
   fNpar = 0;
   fQtot = 0;
   if (npads < 2) return 0; 
-
-  Int_t digit = 0, nfit0 = nfit;
-  AliMUONDigit *mdig = 0;
+  
+  AliMUONVDigit *mdig = 0;
   Int_t tracks[3] = {-1, -1, -1};
   for (Int_t cath=0; cath<2; cath++) {  
     for (Int_t i=0; i<fnPads[0]+fnPads[1]; i++) {
       if (fPadIJ[0][i] != cath) continue;
       if (fPadIJ[1][i] != 1) continue;
       if (fXyq[3][i] < 0) continue; // exclude virtual pads
-      digit = TMath::Nint (fXyq[5][i]);
-      if (digit >= 0) mdig = fInput->Digit(cath,digit);
-      else mdig = fInput->Digit(TMath::Even(cath),-digit-1);
-      //if (!mdig) mdig = fInput->Digit(TMath::Even(cath),digit);
+      UInt_t digit = fDigitId[i];
+      mdig = static_cast<AliMUONVDigit*>(fDigitStore->FindObject(digit));
       if (!mdig) continue; // protection for cluster display
       if (mdig->Hit() >= 0) {
-       if (tracks[0] < 0) {
-         tracks[0] = mdig->Hit();
-         tracks[1] = mdig->Track(0);
-       } else if (mdig->Track(0) < tracks[1]) {
-         tracks[0] = mdig->Hit();
-         tracks[1] = mdig->Track(0);
-       }
+        if (tracks[0] < 0) {
+          tracks[0] = mdig->Hit();
+          tracks[1] = mdig->Track(0);
+        } else if (mdig->Track(0) < tracks[1]) {
+          tracks[0] = mdig->Hit();
+          tracks[1] = mdig->Track(0);
+        }
       }
-      //AZif (mdig->Track(1)) {
       if (mdig->Track(1) >= 0 && mdig->Track(1) != tracks[1]) {
-       if (tracks[2] < 0) tracks[2] = mdig->Track(1);
-       else tracks[2] = TMath::Min (tracks[2], mdig->Track(1));
+        if (tracks[2] < 0) tracks[2] = mdig->Track(1);
+        else tracks[2] = TMath::Min (tracks[2], mdig->Track(1));
       }
       //if (!mdig) break;
       //cout << mdig->Hit() << " " << mdig->Track(0) << " " << mdig->Track(1) <<endl;
@@ -1818,6 +1982,13 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
   PadsInXandY(nInX, nInY);
   //cout << " nInX and Y: " << nInX << " " << nInY << endl;
 
+  Int_t nfitMax = 3; 
+  nfitMax = TMath::Min (nfitMax, (npads + 1) / 3);
+  if (nfitMax > 1) {
+    if (nInX < 3 && nInY < 3 || nInX == 3 && nInY < 3 || nInX < 3 && nInY == 3) nfitMax = 1; // not enough pads in each direction
+  }
+  if (nfit > nfitMax) nfit = nfitMax;
+
   // Take cluster maxima as fitting seeds
   TObjArray *pix;
   AliMUONPixel *pixPtr;
@@ -1825,7 +1996,7 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
   Double_t cont, cmax = 0, xseed = 0, yseed = 0, errOk[8], qq = 0;
   Double_t xyseed[3][2], qseed[3], xyCand[3][2] = {{0},{0}}, sigCand[3][2] = {{0},{0}};
 
-  for (Int_t ifit=1; ifit<=nfit; ifit++) {
+  for (Int_t ifit=1; ifit<=nfit0; ifit++) {
     cmax = 0;
     pix = clusters[clustFit[ifit-1]];
     npxclu = pix->GetEntriesFast();
@@ -1873,36 +2044,63 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
   sigCand[0][1] = sigCand[0][1] > 0 ? TMath::Sqrt (sigCand[0][1]) : 0;
   if (fDebug) cout << xyCand[0][0] << " " << xyCand[0][1] << " " << sigCand[0][0] << " " << sigCand[0][1] << endl;
 
-  Int_t nDof, maxSeed[3];
+  Int_t nDof, maxSeed[3], nMax = 0;
   Double_t fmin, chi2o = 9999, chi2n;
 
-  // Try to fit with one-track hypothesis, then 2-track. If chi2/dof is 
-  // lower, try 3-track (if number of pads is sufficient).
-  
-  TMath::Sort(nfit, qseed, maxSeed, kTRUE); // in decreasing order
-  nfit = TMath::Min (nfit, (npads + 1) / 3);
-  if (nfit > 1) {
-    if (nInX < 3 && nInY < 3 || nInX == 3 && nInY < 3 || nInX < 3 && nInY == 3) nfit = 1; // not enough pads in each direction
-  }
-  //if (nfit > 1) nfit --;
-  // One pad per direction 
-  //if (nInX == 1) { step[0] /= 1; xyseed[0][0] = xPad; }
-  //if (nInY == 1) { step[1] /= 1; xyseed[0][1] = yPad; }
+  TMath::Sort(nfit0, qseed, maxSeed, kTRUE); // in decreasing order
+  /*
+  Int_t itmp[100], localMax[100];
+  Double_t maxVal[100];
+  if (!iSimple && nfit < nfitMax) {
+    // Try to split pixel cluster according to local maxima
+    Int_t nfit1 = nfit;
+    for (Int_t iclus = 0; iclus < nfit1; iclus++) {
+      nMax = FindLocalMaxima (clusters[clustFit[maxSeed[iclus]]], localMax, maxVal);
+      TH2D *hist = (TH2D*) gROOT->FindObject("anode1");
+      if (nMax == 1) { hist->Delete(); continue; }
+      // Add extra fitting seeds from local maxima
+      Int_t ixseed = hist->GetXaxis()->FindBin(xyseed[maxSeed[iclus]][0]);
+      Int_t iyseed = hist->GetYaxis()->FindBin(xyseed[maxSeed[iclus]][1]);
+      Int_t nx = hist->GetNbinsX();
+      TMath::Sort(nMax, maxVal, itmp, kTRUE); // in decreasing order
+      for (Int_t j = 0; j < nMax; j++) {
+       Int_t iyc = localMax[itmp[j]] / nx + 1;
+       Int_t ixc = localMax[itmp[j]] % nx + 1;
+       if (ixc == ixseed && iyc == iyseed) continue; // local max already taken for seeding
+       xyseed[nfit][0] = hist->GetXaxis()->GetBinCenter(ixc);
+       xyseed[nfit][1] = hist->GetYaxis()->GetBinCenter(iyc);
+       qseed[nfit] = maxVal[itmp[j]];
+       maxSeed[nfit] = nfit++;
+       if (nfit >= nfitMax) break;
+      }
+      hist->Delete();
+      if (nfit >= nfitMax) break;
+    } // for (Int_t iclus = 0;
+    //nfit0 = nfit;
+    //TMath::Sort(nfit0, qseed, maxSeed, kTRUE); // in decreasing order
+  } //if (!iSimple && nfit < nfitMax)
+  */
 
-  Double_t *gin = 0, func0, func1, param[8], param0[2][8], deriv[2][8], step0[8];
+  Double_t *gin = 0, func0, func1, param[8], step0[8];
+  Double_t param0[2][8]={{0},{0}}, deriv[2][8]={{0},{0}}; 
   Double_t shift[8], stepMax, derMax, parmin[8], parmax[8], func2[2], shift0;
   Double_t delta[8], scMax, dder[8], estim, shiftSave = 0;
-  Int_t min, max, nCall = 0, memory[8] = {0}, nLoop, idMax = 0, iestMax = 0, nFail;
+  Int_t min, max, nCall = 0, nLoop, idMax = 0, iestMax = 0, nFail;
   Double_t rad, dist[3] = {0};
 
+  // Try to fit with one-track hypothesis, then 2-track. If chi2/dof is 
+  // lower, try 3-track (if number of pads is sufficient).
   for (Int_t iseed=0; iseed<nfit; iseed++) {
 
+    Int_t memory[8] = {0};
     if (iseed) { for (Int_t j=0; j<fNpar; j++) param[j] = parOk[j]; } // for bounded params
     for (Int_t j=0; j<3; j++) step0[fNpar+j] = shift[fNpar+j] = step[j];
-    param[fNpar] = xyseed[maxSeed[iseed]][0];
+    if (nfit == 1) param[fNpar] = xyCand[0][0]; // take COG
+    else param[fNpar] = xyseed[maxSeed[iseed]][0];
     parmin[fNpar] = xmin; 
     parmax[fNpar++] = xmax; 
-    param[fNpar] = xyseed[maxSeed[iseed]][1];
+    if (nfit == 1) param[fNpar] = xyCand[0][1]; // take COG
+    else param[fNpar] = xyseed[maxSeed[iseed]][1];
     parmin[fNpar] = ymin; 
     parmax[fNpar++] = ymax; 
     if (fNpar > 2) {
@@ -1930,7 +2128,7 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
        deriv[max][j] = (func1 - func0) / delta[j] * 10; // first derivative
        //cout << j << " " << deriv[max][j] << endl;
        dder[j] = param0[0][j] != param0[1][j] ? (deriv[0][j] - deriv[1][j]) / 
-                                                (param0[0][j] - param0[1][j]) : 0; // second derivative
+         (param0[0][j] - param0[1][j]) : 0; // second derivative
       }
       param[fNpar-1] -= delta[fNpar-1] / 10;
       if (nCall > 2000) break;
@@ -2033,14 +2231,12 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
 
     // Save parameters and errors
 
-    if (nInX == 1 && qPad[1] > 1) {
+    if (nInX == 1) {
       // One pad per direction 
-      xPad = xyqPad[1] / qPad[1]; // take COG for this case
       for (Int_t i=0; i<fNpar; i++) if (i == 0 || i == 2 || i == 5) param0[min][i] = xPad;
     }
-    if (nInY == 1 && qPad[0] > 1) {
+    if (nInY == 1) {
       // One pad per direction 
-      yPad = xyqPad[0] / qPad[0]; // take COG for this case
       for (Int_t i=0; i<fNpar; i++) if (i == 1 || i == 3 || i == 6) param0[min][i] = yPad;
     }
 
@@ -2071,7 +2267,8 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
 
     for (Int_t i=0; i<fNpar; i++) {
       parOk[i] = param0[min][i];
-      errOk[i] = fmin;
+      //errOk[i] = fmin;
+      errOk[i] = chi2n;
       // Bounded params
       parOk[i] = TMath::Max (parOk[i], parmin[i]);
       parOk[i] = TMath::Min (parOk[i], parmax[i]);
@@ -2083,7 +2280,6 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
 
   if (fDebug) {
     for (Int_t i=0; i<fNpar; i++) {
-      //if (i == 4 || i == 7) continue;
       if (i == 4 || i == 7) {
        if (i == 7 || i == 4 && fNpar < 7) cout << parOk[i] << endl;
        else cout << parOk[i] * (1-parOk[7]) << endl;
@@ -2118,8 +2314,9 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
 
   Int_t indx;
   fnPads[1] -= nVirtual;
-  if (!fDraw) {
+//  if (!fDraw) {
     Double_t coef = 0;
+    if (iSimple) fnCoupled = 0;
     //for (Int_t j=0; j<nfit; j++) {
     for (Int_t j=nfit-1; j>=0; j--) {
       indx = j<2 ? j*2 : j*2+1;  
@@ -2128,20 +2325,21 @@ Int_t AliMUONClusterFinderAZ::Fit(Int_t nfit, Int_t *clustFit, TObjArray **clust
       coef = TMath::Max (coef, 0.);
       if (nfit == 3 && j < 2) coef = j==1 ? coef*parOk[indx+2] : coef - parOk[7];
       coef = TMath::Max (coef, 0.);
-      AddRawCluster (parOk[indx], parOk[indx+1], coef*fQtot, errOk[indx], nfit0+10*nfit, tracks,
+      AddRawCluster (parOk[indx], parOk[indx+1], coef*fQtot, errOk[indx], nfit0+10*nfit+100*nMax+10000*fnCoupled, tracks,
                     //sigCand[maxSeed[j]][0], sigCand[maxSeed[j]][1]);
                     //sigCand[0][0], sigCand[0][1], dist[j]);
                     sigCand[0][0], sigCand[0][1], dist[TMath::LocMin(nfit,dist)]);
     }
-  } else fDraw->FillMuon(nfit, parOk, errOk);
+//  } else fDraw->FillMuon(nfit, parOk, errOk);
   return nfit;
 }  
 
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::Fcn1(Int_t & /*npar*/, Double_t * /*gin*/, Double_t &f, Double_t *par, Int_t /*iflag*/)
 {
-  // Fit for one track
-  //AZ for Muinuit AliMUONClusterFinderAZ& c = *(AliMUONClusterFinderAZ::fgClusterFinder);    
+/// Fit for one track
+/// AZ for Muinuit AliMUONClusterFinderAZ& c = *(AliMUONClusterFinderAZ::fgClusterFinder);    
+
   AliMUONClusterFinderAZ& c = *this; //AZ
   
   Int_t cath, ix, iy, indx, npads=0;
@@ -2151,23 +2349,24 @@ void AliMUONClusterFinderAZ::Fcn1(Int_t & /*npar*/, Double_t * /*gin*/, Double_t
     cath = c.fPadIJ[0][j];
     if (c.fXyq[3][j] > 0) npads++; // exclude virtual pads
     qTot += c.fXyq[2][j];
-    c.fSegmentation[cath]->GetPadI(fInput->DetElemId(),c.fXyq[0][j],c.fXyq[1][j],c.fZpad,ix,iy);
-    c.fSegmentation[cath]->SetPad(fInput->DetElemId(),ix,iy);
+    ix = c.fPadIJ[2][j];
+    iy = c.fPadIJ[3][j];
+//    c.fSegmentation[cath]->SetPad(ix, iy);
     charge = 0;
     for (Int_t i=c.fNpar/3; i>=0; i--) { // sum over tracks
       indx = i<2 ? 2*i : 2*i+1;
-      c.fSegmentation[cath]->SetHit(fInput->DetElemId(),par[indx],par[indx+1],c.fZpad);
-      //charge += c.fResponse->IntXY(fInput->DetElemId(),c.fSegmentation[cath])*par[icl*3+2];
+//      c.fSegmentation[cath]->SetHit(par[indx], par[indx+1], c.fZpad);
       if (c.fNpar == 2) coef = 1;
       else coef = i==c.fNpar/3 ? par[indx+2] : 1-coef;
       coef = TMath::Max (coef, 0.);
       if (c.fNpar == 8 && i < 2) coef = i==1 ? coef*par[indx+2] : coef - par[7];
       coef = TMath::Max (coef, 0.);
-      charge += c.fResponse->IntXY(fInput->DetElemId(),c.fSegmentation[cath])*coef;
+//      charge += fMathieson->IntXY(fDetElemId, fSegmentation[cath])*coef;
+      charge += ChargeIntegration(par[indx],par[indx+1],
+                                  c.fXyq[0][j],c.fXyq[1][j],
+                                  TMath::Abs(c.fXyq[3][j]),c.fXyq[4][j]) * coef;
     }
     charge *= c.fQtot;
-    //if (c.fXyq[2][j] > c.fResponse->MaxAdc()-1 && charge > 
-    // c.fResponse->MaxAdc()) charge = c.fResponse->MaxAdc(); 
     delta = charge - c.fXyq[2][j];
     delta *= delta;
     delta /= c.fXyq[2][j];
@@ -2182,7 +2381,7 @@ void AliMUONClusterFinderAZ::Fcn1(Int_t & /*npar*/, Double_t * /*gin*/, Double_t
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::UpdatePads(Int_t /*nfit*/, Double_t *par)
 {
-  // Subtract the fitted charges from pads with strong coupling
+/// Subtract the fitted charges from pads with strong coupling
 
   Int_t cath, ix, iy, indx;
   Double_t charge, coef=0;
@@ -2190,29 +2389,35 @@ void AliMUONClusterFinderAZ::UpdatePads(Int_t /*nfit*/, Double_t *par)
     if (fPadIJ[1][j] != -1) continue;
     if (fNpar != 0) {
       cath = fPadIJ[0][j];
-      fSegmentation[cath]->GetPadI(fInput->DetElemId(),fXyq[0][j],fXyq[1][j],fZpad,ix,iy);
-      fSegmentation[cath]->SetPad(fInput->DetElemId(),ix,iy);
+      ix = fPadIJ[2][j];
+      iy = fPadIJ[3][j];
+      //      fSegmentation[cath]->SetPad(ix, iy);
       charge = 0;
       for (Int_t i=fNpar/3; i>=0; i--) { // sum over tracks
-       indx = i<2 ? 2*i : 2*i+1;
-       fSegmentation[cath]->SetHit(fInput->DetElemId(),par[indx],par[indx+1],fZpad);
-       if (fNpar == 2) coef = 1;
-       else coef = i==fNpar/3 ? par[indx+2] : 1-coef;
-       coef = TMath::Max (coef, 0.);
-       if (fNpar == 8 && i < 2) coef = i==1 ? coef*par[indx+2] : coef - par[7];
-       coef = TMath::Max (coef, 0.);
-       charge += fResponse->IntXY(fInput->DetElemId(),fSegmentation[cath])*coef;
+        indx = i<2 ? 2*i : 2*i+1;
+//        fSegmentation[cath]->SetHit(par[indx], par[indx+1], fZpad);
+        if (fNpar == 2) coef = 1;
+        else coef = i==fNpar/3 ? par[indx+2] : 1-coef;
+        coef = TMath::Max (coef, 0.);
+        if (fNpar == 8 && i < 2) coef = i==1 ? coef*par[indx+2] : coef - par[7];
+        coef = TMath::Max (coef, 0.);
+//        charge += fMathieson->IntXY(fDetElemId,fSegmentation[cath])*coef;
+        charge += ChargeIntegration(par[indx],par[indx+1],
+                                    fXyq[0][j],fXyq[1][j],
+                                    TMath::Abs(fXyq[3][j]),fXyq[4][j]) * coef;
       }
       charge *= fQtot;
       fXyq[2][j] -= charge;
     } // if (fNpar != 0)
-    if (fXyq[2][j] > fResponse->ZeroSuppression()) fPadIJ[1][j] = 0; // return pad for further using
+    if (fXyq[2][j] > fgkZeroSuppression) fPadIJ[1][j] = 0; // return pad for further using
   } // for (Int_t j=0;
 }  
 
 //_____________________________________________________________________________
-Bool_t AliMUONClusterFinderAZ::TestTrack(Int_t /*t*/) const {
-// Test if track was user selected
+Bool_t AliMUONClusterFinderAZ::TestTrack(Int_t /*t*/) const 
+{
+/// Test if track was user selected
+
   return kTRUE;
   /*
     if (fTrack[0]==-1 || fTrack[1]==-1) {
@@ -2226,70 +2431,81 @@ Bool_t AliMUONClusterFinderAZ::TestTrack(Int_t /*t*/) const {
 }
 
 //_____________________________________________________________________________
-void AliMUONClusterFinderAZ::AddRawCluster(Double_t x, Double_t y, Double_t qTot, Double_t fmin, Int_t nfit, Int_t *tracks, Double_t /*sigx*/, Double_t /*sigy*/, Double_t /*dist*/)
+void AliMUONClusterFinderAZ::AddRawCluster(Double_t x, Double_t y, 
+                                           Double_t qTot, 
+                                           Double_t /*fmin*/, Int_t /*nfit*/, 
+                                           Int_t* /*tracks*/, 
+                                           Double_t /*sigx*/, Double_t /*sigy*/, 
+                                           Double_t /*dist*/)
 {
-  //
-  // Add a raw cluster copy to the list
-  //
-  if (qTot <= 0.501) return; 
-  AliMUONRawCluster cnew;
-  AliMUON *pMUON=(AliMUON*)gAlice->GetModule("MUON");
-  pMUON=0; //AZ
-  //pMUON->AddRawCluster(fInput->Chamber(),c); 
-
-  Int_t cath, npads[2] = {0}, nover[2] = {0};
-  for (Int_t j=0; j<fnPads[0]+fnPads[1]; j++) {
-    cath = fPadIJ[0][j];
-    // There was an overflow
-    if (fPadIJ[1][j] == -9) nover[cath]++;
-    if (fPadIJ[1][j] != 1 && fPadIJ[1][j] != -9) continue;
-    cnew.SetMultiplicity(cath,cnew.GetMultiplicity(cath)+1);
-    if (fXyq[2][j] > cnew.GetPeakSignal(cath)) cnew.SetPeakSignal(cath,TMath::Nint (fXyq[2][j]));
-    //cnew.SetCharge(cath,cnew.GetCharge(cath) + TMath::Nint (fXyq[2][j]));
-    cnew.SetContrib(npads[cath],cath,fXyq[2][j]);
-    cnew.SetIndex(npads[cath],cath,TMath::Nint (fXyq[5][j]));
-    cnew.SetDetElemId(fInput->DetElemId());
-    npads[cath]++;
-  }
+/// Add a raw cluster copy to the list
 
-  cnew.SetClusterType(nover[0] + nover[1] * 100);
-  for (Int_t j=0; j<3; j++) cnew.SetTrack(j,tracks[j]);
+  if (qTot <= 0.501) return; 
 
-  for (cath=0; cath<2; cath++) {
-    cnew.SetX(cath, x);
-    cnew.SetY(cath, y);
-    cnew.SetZ(cath, fZpad);
-    cnew.SetCharge(cath, TMath::Nint(qTot));
-    //cnew.SetPeakSignal(cath,20);
-    //cnew.SetMultiplicity(cath, 5);
-    cnew.SetNcluster(cath, nfit);
-    cnew.SetChi2(cath, fmin); //0.;1
-  } 
+//  Int_t cath, npads[2] = {0}, nover[2] = {0};
+//  for (Int_t j=0; j<fnPads[0]+fnPads[1]; j++)
+//  {
+//    cath = fPadIJ[0][j];
+//    // There was an overflow
+//    if (fPadIJ[1][j] == -9) nover[cath]++;
+//    if (fPadIJ[1][j] != 1 && fPadIJ[1][j] != -9) continue;
+//    cnew.SetMultiplicity(cath,cnew.GetMultiplicity(cath)+1);
+//    if (fXyq[2][j] > cnew.GetPeakSignal(cath)) cnew.SetPeakSignal(cath,fXyq[2][j]);
+//    //cnew.SetCharge(cath,cnew.GetCharge(cath) + TMath::Nint (fXyq[2][j]));
+//    cnew.SetContrib(npads[cath],cath,fXyq[2][j]);
+//    cnew.SetIndex(npads[cath],cath,TMath::Nint (fXyq[5][j]));
+//    cnew.SetDetElemId(fDetElemId);
+//    npads[cath]++;
+//  }
+
+//  cnew.SetClusterType(nover[0] + nover[1] * 100);
+//  for (Int_t j=0; j<3; j++) cnew.SetTrack(j,tracks[j]);
+
+//  Double_t xg, yg, zg;
+//  for (cath=0; cath<2; cath++) 
+//  {
+//    // Perform local-to-global transformation
+//    cnew.SetX(cath, xg);
+//    cnew.SetY(cath, yg);
+//    cnew.SetZ(cath, zg);
+//    cnew.SetCharge(cath, TMath::Nint(qTot));
+//    //cnew.SetPeakSignal(cath,20);
+//    //cnew.SetMultiplicity(cath, 5);
+//    cnew.SetNcluster(cath, nfit);
+//    cnew.SetChi2(cath, fmin); //0.;1
+//  } 
   // Evaluate measurement errors
   //AZ Errors(&cnew);
+  
+  AliMUONCluster cnew;
+  
+  cnew.SetCharge(qTot,qTot);
+  cnew.SetPosition(TVector2(x,y),TVector2(0.0,0.0));
 
-  cnew.SetGhost(nfit); //cnew.SetX(1,sigx); cnew.SetY(1,sigy); cnew.SetZ(1,dist);
+//  cnew.SetGhost(nfit); //cnew.SetX(1,sigx); cnew.SetY(1,sigy); cnew.SetZ(1,dist);
   //cnew.fClusterType=cnew.PhysicsContribution();
-  //AZ pMUON->GetMUONData()->AddRawCluster(AliMUONClusterInput::Instance()->Chamber(),cnew); 
-  new((*fRawClusters)[fNRawClusters++]) AliMUONRawCluster(cnew); //AZ
-  if (fDebug) cout << fNRawClusters << " " << AliMUONClusterInput::Instance()->Chamber() << endl;
+  new((*fRawClusters)[fRawClusters->GetLast()+1]) AliMUONCluster(cnew); 
+//  if (fDebug) cout << fNRawClusters << " " << fChamberId << endl;
   //fNPeaks++;
 }
 
 //_____________________________________________________________________________
-Int_t AliMUONClusterFinderAZ::FindLocalMaxima(Int_t *localMax, Double_t *maxVal)
+Int_t AliMUONClusterFinderAZ::FindLocalMaxima(TObjArray *pixArray, Int_t *localMax, Double_t *maxVal)
 {
-  // Find local maxima in pixel space for large preclusters in order to
-  // try to split them into smaller pieces (to speed up the MLEM procedure)
+/// Find local maxima in pixel space for large preclusters in order to
+/// try to split them into smaller pieces (to speed up the MLEM procedure)
+/// or to find additional fitting seeds if clusters were not completely resolved  
 
-  TH2D *hist = (TH2D*) gROOT->FindObject("anode");
-  if (hist) hist->Delete();
+  TH2D *hist = NULL;
+  //if (pixArray == fPixArray) hist = (TH2D*) gROOT->FindObject("anode");
+  //else { hist = (TH2D*) gROOT->FindObject("anode1"); cout << hist << endl; }
+  //if (hist) hist->Delete();
 
   Double_t xylim[4] = {999, 999, 999, 999};
-  Int_t nPix = fPixArray->GetEntriesFast();
+  Int_t nPix = pixArray->GetEntriesFast();
   AliMUONPixel *pixPtr = 0;
   for (Int_t ipix=0; ipix<nPix; ipix++) {
-    pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(ipix);
+    pixPtr = (AliMUONPixel*) pixArray->UncheckedAt(ipix);
     for (Int_t i=0; i<4; i++) 
          xylim[i] = TMath::Min (xylim[i], (i%2 ? -1 : 1)*pixPtr->Coord(i/2));
   }
@@ -2297,12 +2513,13 @@ Int_t AliMUONClusterFinderAZ::FindLocalMaxima(Int_t *localMax, Double_t *maxVal)
 
   Int_t nx = TMath::Nint ((-xylim[1]-xylim[0])/pixPtr->Size(0)/2);
   Int_t ny = TMath::Nint ((-xylim[3]-xylim[2])/pixPtr->Size(1)/2);
-  hist = new TH2D("anode","anode",nx,xylim[0],-xylim[1],ny,xylim[2],-xylim[3]);
+  if (pixArray == fPixArray) hist = new TH2D("anode","anode",nx,xylim[0],-xylim[1],ny,xylim[2],-xylim[3]);
+  else hist = new TH2D("anode1","anode1",nx,xylim[0],-xylim[1],ny,xylim[2],-xylim[3]);
   for (Int_t ipix=0; ipix<nPix; ipix++) {
-    pixPtr = (AliMUONPixel*) fPixArray->UncheckedAt(ipix);
+    pixPtr = (AliMUONPixel*) pixArray->UncheckedAt(ipix);
     hist->Fill(pixPtr->Coord(0), pixPtr->Coord(1), pixPtr->Charge());
   }
-  if (fDraw) fDraw->DrawHist("c2", hist);
+//  if (fDraw && pixArray == fPixArray) fDraw->DrawHist("c2", hist);
 
   Int_t nMax = 0, indx;
   Int_t *isLocalMax = new Int_t[ny*nx];
@@ -2336,39 +2553,41 @@ Int_t AliMUONClusterFinderAZ::FindLocalMaxima(Int_t *localMax, Double_t *maxVal)
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::FlagLocalMax(TH2D *hist, Int_t i, Int_t j, Int_t *isLocalMax)
 {
-  // Flag pixels (whether or not local maxima)
+/// Flag pixels (whether or not local maxima)
 
   Int_t nx = hist->GetNbinsX();
   Int_t ny = hist->GetNbinsY();
   Int_t cont = TMath::Nint (hist->GetCellContent(j,i));
-  Int_t cont1 = 0;
+  Int_t cont1 = 0, indx = (i-1)*nx+j-1, indx1 = 0, indx2 = 0;
 
   for (Int_t i1=i-1; i1<i+2; i1++) {
     if (i1 < 1 || i1 > ny) continue;
+    indx1 = (i1 - 1) * nx;
     for (Int_t j1=j-1; j1<j+2; j1++) {
       if (j1 < 1 || j1 > nx) continue;
       if (i == i1 && j == j1) continue;
+      indx2 = indx1 + j1 - 1;
       cont1 = TMath::Nint (hist->GetCellContent(j1,i1));
-      if (cont < cont1) { isLocalMax[(i-1)*nx+j-1] = -1; return; }
-      else if (cont > cont1) isLocalMax[(i1-1)*nx+j1-1] = -1;
+      if (cont < cont1) { isLocalMax[indx] = -1; return; }
+      else if (cont > cont1) isLocalMax[indx2] = -1;
       else { // the same charge
-       isLocalMax[(i-1)*nx+j-1] = 1; 
-       if (isLocalMax[(i1-1)*nx+j1-1] == 0) {
+       isLocalMax[indx] = 1; 
+       if (isLocalMax[indx2] == 0) {
          FlagLocalMax(hist, i1, j1, isLocalMax);
-         if (isLocalMax[(i1-1)*nx+j1-1] < 0) { isLocalMax[(i-1)*nx+j-1] = -1; return; }
-         else isLocalMax[(i1-1)*nx+j1-1] = -1;
+         if (isLocalMax[indx2] < 0) { isLocalMax[indx] = -1; return; }
+         else isLocalMax[indx2] = -1;
        }
       } 
     }
   }
-  isLocalMax[(i-1)*nx+j-1] = 1; // local maximum
+  isLocalMax[indx] = 1; // local maximum
 }
 
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::FindCluster(Int_t *localMax, Int_t iMax)
 {
-  // Find pixel cluster around local maximum #iMax and pick up pads
-  // overlapping with it
+/// Find pixel cluster around local maximum \a iMax and pick up pads
+/// overlapping with it
 
   TH2D *hist = (TH2D*) gROOT->FindObject("anode");
   Int_t nx = hist->GetNbinsX();
@@ -2412,35 +2631,18 @@ void AliMUONClusterFinderAZ::FindCluster(Int_t *localMax, Int_t iMax)
   delete [] used; used = 0;
 }
 
-//_____________________________________________________________________________
-AliMUONClusterFinderAZ&  
-AliMUONClusterFinderAZ::operator=(const AliMUONClusterFinderAZ& rhs)
-{
-// Protected assignement operator
-
-  if (this == &rhs) return *this;
-
-  AliFatal("Not implemented.");
-    
-  return *this;  
-}    
-          
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::AddVirtualPad()
 {
-  // Add virtual pad (with small charge) to improve fit for some
-  // clusters (when pad with max charge is at the extreme of the cluster)
+/// Add virtual pad (with small charge) to improve fit for some
+/// clusters (when pad with max charge is at the extreme of the cluster)
 
   // Get number of pads in X and Y-directions
   Int_t nInX = -1, nInY;
   PadsInXandY(nInX, nInY);
   //return;
 
-  //nInY = npady[0];
-  //nInX = npadx[1] ? npadx[1] : npadx[0];
-  // Add virtual pads only if number of pads per direction == 2
-  //if (!npadx[1] && npady[0] != 2 && npadx[0] != 2) return 0; // one-sided
-  //if (npadx[1] && npady[0] != 2 && npadx[1] != 2) return 0;
+  // Add virtual pad only if number of pads per direction == 2
   if (nInX != 2 && nInY != 2) return;
 
   // Find pads with max charge
@@ -2469,18 +2671,30 @@ void AliMUONClusterFinderAZ::AddVirtualPad()
   }
   // Check for mirrors (side X on cathode 0) 
   Bool_t mirror = kFALSE;
-  if (maxpad[0][0] >= 0 && maxpad[1][0] >= 0) 
+  if (maxpad[0][0] >= 0 && maxpad[1][0] >= 0) {
     mirror = fXyq[3][maxpad[0][0]] < fXyq[4][maxpad[0][0]]; 
+    if (!mirror && TMath::Abs(fXyq[3][maxpad[0][0]]-fXyq[3][maxpad[1][0]]) < 0.001) {
+      // Special case when pads on both cathodes have the same size
+      Int_t yud[2] = {0};
+      for (Int_t j = 0; j < fnPads[0]+fnPads[1]; j++) {
+       cath = fPadIJ[0][j];
+       if (j == maxpad[cath][0]) continue;
+       if (fPadIJ[2][j] != fPadIJ[2][maxpad[cath][0]]) continue;
+       if (fPadIJ[3][j] + 1 == fPadIJ[3][maxpad[cath][0]] || 
+           fPadIJ[3][j] - 1 == fPadIJ[3][maxpad[cath][0]]) yud[cath]++;
+      }
+      if (!yud[0]) mirror = kTRUE; // take the other cathode
+    } // if (!mirror &&...
+  } // if (maxpad[0][0] >= 0 && maxpad[1][0] >= 0)
 
   // Find neughbours of pads with max charges
-  Int_t nn, xList[10], yList[10], ix0, iy0, ix, iy, neighb;
+  Int_t xList[10], yList[10], ix0, iy0, ix, iy, neighb;
   for (cath=0; cath<2; cath++) {
     if (!cath && maxpad[0][0] < 0) continue; // one-sided cluster - cathode 1
     if (cath && maxpad[1][0] < 0) break; // one-sided cluster - cathode 0
     if (maxpad[1][0] >= 0) {
       if (!mirror) {
        if (!cath && nInY != 2) continue;
-       //AZ if (cath && nInX != 2) continue;
        if (cath && nInX != 2 && (maxpad[0][0] >= 0 || nInY != 2)) continue;
       } else {
        if (!cath && nInX != 2) continue;
@@ -2491,45 +2705,23 @@ void AliMUONClusterFinderAZ::AddVirtualPad()
     Int_t iAddX = 0, iAddY = 0, ix1 = 0, iy1 = 0, iPad = 0;
     if (maxpad[0][0] < 0) iPad = 1;
 
-    /*
-    // This part of code to take care of edge effect (problems in MC)
-    Float_t sprX = fResponse->SigmaIntegration()*fResponse->ChargeSpreadX();
-    Float_t sprY = fResponse->SigmaIntegration()*fResponse->ChargeSpreadY();
-    Double_t rmin = 9999, rad2;
-    Int_t border = 0, iYlow = 0, iMuon = 0;
-
-    if (fDraw) {
-      for (Int_t i=0; i<2; i++) {
-       rad2 = (fXyq[0][maxpad[iPad][0]]-fxyMu[i][0]) * (fXyq[0][maxpad[iPad][0]]-fxyMu[i][0]);
-       rad2 += (fXyq[1][maxpad[iPad][0]]-fxyMu[i][1]) * (fXyq[1][maxpad[iPad][0]]-fxyMu[i][1]);
-       if (rad2 < rmin) { iMuon = i; rmin = rad2; }
-      }
-      fSegmentation[cath]->FirstPad(fInput->DetElemId(),(Float_t)fxyMu[iMuon][0], (Float_t)fxyMu[iMuon][1], fZpad, sprX, sprY);  
-      if (fSegmentation[cath]->Sector(fInput->DetElemId(),fSegmentation[cath]->Ix(),fSegmentation[cath]->Iy()) <= 0) {
-       fSegmentation[cath]->NextPad(fInput->DetElemId());
-       border = 1; 
-       iYlow = fSegmentation[cath]->Iy();
-      }
-    }
-    */
-    
     for (iPad=0; iPad<2; iPad++) {
+      if (maxpad[cath][iPad] < 0) continue;
       if (iPad && !iAddX && !iAddY) break;
       if (iPad && fXyq[2][maxpad[cath][1]] / sigmax[cath] < 0.5) break;
 
       Int_t neighbx = 0, neighby = 0;
-      fSegmentation[cath]->GetPadI(fInput->DetElemId(),fXyq[0][maxpad[cath][iPad]],fXyq[1][maxpad[cath][iPad]],fZpad,ix0,iy0);
-      fSegmentation[cath]->Neighbours(fInput->DetElemId(),ix0,iy0,&nn,xList,yList); 
-      Float_t zpad; //, xpad, ypad;
+      ix0 = fPadIJ[2][maxpad[cath][iPad]];
+      iy0 = fPadIJ[3][maxpad[cath][iPad]];
+      TObjArray neighbours;
+      AliMpPad pad = fSegmentation[cath]->PadByIndices(AliMpIntPair(ix0, iy0));
+      Int_t nn = fSegmentation[cath]->GetNeighbours(pad,neighbours);
       for (Int_t j=0; j<nn; j++) {
-       /*
-       if (border && yList[j] < iYlow) { xList[j] = yList[j] = 0; continue; }
-       fSegmentation[cath]->GetPadC(fInput->DetElemId(),xList[j],yList[j],xpad,ypad,zpad);
-       if (TMath::Abs(xpad) < 1 && TMath::Abs(ypad) < 1) 
-         { xList[j] = yList[j] = 0; continue; } // strange case (something with pad mapping)
-       */
-       if (TMath::Abs(xList[j]-ix0) == 1 || TMath::Abs(xList[j]*ix0) == 1) neighbx++;
-       if (TMath::Abs(yList[j]-iy0) == 1 || TMath::Abs(yList[j]*iy0) == 1) neighby++;
+        AliMpPad* pad = static_cast<AliMpPad*>(neighbours.At(j));
+        xList[j] = pad->GetIndices().GetFirst();
+        yList[j] = pad->GetIndices().GetSecond();
+        if (TMath::Abs(xList[j]-ix0) == 1 || xList[j]*ix0 == -1) neighbx++;
+        if (TMath::Abs(yList[j]-iy0) == 1 || yList[j]*iy0 == -1) neighby++;
       }
       if (!mirror) {
        if (cath) neighb = neighbx; 
@@ -2545,34 +2737,34 @@ void AliMUONClusterFinderAZ::AddVirtualPad()
 
       for (Int_t j=0; j<fnPads[0]+fnPads[1]; j++) {
        if (fPadIJ[0][j] != cath) continue;
-       fSegmentation[cath]->GetPadI(fInput->DetElemId(),fXyq[0][j],fXyq[1][j],fZpad,ix,iy);
+       ix = fPadIJ[2][j];
+       iy = fPadIJ[3][j];
        if (iy == iy0 && ix == ix0) continue; 
        for (Int_t k=0; k<nn; k++) {
          if (xList[k] != ix || yList[k] != iy) continue;
          if (!mirror) {
            if ((!cath || maxpad[0][0] < 0) && 
-               //(TMath::Abs(iy-iy0) == 1 || TMath::Abs(iy*iy0) == 1)) {
                (TMath::Abs(iy-iy0) == 1 || iy*iy0 == -1)) {
+             if (!iPad && TMath::Abs(ix-ix0) == 1 || ix*ix0 == -1) ix1 = xList[k]; //19-12-05 
              xList[k] = yList[k] = 0; 
              neighb--;
              break;
            }
            if ((cath || maxpad[1][0] < 0) && 
-               //(TMath::Abs(ix-ix0) == 1 || TMath::Abs(ix*ix0) == 1)) {
                (TMath::Abs(ix-ix0) == 1 || ix*ix0 == -1)) {
+             if (!iPad) ix1 = xList[k]; //19-12-05
              xList[k] = yList[k] = 0; 
              neighb--;
            }
          } else {
            if ((!cath || maxpad[0][0] < 0) && 
-               //(TMath::Abs(ix-ix0) == 1 || TMath::Abs(ix*ix0) == 1)) {
                (TMath::Abs(ix-ix0) == 1 || ix*ix0 == -1)) {
+             if (!iPad) ix1 = xList[k]; //19-12-05
              xList[k] = yList[k] = 0; 
              neighb--;
              break;
            }
            if ((cath || maxpad[1][0] < 0) && 
-               //(TMath::Abs(iy-iy0) == 1 || TMath::Abs(iy*iy0) == 1)) {
                (TMath::Abs(iy-iy0) == 1 || iy*iy0 == -1)) {
              xList[k] = yList[k] = 0; 
              neighb--;
@@ -2594,24 +2786,21 @@ void AliMUONClusterFinderAZ::AddVirtualPad()
        fPadIJ[1][npads] = 0;
        ix = xList[j]; 
        iy = yList[j];
-       //if (TMath::Abs(ix-ix0) == 1 || TMath::Abs(ix*ix0) == 1) {
        if (TMath::Abs(ix-ix0) == 1 || ix*ix0 == -1) {
          if (iy != iy0) continue; // new segmentation - check
          if (nInX != 2) continue; // new
          if (!mirror) {
            if (!cath && maxpad[1][0] >= 0) continue;
-           //if (maxpad[1][0] < 0 && nInX != 2) continue;
          } else {
            if (cath && maxpad[0][0] >= 0) continue;
-           //if (maxpad[0][0] < 0 && nInX != 2) continue;
          }
          if (iPad && !iAddX) continue;
-         fSegmentation[cath]->GetPadC(fInput->DetElemId(),ix,iy,fXyq[0][npads],fXyq[1][npads],zpad);
+         AliMpPad pad = fSegmentation[cath]->PadByIndices(AliMpIntPair(ix,iy));
+         fXyq[0][npads] = pad.Position().X();
+         fXyq[1][npads] = pad.Position().Y();
          if (fXyq[0][npads] > 1.e+5) continue; // temporary fix
+         if (ix == ix1) continue; //19-12-05
          if (ix1 == ix0) continue;
-         //if (iPad && ix1 == ix0) continue;
-         //if (iPad && TMath::Abs(fXyq[0][npads]-fXyq[0][iAddX]) < fXyq[3][iAddX]) continue;
-         //if (TMath::Abs(fXyq[0][npads]) < 1 && TMath::Abs(fXyq[1][npads]) < 1) continue; // strange case (something with pad mapping)
          if (maxpad[1][0] < 0 || mirror && maxpad[0][0] >= 0) {
            if (!iPad) fXyq[2][npads] = TMath::Min (sigmax[0]/100, 5.);
            else fXyq[2][npads] = TMath::Min (aamax[0]/100, 5.);
@@ -2621,13 +2810,13 @@ void AliMUONClusterFinderAZ::AddVirtualPad()
            else fXyq[2][npads] = TMath::Min (aamax[1]/100, 5.);
          }
          fXyq[2][npads] = TMath::Max (fXyq[2][npads], (float)1);
-         //fXyq[2][npads] = 1; 
-         //isec = fSegmentation[cath]->Sector(fInput->DetElemId(),ix, iy);
-         //fXyq[3][npads] = fSegmentation[cath]->Dpx(fInput->DetElemId(),isec)/2;
-         fXyq[3][npads] = -2; // flag
+         fXyq[3][npads] = -pad.Dimensions().X(); // "-" to flag
+         fXyq[4][npads] = pad.Dimensions().Y();
+         fPadIJ[2][npads] = ix;
+         fPadIJ[3][npads] = iy;
          fnPads[1]++;
          iAddX = npads;
-         if (fDebug) printf(" ***** Add virtual pad in X ***** %f %f %f %3d %3d \n", fXyq[2][npads],
+         if (fDebug) printf(" ***** Add virtual pad in X ***** %f %f %f %3d %3d \n", fXyq[2][npads], 
                             fXyq[0][npads], fXyq[1][npads], ix, iy);
          ix1 = ix0;
          continue;
@@ -2638,30 +2827,27 @@ void AliMUONClusterFinderAZ::AddVirtualPad()
        if (TMath::Abs(iy-iy0) == 1 || TMath::Abs(iy*iy0) == 1) {
          if (ix != ix0) continue; // new segmentation - check
          if (iPad && !iAddY) continue;
-         fSegmentation[cath]->GetPadC(fInput->DetElemId(),ix,iy,fXyq[0][npads],fXyq[1][npads],zpad);
+         AliMpPad pad = fSegmentation[cath]->PadByIndices(AliMpIntPair(ix,iy));
+         fXyq[0][npads] = pad.Position().X();
+         fXyq[1][npads] = pad.Position().Y();
          if (iy1 == iy0) continue;
          //if (iPad && iy1 == iy0) continue;
-         //if (iPad && TMath::Abs(fXyq[1][npads]-fXyq[1][iAddY]) < fXyq[4][iAddY]) continue;
-         //if (TMath::Abs(fXyq[0][npads]) < 1 && TMath::Abs(fXyq[1][npads]) < 1) continue; // strange case (something with pad mapping)
          if (maxpad[0][0] < 0 || mirror && maxpad[1][0] >= 0) {
-           //if (!iPad) fXyq[2][npads] = TMath::Min (sigmax[1]/20, 5.);
-           //else fXyq[2][npads] = TMath::Min (aamax[1]/20, 5.);
-           if (!iPad) fXyq[2][npads] = TMath::Min (sigmax[1]/15, (double)fResponse->ZeroSuppression());
-           else fXyq[2][npads] = TMath::Min (aamax[1]/15, (double)fResponse->ZeroSuppression());
+           if (!iPad) fXyq[2][npads] = TMath::Min (sigmax[1]/15, fgkZeroSuppression);
+           else fXyq[2][npads] = TMath::Min (aamax[1]/15, fgkZeroSuppression);
          }
          else {
-           //if (!iPad) fXyq[2][npads] = TMath::Min (sigmax[0]/20, 5.);
-           //else fXyq[2][npads] = TMath::Min (aamax[0]/20, 5.);
-           if (!iPad) fXyq[2][npads] = TMath::Min (sigmax[0]/15, (double)fResponse->ZeroSuppression());
-           else fXyq[2][npads] = TMath::Min (aamax[0]/15, (double)fResponse->ZeroSuppression());
+           if (!iPad) fXyq[2][npads] = TMath::Min (sigmax[0]/15, fgkZeroSuppression);
+           else fXyq[2][npads] = TMath::Min (aamax[0]/15, fgkZeroSuppression);
          }
          fXyq[2][npads] = TMath::Max (fXyq[2][npads], (float)1);
-         //isec = fSegmentation[cath]->Sector(fInput->DetElemId(),ix, iy);
-         //fXyq[4][npads] = fSegmentation[cath]->Dpy(isec)/2;
-         fXyq[3][npads] = -2; // flag
+         fXyq[3][npads] = -pad.Dimensions().X(); // "-" to flag
+         fXyq[4][npads] = pad.Dimensions().Y();
+         fPadIJ[2][npads] = ix;
+         fPadIJ[3][npads] = iy;
          fnPads[1]++;
          iAddY = npads;
-         if (fDebug) printf(" ***** Add virtual pad in Y ***** %f %f %f %3d %3d \n", fXyq[2][npads],
+         if (fDebug) printf(" ***** Add virtual pad in Y ***** %f %f %f %3d %3d \n", fXyq[2][npads], 
                             fXyq[0][npads], fXyq[1][npads], ix, iy);
          iy1 = iy0;
        }
@@ -2674,8 +2860,8 @@ void AliMUONClusterFinderAZ::AddVirtualPad()
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::PadsInXandY(Int_t &nInX, Int_t &nInY)
 {
-  // Find number of pads in X and Y-directions (excluding virtual ones and
-  // overflows)
+/// Find number of pads in X and Y-directions (excluding virtual ones and
+/// overflows)
 
   static Int_t nXsaved = 0, nYsaved = 0;
   nXsaved = nYsaved = 0;
@@ -2696,19 +2882,18 @@ void AliMUONClusterFinderAZ::PadsInXandY(Int_t &nInX, Int_t &nInY)
   }
   Int_t n0 = 0, n1 = 0, cath, npadx[2] = {1, 1}, npady[2] = {1, 1};
   for (Int_t j = 0; j < nPads; j++) {
-    //if (fPadIJ[1][j] != 0) continue;
-    //if (fXyq[3][j] < 0) continue; // virtual pad
     if (nInX < 0 && fPadIJ[1][j] != 0) continue; // before fit
     else if (nInX == 0 && fPadIJ[1][j] != 1) continue; // fit - exclude overflows
     else if (nInX > 0 && fPadIJ[1][j] != 1 && fPadIJ[1][j] != -9) continue; // exclude non-marked
-    if (nInX <= 0 && fXyq[2][j] > fResponse->Saturation()-1) continue; // skip overflows
+    if (nInX <= 0 && fXyq[2][j] > fgkSaturation-1) continue; // skip overflows
     cath = fPadIJ[0][j];
     if (fXyq[3][j] > 0) { // exclude virtual pads
       wMinX[cath] = TMath::Min (wMinX[cath], fXyq[3][j]);
       wMinY[cath] = TMath::Min (wMinY[cath], fXyq[4][j]);
+      //20-12-05 }
+      if (cath) { xPad1[n1] = fXyq[0][j]; yPad1[n1++] = fXyq[1][j]; }
+      else { xPad0[n0] = fXyq[0][j]; yPad0[n0++] = fXyq[1][j]; }
     }
-    if (cath) { xPad1[n1] = fXyq[0][j]; yPad1[n1++] = fXyq[1][j]; }
-    else { xPad0[n0] = fXyq[0][j]; yPad0[n0++] = fXyq[1][j]; }
   }
 
   // Sort
@@ -2731,8 +2916,6 @@ void AliMUONClusterFinderAZ::PadsInXandY(Int_t &nInX, Int_t &nInY)
   }
   if (fnPads[0]) { delete [] xPad0; delete [] yPad0; delete [] nPad0; }
   if (fnPads[1]) { delete [] xPad1; delete [] yPad1; delete [] nPad1; }
-  //nInY = TMath::Max (npady[0], npady[1]);
-  //nInX = TMath::Max (npadx[0], npadx[1]);
   if (TMath::Abs (wMinY[0] - wMinY[1]) < 1.e-3) nInY = TMath::Max (npady[0], npady[1]);
   else nInY = wMinY[0] < wMinY[1] ? npady[0] : npady[1];
   if (TMath::Abs (wMinX[0] - wMinX[1]) < 1.e-3) nInX = TMath::Max (npadx[0], npadx[1]);
@@ -2742,128 +2925,117 @@ void AliMUONClusterFinderAZ::PadsInXandY(Int_t &nInX, Int_t &nInY)
 //_____________________________________________________________________________
 void AliMUONClusterFinderAZ::Simple()
 {
-  // Process simple cluster (small number of pads) without EM-procedure
+/// Process simple cluster (small number of pads) without EM-procedure
 
   Int_t nForFit = 1, clustFit[1] = {0}, nfit;
   Double_t parOk[3] = {0.}; 
   TObjArray *clusters[1]; 
   clusters[0] = fPixArray;
   for (Int_t i = 0; i < fnPads[0]+fnPads[1]; i++) {
-    if (fXyq[2][i] > fResponse->Saturation()-1) fPadIJ[1][i] = -9;
+    if (fXyq[2][i] > fgkSaturation-1) fPadIJ[1][i] = -9;
     else fPadIJ[1][i] = 1;
   }
-  nfit = Fit(nForFit, clustFit, clusters, parOk);
+  nfit = Fit(1, nForFit, clustFit, clusters, parOk);
 }
 
 //_____________________________________________________________________________
-void AliMUONClusterFinderAZ::Errors(AliMUONRawCluster *clus)
+void AliMUONClusterFinderAZ::Errors(AliMUONRawCluster* /*clus*/)
 {
-  // Correct reconstructed coordinates for some clusters and evaluate errors
-
-  Double_t qTot = clus->GetCharge(0), fmin = clus->GetChi2(0);
-  Double_t xreco = clus->GetX(0), yreco = clus->GetY(0), zreco = clus->GetZ(0);
-  Double_t sigmax[2] = {0};
-
-  Int_t nInX = 1, nInY, maxdig[2] ={-1, -1}, digit, cath1, isec;
-  PadsInXandY(nInX, nInY);
-
-  // Find pad with maximum signal
-  for (Int_t cath = 0; cath < 2; cath++) {
-    for (Int_t j = 0; j < clus->GetMultiplicity(cath); j++) {
-      cath1 = cath;
-      digit = clus->GetIndex(j, cath);
-      if (digit < 0) { cath1 = TMath::Even(cath); digit = -digit - 1; } // from the other cathode
+/// Correct reconstructed coordinates for some clusters and evaluate errors
 
-      if (clus->GetContrib(j,cath) > sigmax[cath1]) {
-       sigmax[cath1] = clus->GetContrib(j,cath);
-       maxdig[cath1] = digit;
-      }
-    }
-  }
-
-  // Size of pad with maximum signal and reco coordinate distance from the pad center
-  AliMUONDigit *mdig = 0;
-  Double_t wx[2], wy[2], dxc[2], dyc[2];
-  Float_t xpad, ypad, zpad;
-  Int_t ix, iy;
-  for (Int_t cath = 0; cath < 2; cath++) {
-    if (maxdig[cath] < 0) continue;
-    mdig = fInput->Digit(cath,maxdig[cath]);
-    isec = fSegmentation[cath]->Sector(fInput->DetElemId(),mdig->PadX(), mdig->PadY());
-    wx[cath] = fSegmentation[cath]->Dpx(fInput->DetElemId(),isec);
-    wy[cath] = fSegmentation[cath]->Dpy(fInput->DetElemId(),isec);
-    fSegmentation[cath]->GetPadI(fInput->DetElemId(),xreco, yreco, zreco, ix, iy);
-    isec = fSegmentation[cath]->Sector(fInput->DetElemId(),ix,iy);
-    if (isec > 0) {
-      fSegmentation[cath]->GetPadC(fInput->DetElemId(), ix, iy, xpad, ypad, zpad);
-      dxc[cath] = xreco - xpad;
-      dyc[cath] = yreco - ypad;
-    }
-  }
-
-  // Check if pad with max charge at the edge (number of neughbours)
-  Int_t nn, xList[10], yList[10], neighbx[2][2] = {{0,0}, {0,0}}, neighby[2][2]= {{0,0}, {0,0}};
-  for (Int_t cath = 0; cath < 2; cath++) {
-    if (maxdig[cath] < 0) continue;
-    mdig = fInput->Digit(cath,maxdig[cath]);
-    fSegmentation[cath]->Neighbours(fInput->DetElemId(),mdig->PadX(),mdig->PadY(),&nn,xList,yList); 
-    isec = fSegmentation[cath]->Sector(fInput->DetElemId(),mdig->PadX(), mdig->PadY());
-    //*??
-    Float_t sprX = fResponse->SigmaIntegration() * fResponse->ChargeSpreadX();
-    Float_t sprY = fResponse->SigmaIntegration() * fResponse->ChargeSpreadY();
-    //fSegmentation[cath]->FirstPad(fInput->DetElemId(),muons[ihit][1], muons[ihit][2], muons[ihit][3], sprX, sprY);  
-    fSegmentation[cath]->FirstPad(fInput->DetElemId(),xreco, yreco, zreco, sprX, sprY);  
-    Int_t border = 0;
-    if (fSegmentation[cath]->Sector(fInput->DetElemId(),fSegmentation[cath]->Ix(),fSegmentation[cath]->Iy()) <= 0) {
-      fSegmentation[cath]->NextPad(fInput->DetElemId());
-      border = 1;
-    } 
-    //*/
-    for (Int_t j=0; j<nn; j++) {
-      if (border && yList[j] < fSegmentation[cath]->Iy()) continue;
-      fSegmentation[cath]->GetPadC (fInput->DetElemId(), xList[j], yList[j], xpad, ypad, zpad);
-      //cout << ch << " " << xList[j] << " " << yList[j] << " " << border << " " << x << " " << y << " " << xpad << " " << ypad << endl;
-      if (TMath::Abs(xpad) < 1 && TMath::Abs(ypad) < 1) continue;
-      if (xList[j] == mdig->PadX()-1 || mdig->PadX() == 1 && 
-         xList[j] == -1) neighbx[cath][0] = 1;
-      else if (xList[j] == mdig->PadX()+1 || mdig->PadX() == -1 && 
-              xList[j] == 1) neighbx[cath][1] = 1;
-      if (yList[j] == mdig->PadY()-1 || mdig->PadY() == 1 &&
-         yList[j] == -1) neighby[cath][0] = 1;
-      else if (yList[j] == mdig->PadY()+1 || mdig->PadY() == -1 &&
-              yList[j] == 1) neighby[cath][1] = 1;
-    } // for (Int_t j=0; j<nn;
-    if (neighbx[cath][0] && neighbx[cath][1]) neighbx[cath][0] = 0;
-    else if (neighbx[cath][1]) neighbx[cath][0] = -1;
-    else neighbx[cath][0] = 1;
-    if (neighby[cath][0] && neighby[cath][1]) neighby[cath][0] = 0;
-    else if (neighby[cath][1]) neighby[cath][0] = -1;
-    else neighby[cath][0] = 1;
-  }
-
-  Int_t iOver = clus->GetClusterType();
-  // One-sided cluster
-  if (!clus->GetMultiplicity(0)) {
-    neighby[0][0] = neighby[1][0];
-    wy[0] = wy[1];
-    if (iOver < 99) iOver += 100 * iOver;
-    dyc[0] = dyc[1];
-  } else if (!clus->GetMultiplicity(1)) {
-    neighbx[1][0] = neighbx[0][0];
-    wx[1] = wx[0];
-    if (iOver < 99) iOver += 100 * iOver;
-    dxc[1] = dxc[0];
-  }
-
-  // Apply corrections and evaluate errors
-  Double_t errY, errX;
-  Errors(nInY, nInX, neighby[0][0],neighbx[1][0], fmin, wy[0]*10, wx[1]*10, iOver, 
-        dyc[0], dxc[1], qTot, yreco, xreco, errY, errX);
-  errY = TMath::Max (errY, 0.01);
-  //errY = 0.01;
-  //errX = TMath::Max (errX, 0.144);
-  clus->SetX(0, xreco); clus->SetY(0, yreco);
-  clus->SetErrX(errX); clus->SetErrY(errY);
+  AliWarning("Reimplement me!");
+  
+//  Double_t qTot = clus->GetCharge(0), fmin = clus->GetChi2(0);
+//  Double_t xreco = clus->GetX(0), yreco = clus->GetY(0), zreco = clus->GetZ(0);
+//  Double_t sigmax[2] = {0};
+//
+//  Int_t nInX = 1, nInY, maxdig[2] ={-1, -1}, digit, cath1, isec;
+//  PadsInXandY(nInX, nInY);
+//
+//  // Find pad with maximum signal
+//  for (Int_t cath = 0; cath < 2; cath++) {
+//    for (Int_t j = 0; j < clus->GetMultiplicity(cath); j++) {
+//      cath1 = cath;
+//      digit = clus->GetIndex(j, cath);
+//      if (digit < 0) { cath1 = TMath::Even(cath); digit = -digit - 1; } // from the other cathode
+//
+//      if (clus->GetContrib(j,cath) > sigmax[cath1]) {
+//     sigmax[cath1] = clus->GetContrib(j,cath);
+//     maxdig[cath1] = digit;
+//      }
+//    }
+//  }
+//
+//  // Size of pad with maximum signal and reco coordinate distance from the pad center
+//  AliMUONVDigit *mdig = 0;
+//  Double_t wx[2], wy[2], dxc[2], dyc[2];
+//  Float_t xpad, ypad, zpad;
+//  Int_t ix, iy;
+//  for (Int_t cath = 0; cath < 2; cath++) {
+//    if (maxdig[cath] < 0) continue;
+//    mdig = fDigitStore->Find(maxdig[cath]);
+//    isec = fSegmentation[cath]->Sector(mdig->PadX(), mdig->PadY());
+//    wx[cath] = fSegmentation[cath]->Dpx(isec);
+//    wy[cath] = fSegmentation[cath]->Dpy(isec);
+//    fSegmentation[cath]->GetPadI(xreco, yreco, zreco, ix, iy);
+//    isec = fSegmentation[cath]->Sector(ix, iy);
+//    if (isec > 0) {
+//      fSegmentation[cath]->GetPadC(ix, iy, xpad, ypad, zpad);
+//      dxc[cath] = xreco - xpad;
+//      dyc[cath] = yreco - ypad;
+//    }
+//  }
+//
+//  // Check if pad with max charge at the edge (number of neughbours)
+//  Int_t nn, xList[10], yList[10], neighbx[2][2] = {{0,0}, {0,0}}, neighby[2][2]= {{0,0}, {0,0}};
+//  for (Int_t cath = 0; cath < 2; cath++) {
+//    if (maxdig[cath] < 0) continue;
+//    mdig = fDigitStore->FindObject(maxdig[cath]);
+//    fSegmentation[cath]->Neighbours(mdig->PadX(), mdig->PadY(), &nn, xList, yList); 
+//    isec = fSegmentation[cath]->Sector(mdig->PadX(), mdig->PadY());
+//    for (Int_t j=0; j<nn; j++) {
+//      fSegmentation[cath]->GetPadC(xList[j], yList[j], xpad, ypad, zpad);
+//      if (TMath::Abs(xpad) < 1 && TMath::Abs(ypad) < 1) continue;
+//      if (xList[j] == mdig->PadX()-1 || mdig->PadX() == 1 && 
+//       xList[j] == -1) neighbx[cath][0] = 1;
+//      else if (xList[j] == mdig->PadX()+1 || mdig->PadX() == -1 && 
+//            xList[j] == 1) neighbx[cath][1] = 1;
+//      if (yList[j] == mdig->PadY()-1 || mdig->PadY() == 1 &&
+//       yList[j] == -1) neighby[cath][0] = 1;
+//      else if (yList[j] == mdig->PadY()+1 || mdig->PadY() == -1 &&
+//            yList[j] == 1) neighby[cath][1] = 1;
+//    } // for (Int_t j=0; j<nn;
+//    if (neighbx[cath][0] && neighbx[cath][1]) neighbx[cath][0] = 0;
+//    else if (neighbx[cath][1]) neighbx[cath][0] = -1;
+//    else neighbx[cath][0] = 1;
+//    if (neighby[cath][0] && neighby[cath][1]) neighby[cath][0] = 0;
+//    else if (neighby[cath][1]) neighby[cath][0] = -1;
+//    else neighby[cath][0] = 1;
+//  }
+//
+//  Int_t iOver = clus->GetClusterType();
+//  // One-sided cluster
+//  if (!clus->GetMultiplicity(0)) {
+//    neighby[0][0] = neighby[1][0];
+//    wy[0] = wy[1];
+//    if (iOver < 99) iOver += 100 * iOver;
+//    dyc[0] = dyc[1];
+//  } else if (!clus->GetMultiplicity(1)) {
+//    neighbx[1][0] = neighbx[0][0];
+//    wx[1] = wx[0];
+//    if (iOver < 99) iOver += 100 * iOver;
+//    dxc[1] = dxc[0];
+//  }
+//
+//  // Apply corrections and evaluate errors
+//  Double_t errY, errX;
+//  Errors(nInY, nInX, neighby[0][0],neighbx[1][0], fmin, wy[0]*10, wx[1]*10, iOver, 
+//      dyc[0], dxc[1], qTot, yreco, xreco, errY, errX);
+//  errY = TMath::Max (errY, 0.01);
+//  //errY = 0.01;
+//  //errX = TMath::Max (errX, 0.144);
+//  clus->SetX(0, xreco); clus->SetY(0, yreco);
+//  clus->SetErrX(errX); clus->SetErrY(errY);
 }
 
 //_____________________________________________________________________________
@@ -2872,7 +3044,7 @@ void AliMUONClusterFinderAZ::Errors(Int_t ny, Int_t nx, Int_t iby, Int_t ibx, Do
                                    Double_t dyc, Double_t /*dxc*/, Double_t qtot, 
                                    Double_t &yrec, Double_t &xrec, Double_t &erry, Double_t &errx)
 {
-  // Correct reconstructed coordinates for some clusters and evaluate errors
+/// Correct reconstructed coordinates for some clusters and evaluate errors
 
     erry = 0.01;
     errx = 0.144;
@@ -3040,3 +3212,9 @@ void AliMUONClusterFinderAZ::Errors(Int_t ny, Int_t nx, Int_t iby, Int_t ibx, Do
     else if (TMath::Abs(wx - 10) < 0.1) errx = 0.07359;
 }
 
+//___________________________________________________________________________
+void AliMUONClusterFinderAZ::ResetRawClusters()
+{
+  /// Reset tracks information
+  if (fRawClusters) fRawClusters->Clear("C");
+}