]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONClusterFinderMLEM.cxx
modified bin sizes of some histo
[u/mrichter/AliRoot.git] / MUON / AliMUONClusterFinderMLEM.cxx
index d48820a9da12ed0c07f3d33207dfb12e093af818..58019ef92e80b05eb6e6183bafefd73f754a7201 100644 (file)
 #include <TMath.h>
 #include "AliCodeTimer.h"
 
+using std::endl;
+using std::cout;
 /// \cond CLASSIMP
 ClassImp(AliMUONClusterFinderMLEM)
 /// \endcond
  
-const Double_t AliMUONClusterFinderMLEM::fgkZeroSuppression = 6; // average zero suppression value
-//const Double_t AliMUONClusterFinderMLEM::fgkDistancePrecision = 1e-6; // (cm) used to check overlaps and so on
 const Double_t AliMUONClusterFinderMLEM::fgkDistancePrecision = 1e-3; // (cm) used to check overlaps and so on
 const TVector2 AliMUONClusterFinderMLEM::fgkIncreaseSize(-AliMUONClusterFinderMLEM::fgkDistancePrecision,-AliMUONClusterFinderMLEM::fgkDistancePrecision);
 const TVector2 AliMUONClusterFinderMLEM::fgkDecreaseSize(AliMUONClusterFinderMLEM::fgkDistancePrecision,AliMUONClusterFinderMLEM::fgkDistancePrecision);
@@ -81,11 +81,14 @@ fDebug(0),
 fPlot(plot),
 fSplitter(0x0),
 fNClusters(0),
-fNAddVirtualPads(0)
+fNAddVirtualPads(0),
+fLowestPixelCharge(0),
+fLowestPadCharge(0),
+fLowestClusterCharge(0)
 {
   /// Constructor
-  fSegmentation[1] = fSegmentation[0] = 0x0; 
+
+  fkSegmentation[1] = fkSegmentation[0] = 0x0; 
 
   if (fPlot) fDebug = 1;
 }
@@ -105,31 +108,36 @@ AliMUONClusterFinderMLEM::~AliMUONClusterFinderMLEM()
 //_____________________________________________________________________________
 Bool_t 
 AliMUONClusterFinderMLEM::Prepare(Int_t detElemId,
-                                  TClonesArray* pads[2],
+                                  TObjArray* pads[2],
                                   const AliMpArea& area,
                                   const AliMpVSegmentation* seg[2])
 {
   /// Prepare for clustering
-//  AliCodeTimerAuto("")
+//  AliCodeTimerAuto("",0)
   
   for ( Int_t i = 0; i < 2; ++i )
   {
-    fSegmentation[i] = seg[i];
+    fkSegmentation[i] = seg[i];
   }
   
   // Find out the DetElemId
   fDetElemId = detElemId;
   
   delete fSplitter;
-  fSplitter = new AliMUONClusterSplitterMLEM(fDetElemId,fPixArray);
+  fSplitter = new AliMUONClusterSplitterMLEM(fDetElemId,
+                                             fPixArray,
+                                             fLowestPixelCharge,
+                                             fLowestPadCharge,
+                                             fLowestClusterCharge);
   fSplitter->SetDebug(fDebug);
     
   // find out current event number, and reset the cluster number
-  AliRunLoader *runLoader = AliRunLoader::GetRunLoader();
+  AliRunLoader *runLoader = AliRunLoader::Instance();
   fEventNumber = runLoader ? runLoader->GetEventNumber() : 0;
   fClusterNumber = -1;
   fClusterList.Delete();
-  
+  fPixArray->Delete();
+
   AliDebug(3,Form("EVT %d DE %d",fEventNumber,fDetElemId));
   
   if ( fPreClusterFinder->NeedSegmentation() )
@@ -147,10 +155,17 @@ AliMUONCluster*
 AliMUONClusterFinderMLEM::NextCluster()
 {
   /// Return next cluster
-//  AliCodeTimerAuto("")
+//  AliCodeTimerAuto("",0)
   
   // if the list of clusters is not void, pick one from there
-  TObject* o = fClusterList.At(++fClusterNumber);
+  TObject* o(0x0);
+  
+  // do we have clusters in our list ?
+  if ( fClusterNumber < fClusterList.GetLast() )
+  {
+    o = fClusterList.At(++fClusterNumber);
+  }
+  
   if ( o != 0x0 ) return static_cast<AliMUONCluster*>(o);
   
   //FIXME : at this point, must check whether we've used all the digits
@@ -162,6 +177,7 @@ AliMUONClusterFinderMLEM::NextCluster()
 
   fPreCluster = fPreClusterFinder->NextCluster();
 
+  fPixArray->Delete();
   fClusterList.Delete(); // reset the list of clusters for this pre-cluster
   fClusterNumber = -1; //AZ
     
@@ -196,7 +212,7 @@ AliMUONClusterFinderMLEM::WorkOnPreCluster()
   /// Starting from a precluster, builds a pixel array, and then
   /// extract clusters from this array
   
-  //  AliCodeTimerAuto("")     
+  //  AliCodeTimerAuto("",0)   
 
   if (fDebug) {
     cout << " *** Event # " << fEventNumber 
@@ -293,11 +309,11 @@ AliMUONClusterFinderMLEM::CheckPrecluster(const AliMUONCluster& origCluster)
   /// Check precluster in order to attempt to simplify it (mostly for
   /// two-cathode preclusters)
     
-  AliCodeTimerAuto("")
+  AliCodeTimerAuto("",0)
 
   // Disregard small clusters (leftovers from splitting or noise)
   if ((origCluster.Multiplicity()==1 || origCluster.Multiplicity()==2) &&
-      origCluster.Charge(0)+origCluster.Charge(1) < 10) 
+      origCluster.Charge(0)+origCluster.Charge(1) < fLowestClusterCharge )
   { 
     return 0x0;
   }
@@ -363,10 +379,11 @@ AliMUONClusterFinderMLEM::CheckPreclusterTwoCathodes(AliMUONCluster* cluster)
       Int_t cath = pad->Cathode();
       Int_t cath1 = TMath::Even(cath);
       // Check for edge effect (missing pads on the _other_ cathode)
-      AliMpPad mpPad = fSegmentation[cath1]->PadByPosition(pad->Position(),kFALSE);
+      AliMpPad mpPad =
+      fkSegmentation[cath1]->PadByPosition(pad->Position().X(),
+                                           pad->Position().Y(),kFALSE);
       if (!mpPad.IsValid()) continue;
-      //if (nFlags == 1 && pad->Charge() < fgkZeroSuppression * 3) continue;
-      if (nFlags == 1 && pad->Charge() < 20) continue;
+      if (nFlags == 1 && pad->Charge() < fLowestPadCharge) continue; 
       AliDebug(2,Form("Releasing the following pad : de,cath,ix,iy %d,%d,%d,%d charge %e",
                       fDetElemId,pad->Cathode(),pad->Ix(),pad->Iy(),pad->Charge()));
       toBeRemoved.AddLast(pad);
@@ -536,7 +553,7 @@ AliMUONClusterFinderMLEM::CheckOverlaps()
                         cout << " Surface = " << pixelI->Size(0)*pixelI->Size(1)*4 << endl;
                         pixelJ->Print();
                         cout << " Surface = " << pixelJ->Size(0)*pixelJ->Size(1)*4 << endl;
-                        cout << " Area surface = " << area.Dimensions().X()*area.Dimensions().Y()*4 << endl;
+                        cout << " Area surface = " << area.GetDimensionX()*area.GetDimensionY()*4 << endl;
                         cout << "-------" << endl;
                         );
        */        
@@ -589,8 +606,8 @@ void AliMUONClusterFinderMLEM::BuildPixArrayOneCathode(AliMUONCluster& cluster)
 //  AliDebug(2,Form("cluster.Multiplicity=%d",cluster.Multiplicity()));
 
   TVector2 dim = cluster.MinPadDimensions (-1, kFALSE);
-  Double_t width[2] = {dim.X(), dim.Y()}, xy0[2];
-  Int_t found[2] = {0}, mult = cluster.Multiplicity();
+  Double_t width[2] = {dim.X(), dim.Y()}, xy0[2]={99999,99999};
+  Int_t found[2] = {0,0}, mult = cluster.Multiplicity();
 
   for ( Int_t i = 0; i < mult; ++i) {
     AliMUONPad* pad = cluster.Pad(i);
@@ -608,24 +625,27 @@ void AliMUONClusterFinderMLEM::BuildPixArrayOneCathode(AliMUONCluster& cluster)
   if (cluster.Multiplicity(0) == 0) cath0 = 1;
   else if (cluster.Multiplicity(1) == 0) cath1 = 0;
 
-  TVector2 leftDown = cluster.Area(cath0).LeftDownCorner();
-  TVector2 rightUp = cluster.Area(cath0).RightUpCorner();
-  min[0] = leftDown.X();
-  min[1] = leftDown.Y();
-  max[0] = rightUp.X();
-  max[1] = rightUp.Y();
+
+  Double_t leftDownX, leftDownY;
+  cluster.Area(cath0).LeftDownCorner(leftDownX, leftDownY);
+  Double_t rightUpX, rightUpY;
+  cluster.Area(cath0).RightUpCorner(rightUpX, rightUpY);
+  min[0] = leftDownX;
+  min[1] = leftDownY;
+  max[0] = rightUpX;
+  max[1] = rightUpY;;
   if (cath1 != cath0) {
-    leftDown = cluster.Area(cath1).LeftDownCorner();
-    rightUp = cluster.Area(cath1).RightUpCorner();
-    min[0] = TMath::Max (min[0], leftDown.X());
-    min[1] = TMath::Max (min[1], leftDown.Y());
-    max[0] = TMath::Min (max[0], rightUp.X());
-    max[1] = TMath::Min (max[1], rightUp.Y());
+    cluster.Area(cath1).LeftDownCorner(leftDownX, leftDownY);
+    cluster.Area(cath1).RightUpCorner(rightUpX, rightUpY);
+    min[0] = TMath::Max (min[0], leftDownX);
+    min[1] = TMath::Max (min[1], leftDownY);
+    max[0] = TMath::Min (max[0], rightUpX);
+    max[1] = TMath::Min (max[1], rightUpY);
   }
 
   // Adjust limits
   //width[0] /= 2; width[1] /= 2; // just for check
-  Int_t nbins[2];
+  Int_t nbins[2]={0,0};
   for (Int_t i = 0; i < 2; ++i) {
     Double_t dist = (min[i] - xy0[i]) / width[i] / 2;
     if (TMath::Abs(dist) < 1.e-6) dist = -1.e-6;
@@ -655,17 +675,17 @@ void AliMUONClusterFinderMLEM::BuildPixArrayOneCathode(AliMUONCluster& cluster)
   for (Int_t i = 1; i <= nbins[0]; ++i) {
     Double_t x = xaxis->GetBinCenter(i);
     for (Int_t j = 1; j <= nbins[1]; ++j) {
-      if (hist2->GetCellContent(i,j) < 0.1) continue;
-      //if (hist2->GetCellContent(i,j) < 1.1 && cluster.Multiplicity(0) && 
+      if (hist2->GetBinContent(hist2->GetBin(i,j)) < 0.1) continue;
+      //if (hist2->GetBinContent(hist2->GetBin(i,j)) < 1.1 && cluster.Multiplicity(0) && 
       //  cluster.Multiplicity(1)) continue;
       if (cath0 != cath1) {
        // Two-sided cluster
-       Double_t cont = hist2->GetCellContent(i,j);
+       Double_t cont = hist2->GetBinContent(hist2->GetBin(i,j));
        if (cont < 999.) continue;
        if (cont-Int_t(cont/1000.)*1000. < 0.5) continue;
       }
       Double_t y = yaxis->GetBinCenter(j);
-      Double_t charge = hist1->GetCellContent(i,j);
+      Double_t charge = hist1->GetBinContent(hist1->GetBin(i,j));
       AliMUONPad* pixPtr = new AliMUONPad(x, y, width[0], width[1], charge);
       fPixArray->Add(pixPtr);
     }  
@@ -706,11 +726,11 @@ void AliMUONClusterFinderMLEM::PadOverHist(Int_t idir, Int_t ix0, Int_t iy0, Ali
     else {
       // Fill histogram
       Double_t cont = pad->Charge();
-      if (hist2->GetCellContent(ix0, ixy) > 0.1) 
-       cont = TMath::Min (hist1->GetCellContent(ix0, ixy), cont);
-      hist1->SetCellContent(ix0, ixy, cont);
-      //hist2->SetCellContent(ix0, ixy, hist2->GetCellContent(ix0, ixy)+1);
-      hist2->SetCellContent(ix0, ixy, hist2->GetCellContent(ix0, ixy)+amask);
+      if (hist2->GetBinContent(hist2->GetBin(ix0, ixy)) > 0.1) 
+       cont = TMath::Min (hist1->GetBinContent(hist1->GetBin(ix0, ixy)), cont);
+      hist1->SetBinContent(hist1->GetBin(ix0, ixy), cont);
+      //hist2->SetBinContent(hist2->GetBin(ix0, ixy), hist2->GetBinContent(hist2->GetBin(ix0, ixy))+1);
+      hist2->SetBinContent(hist2->GetBin(ix0, ixy), hist2->GetBinContent(hist2->GetBin(ix0, ixy))+amask);
     }
   }
 
@@ -723,31 +743,31 @@ void AliMUONClusterFinderMLEM::PadOverHist(Int_t idir, Int_t ix0, Int_t iy0, Ali
     else {
       // Fill histogram
       Double_t cont = pad->Charge();
-      if (hist2->GetCellContent(ix0, ixy) > 0.1) 
-       cont = TMath::Min (hist1->GetCellContent(ix0, ixy), cont);
-      hist1->SetCellContent(ix0, ixy, cont);
-      //hist2->SetCellContent(ix0, ixy, hist2->GetCellContent(ix0, ixy)+1);
-      hist2->SetCellContent(ix0, ixy, hist2->GetCellContent(ix0, ixy)+amask);
+      if (hist2->GetBinContent(hist2->GetBin(ix0, ixy)) > 0.1) 
+       cont = TMath::Min (hist1->GetBinContent(hist1->GetBin(ix0, ixy)), cont);
+      hist1->SetBinContent(hist1->GetBin(ix0, ixy), cont);
+      //hist2->SetBinContent(hist1->GetBin(ix0, ixy), hist2->GetBinContent(hist2->GetBin(ix0, ixy))+1);
+      hist2->SetBinContent(hist2->GetBin(ix0, ixy), hist2->GetBinContent(hist2->GetBin(ix0, ixy))+amask);
     }
   }
 }
 
 //_____________________________________________________________________________
 void
-AliMUONClusterFinderMLEM::Plot(const char* basename)
+AliMUONClusterFinderMLEM::Plot(const char* /*basename*/)
 {
   /// Make a plot and save it as png
   
   return; //AZ
-  if (!fPlot) return;
-  
-  TCanvas* c = new TCanvas("MLEM","MLEM",800,600);
-  c->Draw();
-  Draw();
-  c->Modified();
-  c->Update();
-  c->Print(Form("%s.EVT%d.DE%d.CLU%d.png",basename,fEventNumber,
-                fDetElemId,fClusterNumber));
+//  if (!fPlot) return;
+//  
+//  TCanvas* c = new TCanvas("MLEM","MLEM",800,600);
+//  c->Draw();
+//  Draw();
+//  c->Modified();
+//  c->Update();
+//  c->Print(Form("%s.EVT%d.DE%d.CLU%d.png",basename,fEventNumber,
+//                fDetElemId,fClusterNumber));
 }
 
 //_____________________________________________________________________________
@@ -758,9 +778,11 @@ AliMUONClusterFinderMLEM::ComputeCoefficients(AliMUONCluster& cluster,
 {
   /// Compute coefficients needed for MLEM algorithm
   
+  Int_t npadTot = cluster.Multiplicity();
   Int_t nPix = fPixArray->GetLast()+1;
   
   //memset(probi,0,nPix*sizeof(Double_t));
+  for (Int_t j = 0; j < npadTot*nPix; ++j) coef[j] = 0.;
   for (Int_t j = 0; j < nPix; ++j) probi[j] = 0.;
 
   Int_t mult = cluster.Multiplicity();
@@ -800,7 +822,7 @@ Bool_t AliMUONClusterFinderMLEM::MainLoop(AliMUONCluster& cluster, Int_t iSimple
 {
   /// Repeat MLEM algorithm until pixel size becomes sufficiently small
   
-  //  AliCodeTimerAuto("")
+  //  AliCodeTimerAuto("",0)
   
   Int_t nPix = fPixArray->GetLast()+1;
 
@@ -834,10 +856,11 @@ Bool_t AliMUONClusterFinderMLEM::MainLoop(AliMUONCluster& cluster, Int_t iSimple
   {
     ++lc;
     delete fHistMlem;
+    fHistMlem = 0x0;
     
     AliDebug(2,Form("lc %d nPix %d(%d) npadTot %d npadOK %d",lc,nPix,fPixArray->GetLast()+1,npadTot,npadOK));
     AliDebug(2,Form("EVT%d PixArray=",fEventNumber));
-    //StdoutToAliDebug(2,fPixArray->Print("","full"));
+    //StdoutToAliDebug(2,fPixArray->Print("full"));
         
     coef = new Double_t [npadTot*nPix];
     probi = new Double_t [nPix];
@@ -887,6 +910,10 @@ Bool_t AliMUONClusterFinderMLEM::MainLoop(AliMUONCluster& cluster, Int_t iSimple
                     xylim[0],-xylim[1],xylim[2],-xylim[3]
                     ));
     
+    AliDebug(2,Form("LowestPadCharge=%e",fLowestPadCharge));
+    
+    delete fHistMlem;
+    
     fHistMlem = new TH2D("mlem","mlem",nx,xylim[0],-xylim[1],ny,xylim[2],-xylim[3]);
 
     for (Int_t ipix = 0; ipix < nPix; ++ipix) 
@@ -902,7 +929,7 @@ Bool_t AliMUONClusterFinderMLEM::MainLoop(AliMUONCluster& cluster, Int_t iSimple
       qTot += Pixel(i)->Charge();
     }
     
-    if ( qTot < 1.e-4 || ( npadOK < 3 && qTot < 7 ) ) 
+    if ( qTot < 1.e-4 || ( npadOK < 3 && qTot < fLowestClusterCharge ) )
     {
       AliDebug(1,Form("Deleting the above cluster (charge %e too low, npadOK=%d)",qTot,npadOK));
       delete [] coef; 
@@ -939,7 +966,7 @@ Bool_t AliMUONClusterFinderMLEM::MainLoop(AliMUONCluster& cluster, Int_t iSimple
     fPixArray->Sort();
     MaskPeaks(0); // unmask local maxima
     Double_t pixMin = 0.01*Pixel(0)->Charge();
-    pixMin = TMath::Min(pixMin,50.);
+    pixMin = TMath::Min(pixMin,100*fLowestPixelCharge);
 
     // Decrease pixel size and shift pixels to make them centered at 
     // the maximum one
@@ -955,7 +982,7 @@ Bool_t AliMUONClusterFinderMLEM::MainLoop(AliMUONCluster& cluster, Int_t iSimple
       AliMUONPad* pixPtr2 = Pixel(ipix);
       if ( nPix >= npadOK  // too many pixels already
            ||
-           pixPtr2->Charge() < pixMin && pixPtr2->Status() != fgkMustKeep // too low charge
+           ((pixPtr2->Charge() < pixMin) && (pixPtr2->Status() != fgkMustKeep)) // too low charge
            ) 
       { 
         RemovePixel(ipix);
@@ -965,7 +992,7 @@ Bool_t AliMUONClusterFinderMLEM::MainLoop(AliMUONCluster& cluster, Int_t iSimple
       {
         if (!i) 
         {
-          pixPtr2->SetCharge(10);
+          pixPtr2->SetCharge(fLowestPadCharge);
           pixPtr2->SetSize(indx, pixPtr2->Size(indx)/2);
           width = -pixPtr2->Size(indx);
           pixPtr2->Shift(indx, width);
@@ -1045,8 +1072,8 @@ Bool_t AliMUONClusterFinderMLEM::MainLoop(AliMUONCluster& cluster, Int_t iSimple
 
   // remove pixels with low signal or low visibility
   // Cuts are empirical !!!
-  Double_t thresh = TMath::Max (fHistMlem->GetMaximum()/100.,1.);
-  thresh = TMath::Min (thresh,50.);
+  Double_t thresh = TMath::Max (fHistMlem->GetMaximum()/100.,2.0*fLowestPixelCharge);
+  thresh = TMath::Min (thresh,100.0*fLowestPixelCharge);
   Double_t charge = 0;
 
   // Mark pixels which should be removed
@@ -1090,7 +1117,7 @@ Bool_t AliMUONClusterFinderMLEM::MainLoop(AliMUONCluster& cluster, Int_t iSimple
 
   // Try to split into clusters
   Bool_t ok = kTRUE;
-  if (fHistMlem->GetSum() < 1
+  if (fHistMlem->GetSum() < 2.0*fLowestPixelCharge
   {
     ok = kFALSE;
   }
@@ -1123,7 +1150,7 @@ void AliMUONClusterFinderMLEM::MaskPeaks(Int_t mask)
 
 //_____________________________________________________________________________
 void AliMUONClusterFinderMLEM::Mlem(AliMUONCluster& cluster, 
-                                    Double_t* coef, Double_t* probi, 
+                                    const Double_t* coef, Double_t* probi, 
                                     Int_t nIter)
 {
   /// Use MLEM to find pixel charges
@@ -1142,6 +1169,7 @@ void AliMUONClusterFinderMLEM::Mlem(AliMUONCluster& cluster,
     {
       Pixel(ipix)->SetChargeBackup(0);
       // Correct each pixel
+      probi1[ipix] = 0;
       if (probi[ipix] < 0.01) continue; // skip "invisible" pixel
       Double_t sum = 0;
       probi1[ipix] = probMax;
@@ -1209,7 +1237,7 @@ void AliMUONClusterFinderMLEM::FindCOG(Double_t *xyc)
   for (Int_t i = TMath::Max(1,iymax-1); i <= ie; ++i) {
     y = fHistMlem->GetYaxis()->GetBinCenter(i);
     for (Int_t j = TMath::Max(1,ixmax-1); j <= je; ++j) {
-      cont = fHistMlem->GetCellContent(j,i);
+      cont = fHistMlem->GetBinContent(fHistMlem->GetBin(j,i));
       if (cont < thresh) continue;
       if (i != i1) {i1 = i; nsumy++;}
       if (j != j1) {j1 = j; nsumx++;}
@@ -1229,7 +1257,7 @@ void AliMUONClusterFinderMLEM::FindCOG(Double_t *xyc)
     for (Int_t i = TMath::Max(1,iymax-1); i <= ie; ++i) {
       if (i == iymax) continue;
       for (Int_t j = TMath::Max(1,ixmax-1); j <= je; ++j) {
-        cont = fHistMlem->GetCellContent(j,i);
+        cont = fHistMlem->GetBinContent(fHistMlem->GetBin(j,i));
         if (cont > cmax) {
           cmax = cont;
           x = fHistMlem->GetXaxis()->GetBinCenter(j);
@@ -1253,7 +1281,7 @@ void AliMUONClusterFinderMLEM::FindCOG(Double_t *xyc)
     for (Int_t j = TMath::Max(1,ixmax-1); j <= je; ++j) {
       if (j == ixmax) continue;
       for (Int_t i = TMath::Max(1,iymax-1); i <= ie; ++i) {
-        cont = fHistMlem->GetCellContent(j,i);
+        cont = fHistMlem->GetBinContent(fHistMlem->GetBin(j,i));
         if (cont > cmax) {
           cmax = cont;
           x = fHistMlem->GetXaxis()->GetBinCenter(j);
@@ -1276,7 +1304,7 @@ void AliMUONClusterFinderMLEM::FindCOG(Double_t *xyc)
 }
 
 //_____________________________________________________________________________
-Int_t AliMUONClusterFinderMLEM::FindNearest(AliMUONPad *pixPtr0)
+Int_t AliMUONClusterFinderMLEM::FindNearest(const AliMUONPad *pixPtr0)
 {
 /// Find the pixel nearest to the given one
 /// (algorithm may be not very efficient)
@@ -1288,7 +1316,7 @@ Int_t AliMUONClusterFinderMLEM::FindNearest(AliMUONPad *pixPtr0)
 
   for (Int_t i = 0; i < nPix; ++i) {
     pixPtr = (AliMUONPad*) fPixArray->UncheckedAt(i);
-    if (pixPtr == pixPtr0 || pixPtr->Charge() < 0.5) continue;
+    if (pixPtr == pixPtr0 || pixPtr->Charge() < fLowestPixelCharge) continue;
     dx = (xc - pixPtr->Coord(0)) / pixPtr->Size(0);
     dy = (yc - pixPtr->Coord(1)) / pixPtr->Size(1);
     r = dx *dx + dy * dy;
@@ -1368,6 +1396,9 @@ Int_t AliMUONClusterFinderMLEM::FindLocalMaxima(TObjArray *pixArray, Int_t *loca
   Double_t xylim[4] = {999, 999, 999, 999};
 
   Int_t nPix = pixArray->GetEntriesFast();
+  
+  if ( nPix <= 0 ) return 0;
+  
   AliMUONPad *pixPtr = 0;
   for (Int_t ipix = 0; ipix < nPix; ++ipix) {
     pixPtr = (AliMUONPad*) pixArray->UncheckedAt(ipix);
@@ -1393,7 +1424,7 @@ Int_t AliMUONClusterFinderMLEM::FindLocalMaxima(TObjArray *pixArray, Int_t *loca
   for (Int_t i = 1; i <= ny; ++i) {
     indx = (i-1) * nx;
     for (Int_t j = 1; j <= nx; ++j) {
-      if (fHistAnode->GetCellContent(j,i) < 0.5) continue;
+      if (fHistAnode->GetBinContent(fHistAnode->GetBin(j,i)) < fLowestPixelCharge) continue;
       //if (isLocalMax[indx+j-1] < 0) continue;
       if (isLocalMax[indx+j-1] != 0) continue;
       FlagLocalMax(fHistAnode, i, j, isLocalMax);
@@ -1405,7 +1436,7 @@ Int_t AliMUONClusterFinderMLEM::FindLocalMaxima(TObjArray *pixArray, Int_t *loca
     for (Int_t j = 1; j <= nx; ++j) {
       if (isLocalMax[indx+j-1] > 0) { 
        localMax[nMax] = indx + j - 1; 
-       maxVal[nMax++] = fHistAnode->GetCellContent(j,i);
+       maxVal[nMax++] = fHistAnode->GetBinContent(fHistAnode->GetBin(j,i));
        ((AliMUONPad*)fSplitter->BinToPix(fHistAnode, j, i))->SetStatus(fgkMustKeep);
        if (nMax > 99) break;
       }
@@ -1427,7 +1458,7 @@ void AliMUONClusterFinderMLEM::FlagLocalMax(TH2D *hist, Int_t i, Int_t j, Int_t
 
   Int_t nx = hist->GetNbinsX();
   Int_t ny = hist->GetNbinsY();
-  Int_t cont = TMath::Nint (hist->GetCellContent(j,i));
+  Int_t cont = TMath::Nint (hist->GetBinContent(hist->GetBin(j,i)));
   Int_t cont1 = 0, indx = (i-1)*nx+j-1, indx1 = 0, indx2 = 0;
 
   Int_t ie = i + 2, je = j + 2;
@@ -1438,7 +1469,7 @@ void AliMUONClusterFinderMLEM::FlagLocalMax(TH2D *hist, Int_t i, Int_t j, Int_t
       if (j1 < 1 || j1 > nx) continue;
       if (i == i1 && j == j1) continue;
       indx2 = indx1 + j1 - 1;
-      cont1 = TMath::Nint (hist->GetCellContent(j1,i1));
+      cont1 = TMath::Nint (hist->GetBinContent(hist->GetBin(j1,i1)));
       if (cont < cont1) { isLocalMax[indx] = -1; return; }
       else if (cont > cont1) isLocalMax[indx2] = -1;
       else { // the same charge
@@ -1456,7 +1487,7 @@ void AliMUONClusterFinderMLEM::FlagLocalMax(TH2D *hist, Int_t i, Int_t j, Int_t
 
 //_____________________________________________________________________________
 void AliMUONClusterFinderMLEM::FindCluster(AliMUONCluster& cluster, 
-                                           Int_t *localMax, Int_t iMax)
+                                           const Int_t *localMax, Int_t iMax)
 {
 /// Find pixel cluster around local maximum \a iMax and pick up pads
 /// overlapping with it
@@ -1484,7 +1515,7 @@ void AliMUONClusterFinderMLEM::FindCluster(AliMUONCluster& cluster,
   Double_t wy = fHistAnode->GetYaxis()->GetBinWidth(1)/2;  
   Double_t yc = fHistAnode->GetYaxis()->GetBinCenter(ic);
   Double_t xc = fHistAnode->GetXaxis()->GetBinCenter(jc);
-  Double_t cont = fHistAnode->GetCellContent(jc,ic);
+  Double_t cont = fHistAnode->GetBinContent( fHistAnode->GetBin(jc,ic));
   fPixArray->Add(new AliMUONPad (xc, yc, wx, wy, cont));
   used[(ic-1)*nx+jc-1] = kTRUE;
   AddBinSimple(fHistAnode, ic, jc);
@@ -1535,15 +1566,15 @@ AliMUONClusterFinderMLEM::AddBinSimple(TH2D *hist, Int_t ic, Int_t jc)
   
   Int_t nx = hist->GetNbinsX();
   Int_t ny = hist->GetNbinsY();
-  Double_t cont1, cont = hist->GetCellContent(jc,ic);
+  Double_t cont1, cont = hist->GetBinContent(hist->GetBin(jc,ic));
   AliMUONPad *pixPtr = 0;
   
   Int_t ie = TMath::Min(ic+1,ny), je = TMath::Min(jc+1,nx);
   for (Int_t i = TMath::Max(ic-1,1); i <= ie; ++i) {
     for (Int_t j = TMath::Max(jc-1,1); j <= je; ++j) {
-      cont1 = hist->GetCellContent(j,i);
+      cont1 = hist->GetBinContent(hist->GetBin(j,i));
       if (cont1 > cont) continue;
-      if (cont1 < 0.5) continue;
+      if (cont1 < fLowestPixelCharge) continue;
       pixPtr = new AliMUONPad (hist->GetXaxis()->GetBinCenter(j), 
                               hist->GetYaxis()->GetBinCenter(i), 0, 0, cont1);
       fPixArray->Add(pixPtr);
@@ -1583,19 +1614,19 @@ void AliMUONClusterFinderMLEM::AddVirtualPad(AliMUONCluster& cluster)
   Bool_t same = kFALSE;
   if (TMath::Abs(dim0.Y()-dim1.Y()) < fgkDistancePrecision) same = kTRUE; // the same pad size on both planes 
 
-  AliMpIntPair cn;
+  Long_t cn;
   Bool_t check[2] = {kFALSE, kFALSE};
   Int_t nxy[2];
   nxy[0] = nxy[1] = 0;
   for (Int_t inb = 0; inb < 2; ++inb) {
     cn = cluster.NofPads(nonb[inb], 0, kTRUE);
-    if (inb == 0 && cn.GetFirst() == 2) check[inb] = kTRUE; // check non-bending plane
-    else if (inb == 1 && cn.GetSecond() == 2) check[inb] = kTRUE; // check bending plane
+    if (inb == 0 && AliMp::PairFirst(cn) == 2) check[inb] = kTRUE; // check non-bending plane
+    else if (inb == 1 && AliMp::PairSecond(cn) == 2) check[inb] = kTRUE; // check bending plane
     if (same) {
-      nxy[0] = TMath::Max (nxy[0], cn.GetFirst());
-      nxy[1] = TMath::Max (nxy[1], cn.GetSecond());
+      nxy[0] = TMath::Max (nxy[0], AliMp::PairFirst(cn));
+      nxy[1] = TMath::Max (nxy[1], AliMp::PairSecond(cn));
       if (inb == 0 && nxy[0] < 2) nonb[inb] = !nonb[inb];
-      else if (inb == 1 && cn.GetSecond() < 2) nonb[inb] = !nonb[inb];
+      else if (inb == 1 && AliMp::PairSecond(cn) < 2) nonb[inb] = !nonb[inb];
     }
   }
   if (same) {
@@ -1657,17 +1688,16 @@ void AliMUONClusterFinderMLEM::AddVirtualPad(AliMUONCluster& cluster)
       TVector2 pos;
       if (inb == 0) pos.Set (pad->X() + idir * (pad->DX()+fgkDistancePrecision), pad->Y());
       else pos.Set (pad->X(), pad->Y() + idir * (pad->DY()+fgkDistancePrecision));
-      //AliMpPad mppad = fSegmentation[nonb[inb]]->PadByPosition(pos,kTRUE);
-      AliMpPad mppad = fSegmentation[nonb[inb]]->PadByPosition(pos,kFALSE);
+      //AliMpPad mppad = fkSegmentation[nonb[inb]]->PadByPosition(pos,kTRUE);
+      AliMpPad mppad = fkSegmentation[nonb[inb]]->PadByPosition(pos.X(), pos.Y(),kFALSE);
       if (!mppad.IsValid()) continue; // non-existing pad
-      cn = mppad.GetIndices();
-      AliMUONPad muonPad(fDetElemId, nonb[inb], cn.GetFirst(), cn.GetSecond(), 
-                        mppad.Position().X(), mppad.Position().Y(), 
-                        mppad.Dimensions().X(), mppad.Dimensions().Y(), 0);
-      if (inb == 0) muonPad.SetCharge(TMath::Min (amax[j]/100, 5.));
+      AliMUONPad muonPad(fDetElemId, nonb[inb], mppad.GetIx(), mppad.GetIy(), 
+                        mppad.GetPositionX(), mppad.GetPositionY(), 
+                        mppad.GetDimensionX(), mppad.GetDimensionY(), 0);
+      if (inb == 0) muonPad.SetCharge(TMath::Min (amax[j]/100, fLowestPadCharge));
       //else muonPad.SetCharge(TMath::Min (amax[j]/15, fgkZeroSuppression));
-      else muonPad.SetCharge(TMath::Min (amax[j]/15, 6.));
-      if (muonPad.Charge() < 1.) muonPad.SetCharge(1.);
+      else muonPad.SetCharge(TMath::Min (amax[j]/15, fLowestPadCharge));
+      if (muonPad.Charge() < 2.0*fLowestPixelCharge) muonPad.SetCharge(2.0*fLowestPixelCharge);
       muonPad.SetReal(kFALSE);
       if (fDebug) printf(" ***** Add virtual pad in %d direction ***** %f %f %f %3d %3d %f %f \n",
                         inb, muonPad.Charge(), muonPad.X(), muonPad.Y(), muonPad.Ix(), 
@@ -1694,10 +1724,10 @@ void AliMUONClusterFinderMLEM::PadsInXandY(AliMUONCluster& cluster,
        
   Bool_t mustMatch(kTRUE);
 
-  AliMpIntPair cn = cluster.NofPads(statusToTest,mustMatch);
+  Long_t cn = cluster.NofPads(statusToTest,mustMatch);
   
-  nInX = cn.GetFirst();
-  nInY = cn.GetSecond();
+  nInX = AliMp::PairFirst(cn);
+  nInY = AliMp::PairSecond(cn);
 }
 
 //_____________________________________________________________________________
@@ -1761,4 +1791,14 @@ AliMUONClusterFinderMLEM::Print(Option_t* what) const
   }
 }
 
+//_____________________________________________________________________________
+void 
+AliMUONClusterFinderMLEM::SetChargeHints(Double_t lowestPadCharge, Double_t lowestClusterCharge)
+{
+  /// Set some thresholds we use later on in the algorithm
+  fLowestPadCharge=lowestPadCharge;
+  fLowestClusterCharge=lowestClusterCharge;
+  fLowestPixelCharge=fLowestPadCharge/12.0; 
+}
+