]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONSt345SlatSegmentation.cxx
New version of SPD raw-data reconstruction. The format now correponds to the actual...
[u/mrichter/AliRoot.git] / MUON / AliMUONSt345SlatSegmentation.cxx
index ae16aefb12a5ba2746c42ca942536f43f3daa75f..0cec3a047519fd5f02a856dad4a83a0eb53149fc 100644 (file)
 /**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- *                                                                        *
- * Author: The ALICE Off-line Project.                                    *
- * Contributors are mentioned in the code where appropriate.              *
- *                                                                        *
- * Permission to use, copy, modify and distribute this software and its   *
- * documentation strictly for non-commercial purposes is hereby granted   *
- * without fee, provided that the above copyright notice appears in all   *
- * copies and that both the copyright notice and this permission notice   *
- * appear in the supporting documentation. The authors make no claims     *
- * about the suitability of this software for any purpose. It is          *
- * provided "as is" without express or implied warranty.                  *
- **************************************************************************/
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
 
 /* $Id$ */
 
-//*********************************************************
-//  Segmentation classes for slat modules          
-//  This class works with local coordinates
-//  of the slats via the class AliMUONGeometrySegmentation
-//  This class contains the size of the slats and the
-//  and the differents PCB densities. 
-//  (from old AliMUONSegmentationSlatModule)
-//  Gines, Subatech, Nov04
-//  Add electronics mapping
-//  Christian, Subatech, Mai 05
-//*********************************************************
-
-#include <TArrayI.h>
-#include <TArrayF.h>
 #include "AliMUONSt345SlatSegmentation.h"
+#include "AliMUONConstants.h"
+
+#include "AliMpArea.h"
+#include "AliMpSlat.h"
+#include "AliMpSlatSegmentation.h"
+#include "AliMpPCB.h" 
+// FIXME: we should not need access to PCB at this level
+// if the Dpx, Dpy, Sector interface would not be used.
+// Investigate instead to direct use of AliMpVSegmentation and AliMpPad
+// from the clusterFinder ? // :aphecetc:20050722 
+// or, or ... have the AliMpSlat handles the notion of zone, finally
+// (where "zone" in mapping is equivalent to "sector" here), and thus
+// let AliMpSlat offer the interface to get information similar to what
+// Dpx, Dpy, Sector offer now to the clustering. That indeed should be
+// handled directly at the level of AliMpVSegmentation...
+#include "AliMpVPadIterator.h"
+
 #include "AliLog.h"
 
+#include "Riostream.h"
+
+/// \cond CLASSIMP
 ClassImp(AliMUONSt345SlatSegmentation)
+/// \endcond
 
+namespace
+{
+  Float_t FMAX(1E9);
+}
+
+//_____________________________________________________________________________
+AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation()
+: AliMUONVGeometryDESegmentation(),
+fDetElemId(-1),
+fPlaneType(kBendingPlane),
+fSlat(0),
+fSlatSegmentation(0),
+fPadIterator(0),
+fCurrentPad(),
+fXhit(FMAX),
+fYhit(FMAX)
+{
+/// Default ctor
 
-AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation() 
-  :     AliMUONVGeometryDESegmentation(),
-       fBending(0),
-       fId(0),
-        fNsec(0),
-        fNDiv(0),
-        fDpxD(0),
-        fDpyD(0),
-       fDpx(0),
-       fDpy(0),
-       fNpx(999999),
-       fNpy(999999),
-       fWireD(0.0),
-       fXhit(0.),
-       fYhit(0.),
-       fIx(0),
-       fIy(0),
-       fX(0.),
-       fY(0.),
-       fIxmin(0),
-       fIxmax(0),
-       fIymin(0),
-        fIymax(0),
-       fInitDone(kFALSE)
-{
-  // default constructor
        AliDebug(1,Form("this=%p default (empty) ctor",this));
 }
 
-//___________________________________________
-AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(Bool_t bending) 
-  :     AliMUONVGeometryDESegmentation(),
-       fBending(bending),
-       fId(0),
-        fNsec(0),
-        fNDiv(0),
-        fDpxD(0),
-        fDpyD(0),
-       fDpx(0),
-       fDpy(0),
-       fNpx(999999),
-       fNpy(999999),
-       fWireD(0.25),
-       fXhit(0.),
-       fYhit(0.),
-       fIx(0),
-       fIy(0),
-       fX(0.),
-       fY(0.),
-       fIxmin(0),
-       fIxmax(0),
-       fIymin(0),
-       fIymax(0),
-       fInitDone(kFALSE)
-
-{
-  // Non default constructor
-  fNsec = 4;  // 4 sector densities at most per slat 
-  fNDiv = new TArrayI(fNsec);      
-  fDpxD = new TArrayF(fNsec);      
-  fDpyD = new TArrayF(fNsec);      
-  (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;     
-  (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;       
-  (*fDpyD)[0]=(*fDpyD)[1]=(*fDpyD)[2]=(*fDpyD)[3]=0;   
-  AliDebug(1,Form("this=%p ctor for bending=%d",this,fBending)); 
-
-}
-//----------------------------------------------------------------------
-AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(const AliMUONSt345SlatSegmentation& rhs) 
-:       AliMUONVGeometryDESegmentation(rhs),
-       fBending(0),
-       fId(0),
-       fDpx(0),
-       fDpy(0),
-       fNpx(999999),
-       fNpy(999999),
-       fWireD(0.25),
-       fXhit(0.),
-       fYhit(0.),
-       fIx(0),
-       fIy(0),
-       fX(0.),
-       fY(0.),
-       fIxmin(0),
-       fIxmax(0),
-       fIymin(0),
-       fIymax(0)
-{
-               AliFatal("Not implemented");
-}
-//----------------------------------------------------------------------
-AliMUONSt345SlatSegmentation::~AliMUONSt345SlatSegmentation() 
-{
-  // Destructor
-
-  AliDebug(1, Form("dtor this = %p", this));
-
-  delete fNDiv;
-  delete fDpxD;
-  delete fDpyD;
-}
-//----------------------------------------------------------------------
-AliMUONSt345SlatSegmentation& AliMUONSt345SlatSegmentation::operator=(const AliMUONSt345SlatSegmentation& rhs)
-{
-  // Protected assignement operator
-  if (this == &rhs) return *this;
-  AliFatal("Not implemented.");
-  return *this;  
-}
-
-
-//------------------------------------------------------------------------
-Float_t AliMUONSt345SlatSegmentation::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t * /*dummy*/)
-{
-  // Returns the square of the distance between 1 pad
-  // labelled by its Channel numbers and a coordinate
-  Float_t x,y;
-  GetPadC(iX,iY,x,y);
-  return (x-X)*(x-X) + (y-Y)*(y-Y);
-}
-//____________________________________________________________________________
-Float_t AliMUONSt345SlatSegmentation::Dpx(Int_t isec) const
-{
-  // Return x-strip width
-  return (*fDpxD)[isec];
-} 
-
-//____________________________________________________________________________
-Float_t AliMUONSt345SlatSegmentation::Dpy(Int_t  isec) const
-{
-  // Return y-strip width
-  return (*fDpyD)[isec];
-}
-//_____________________________________________________________________________
-Float_t AliMUONSt345SlatSegmentation::GetAnod(Float_t xhit) const
-{
-  // Returns for a hit position xhit the position of the nearest anode wire    
-  Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5;
-  return fWireD*wire;
+//_____________________________________________________________________________
+AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(
+                                   AliMpVSegmentation* segmentation,
+                                   Int_t detElemId, AliMpPlaneType bendingOrNonBending)
+: AliMUONVGeometryDESegmentation(),
+fDetElemId(detElemId),
+fPlaneType(bendingOrNonBending),
+fSlat(0),
+fSlatSegmentation(0),
+fPadIterator(0),
+fCurrentPad(),
+fXhit(FMAX),
+fYhit(FMAX)
+{ 
+/// Normal ctor.
+
+  fSlatSegmentation = dynamic_cast<AliMpSlatSegmentation*>(segmentation);
+  if (fSlatSegmentation)
+    fSlat = fSlatSegmentation->Slat();
+  else 
+    AliFatal("Wrong mapping segmentation type");
+               
+  AliDebug(1,Form("this=%p detElemId=%3d %s fSlatSegmentation=%p",this,detElemId,
+                                                                       ( (bendingOrNonBending==kBendingPlane)?"Bending":"NonBending" ),
+                                                                       fSlatSegmentation));
+}
+
+//_____________________________________________________________________________
+AliMUONSt345SlatSegmentation::~AliMUONSt345SlatSegmentation()
+{
+/// Destructor
+
+       AliDebug(1,Form("dtor this=%p",this));
+  delete fPadIterator;
+}
+
+//_____________________________________________________________________________
+TF1*
+AliMUONSt345SlatSegmentation::CorrFunc(Int_t /*isec*/) const
+{
+/// Not implemented
+
+  AliFatal("Not Implemented");
+  return 0x0;
+}
+
+//_____________________________________________________________________________
+Float_t 
+AliMUONSt345SlatSegmentation::Distance2AndOffset(Int_t /*iX*/, Int_t /*iY*/, 
+                                 Float_t /*x*/, Float_t /*y*/, Int_t* /*dummy*/){
+/// Not implemented
+
+  AliFatal("Not Implemented");
+  return 0.0;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::Draw(Option_t* /*opt*/)
+{
+/// Not implemented
+
+  AliFatal("Not Implemented");
+}
+
+//_____________________________________________________________________________
+Float_t
+AliMUONSt345SlatSegmentation::Dpx() const
+{
+/// Not implemented
+
+  AliFatal("Not Implemented");
+  return 0.0;
 }
 
 //_____________________________________________________________________________
-Bool_t AliMUONSt345SlatSegmentation::HasPad(Int_t ix, Int_t iy)
+Float_t
+AliMUONSt345SlatSegmentation::Dpy() const
 {
-       if ( ix < 1 || ix > Npx() || iy < 1 || iy > Npy() )
+/// Not implemented
+
+  AliFatal("Not Implemented");
+  return 0.0;
+}
+
+//_____________________________________________________________________________
+Float_t
+AliMUONSt345SlatSegmentation::Dpx(int ipcb) const
+{
+/// Get pad size in x
+
+       AliMpPCB* pcb = fSlat->GetPCB(ipcb);
+       if (!pcb) 
+  {
+    AliFatal("pcb is null!");
+  }
+       return pcb->PadSizeX();
+}
+
+//_____________________________________________________________________________
+Float_t
+AliMUONSt345SlatSegmentation::Dpy(int ipcb) const
+{
+/// Get pad size in y
+
+       AliMpPCB* pcb = fSlat->GetPCB(ipcb);
+       if (!pcb) 
+  {
+    AliFatal("pcb is null!");
+  }
+       return pcb->PadSizeY();
+}
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit,Float_t /*zhit*/,
+                                         Float_t dx, Float_t dy)
+{
+/// OK. We will do it in 2 steps. First get the area over which to
+/// iterate, based on hit coordinates and (dx,dy). This first step
+/// has nothing to do with segmentation in the first place, but with
+/// how we simulate the fact that at some point the charge is shared
+/// amongst several pads.
+/// The second step is the actual pad iteration and is handled by 
+/// a specific class (which has to do only with iteration...)
+///
+/// \todo FIXME: this method should not be here in the first place, IMHO.
+       
+  // Find the wire position (center of charge distribution)
+  Float_t xwire = GetAnod(xhit);
+  fXhit = xwire;
+  fYhit = yhit;
+       
+  Double_t x01 = xwire - dx;
+  Double_t x02 = xwire + dx;
+  Double_t y01 = yhit - dy;
+  Double_t y02 = yhit + dy;
+       
+  Double_t xext = x02 - x01;
+  Double_t yext = y02 - y01;
+       
+  // we do not check area here, as we assume the iterator
+  // will do it, and will possibly truncate it if needed.
+  // Note that we convert the area position to a reference frame
+  // located in the lower-left corner of the slat, instead of its
+  // center.
+//  AliMpArea area(TVector2((x01+x02)/2.0+fSlat->DX(),
+//                                                                                                     (y01+y02)/2.0+fSlat->DY()),
+//                                                              TVector2(xext/2.0,yext/2.0));
+  AliMpArea area(TVector2((x01+x02)/2.0,(y01+y02)/2.0),
+                                                                TVector2(xext/2.0,yext/2.0));
+       
+  delete fPadIterator;
+       
+  fPadIterator = fSlatSegmentation->CreateIterator(area);
+       
+  fPadIterator->First();
+       
+  fCurrentPad = fPadIterator->CurrentItem();
+       
+  if ( !fCurrentPad.IsValid() ) 
        {
-               return kFALSE;
+               AliError(Form("Cannot get a valid pad for (xhit,yhit,dx,dy)=(%e,%e,%e,%e)",xhit,yhit,dx,dy));
        }
-       Int_t isec = Sector(ix,iy);
-       if ( isec == -1 )
+       
+  AliDebug(4,Form("xhit,yhit,dx,dy=%e,%e,%e,%e ix,iy=%3d,%3d slat=%s",
+                                                                       xhit,yhit,dx,dy,
+                                                                       fCurrentPad.GetIndices().GetFirst(),
+                                                                       fCurrentPad.GetIndices().GetSecond(),fSlat->GetID()));            
+}
+
+//_____________________________________________________________________________
+Float_t
+AliMUONSt345SlatSegmentation::GetAnod(Float_t xhit) const
+{
+/// Gets the x-coordinate of the wire which is the closest to xhit.
+       
+  Int_t n = Int_t(xhit/AliMUONConstants::Pitch());
+  Float_t wire = (xhit>0) ? n+0.5 : n-0.5;
+  return AliMUONConstants::Pitch()*wire;
+}
+
+//_____________________________________________________________________________
+AliMUONGeometryDirection
+AliMUONSt345SlatSegmentation::GetDirection()
+{
+/// Not implemented
+
+  //AliWarning("Not Implemented");
+  return kDirUndefined;
+}
+
+//______________________________________________________________________________
+const AliMpVSegmentation*  
+AliMUONSt345SlatSegmentation::GetMpSegmentation() const
+{
+/// Returns the mapping segmentation
+/// (provides access to electronics info)
+
+  return fSlatSegmentation;
+}  
+
+
+//_____________________________________________________________________________
+void 
+AliMUONSt345SlatSegmentation::GetNParallelAndOffset(Int_t /*iX*/, Int_t /*iY*/,
+                                        Int_t* /*Nparallel*/, Int_t* /*Offset*/)
+{
+/// Not implemented
+
+  AliFatal("Not Implemented");
+}
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy, 
+                                        Float_t& x, Float_t& y, Float_t& z)
+{                                       
+/// Transform from pad to real coordinates
+
+  z = 0;
+  GetPadC(ix,iy,x,y);
+}
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy, 
+                                        Float_t& x, Float_t& y)
+{
+/// Transform from pad to real coordinates
+
+  AliMpPad pad = 
+  fSlatSegmentation->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
+  x = pad.Position().X();
+  y = pad.Position().Y();
+}
+
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y, Float_t /*z*/,
+Int_t& ix, Int_t& iy)
+{
+///  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
+
+  GetPadI(x,y,ix,iy);
+}
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y,
+                                        Int_t& ix, Int_t& iy)
+{
+///  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
+
+  AliMpPad pad = fSlatSegmentation->PadByPosition(TVector2(x,y), kTRUE);
+       
+  if ( pad != AliMpPad::Invalid() )
        {
-               return kFALSE;
+               ix = pad.GetIndices().GetFirst();
+               iy = pad.GetIndices().GetSecond();
        }
-       if ( iy > fNpyS[isec] )
+  else
        {
-               return kFALSE;
+               ix = iy = -1;
        }
-       return kTRUE;
-}
-
-//--------------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y) 
-{
-  if (ix < 1 || ix > Npx() || iy < 1 || iy > Npy() ){
-    AliWarning(Form("ix %d or iy %d out of boundaries: Npx=%d and Npy=%d",ix, iy, Npx(), Npy()));
-    x = y= 0.;
-
-  } else { 
-
-    //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
-    //  Find sector isec
-    Int_t isec = Sector(ix,iy);
-    if (isec == -1) AliWarning(Form("isector = %d  with ix %d, iy %d", isec, ix, iy));
-    if (iy > fNpyS[isec]) {
-      x = y = 0.;
-      return;
-    }
-    if (isec>0) {
-      x = fCx[isec-1]+(ix-fNpxS[isec-1])*(*fDpxD)[isec];
-      x = x-(*fDpxD)[isec]/2;
-      y = Float_t(iy*(*fDpyD)[isec])-(*fDpyD)[isec]/2.- fCy;  // !!!  
-    } else {
-      x = y = 0;
-    }
-  }
 }
 
+//_____________________________________________________________________________
+void 
+AliMUONSt345SlatSegmentation::GiveTestPoints(Int_t& /*n*/, 
+                                    Float_t* /*x*/, Float_t* /*y*/) const
+{
+/// Not implemented
+
+  AliFatal("Not Implemented");
+}
 
 //_____________________________________________________________________________
-void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy) 
+Bool_t
+AliMUONSt345SlatSegmentation::HasPad(Float_t x, Float_t y, Float_t z)
 {
-//  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
+/// Returns true if a pad exists in the given position
 
-  //  Find sector isec    
-  Int_t isec=-1;
-  for (Int_t i=fNsec-1; i > 0; i--) {
-    if (x >= fCx[i-1]) {
-      isec=i;
-      if (TMath::Abs(fCx[isec] - fCx[isec-1]) <0.1  && isec > 1) isec--;
-      break;
-    }
-  }
-  if (isec == -1) AliWarning(Form("isector equal to %d  with xl %f, yl %f", isec, x, y));
-  if (isec>0) {
-    ix= Int_t((x-fCx[isec-1])/(*fDpxD)[isec])
-      +fNpxS[isec-1]+1;
-    iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
-  } else if (isec == 0) {
-    ix= Int_t(x/(*fDpxD)[isec])+1;
-    iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
-  } else {
-    ix=0;
-    iy=0;
-  }
+  Int_t ix, iy;
+  GetPadI(x,y,z,ix,iy);
+  return HasPad(ix,iy);
 }
-//-------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONSt345SlatSegmentation::HasPad(Int_t ix, Int_t iy)
+{
+/// Returns true if a pad with given indices exists
+
+  return fSlatSegmentation->HasPad(AliMpIntPair(ix,iy));
+}
+
+//_____________________________________________________________________________
+void  
+AliMUONSt345SlatSegmentation::IntegrationLimits(Float_t& x1, Float_t& x2,
+                                                  Float_t& y1, Float_t& y2)
 {
-  GetPadI(x, y, ix, iy);
+///  Returns integration limits for current pad
+       
+       //   x1 = fXhit - fX - Dpx(fSector)/2.;
+       //   x2 = x1 + Dpx(fSector);
+       //   y1 = fYhit - fY - Dpy(fSector)/2.;
+       //   y2 = y1 + Dpy(fSector);    
+       
+  Float_t x = fCurrentPad.Position().X();
+  Float_t y = fCurrentPad.Position().Y();
+       
+  Float_t padsizex = fCurrentPad.Dimensions().X() * 2.0;
+  Float_t padsizey = fCurrentPad.Dimensions().Y() * 2.0;
+       
+  x1 = fXhit - x - padsizex/2.0;
+  x2 = x1 + padsizex;
+  y1 = fYhit - y - padsizey/2.0;
+  y2 = y1 + padsizey;
+       
+  AliDebug(4,Form("xhit,yhit=%e,%e x,y=%e,%e, x1,x2,y1,y2=%e,%e,%e,%e",fXhit,fYhit,x,y,x1,x2,y1,y2));
 }
 
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::ISector()
+{
+/// \todo FIXME: remove the usage of ISector from all the code.
 
-//_______________________________________________________________
-void AliMUONSt345SlatSegmentation::SetPadDivision(Int_t ndiv[4])
+  return -10;
+}
+
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Ix()
 {
-  // Defines the pad size perp. to the anode wire (y) for different sectors. 
-  // Pad sizes are defined as integral fractions ndiv of a basis pad size
-  // fDpx
-  // 
-  for (Int_t i=0; i<4; i++) {
-    (*fNDiv)[i]=ndiv[i];
-  }
-  ndiv[0]=ndiv[1];
+/// Current pad cursor during disintegration
+/// x, y-coordinate
+
+  if ( fPadIterator )
+       {
+               return fPadIterator->CurrentItem().GetIndices().GetFirst();
+       }
+  else
+       {
+               return -1;
+       }
 }
-//____________________________________________________________________________
-void AliMUONSt345SlatSegmentation::SetPadSize(Float_t p1, Float_t p2)
+
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Iy()
 {
-  //  Sets the padsize 
-  fDpx=p1;
-  fDpy=p2;
+/// Current pad cursor during disintegration
+/// x, y-coordinate
+
+  if ( fPadIterator ) 
+       {
+               return fPadIterator->CurrentItem().GetIndices().GetSecond();
+       }
+  else
+       {
+               return -1;
+       }
 }
-//_______________________________________________________________          
-void AliMUONSt345SlatSegmentation::SetPcbBoards(Int_t n[4])
+
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::MorePads()
 {
-  //
-  // Set PcbBoard segmentation zones for each density
-  // n[0] slat type parameter
-  // n[1] PcbBoards for highest density sector fNDiv[1] etc ...
+/// Iterate over pads - condition
 
-  fRtype = n[0];
-  n[0] = 0;
-  for (Int_t i=0; i<4; i++) fPcbBoards[i]=n[i];
+  return (fPadIterator && !fPadIterator->IsDone());
+}
 
+//_____________________________________________________________________________
+void 
+AliMUONSt345SlatSegmentation::Neighbours(Int_t iX, Int_t iY, Int_t* Nlist,
+                                           Int_t Xlist[10], Int_t Ylist[10])
+{
+/// Find pad at (ix,iy) for which we'll search neighbours.
+
+  AliMpPad pad = 
+       fSlatSegmentation->PadByIndices(AliMpIntPair(iX,iY),kTRUE);
+       
+  // Define the region to look into : a region slightly bigger
+  // than the pad itself (5% bigger), in order to catch first neighbours.
+
+  AliMpArea area(pad.Position(),pad.Dimensions()*1.05); 
+               
+  AliMpVPadIterator* it = fSlatSegmentation->CreateIterator(area);
+  it->First();
+  Int_t n = 0;
+  while ( !it->IsDone() && n < 10 )
+       {
+               AliMpPad p = it->CurrentItem();
+               if ( p != pad ) // skip self
+               {
+                       Xlist[n] = p.GetIndices().GetFirst();
+                       Ylist[n] = p.GetIndices().GetSecond();
+                       ++n;
+               }
+               it->Next();
+       }
+       delete it;
+  *Nlist = n;
 }
-//-------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::SetPad(Int_t ix, Int_t iy)
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::NextPad()
 {
-  //
-  // Sets virtual pad coordinates, needed for evaluating pad response 
-  // outside the tracking program 
-  GetPadC(ix,iy,fX,fY);
-  fSector=Sector(ix,iy);
+/// Iterate over pads - stepper
+
+  if ( fPadIterator )
+       {
+               fPadIterator->Next();
+               fCurrentPad = fPadIterator->CurrentItem();
+       }
+  else
+       {
+               AliError("PadIterator not initialized. Please use First() first ;-)");
+       }
 }
-//---------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::SetHit(Float_t x, Float_t y)
+
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Npx() const
 {
-  // Set current hit 
-  //
-  fXhit = x;
-  fYhit = y;
-    
-  if (x <  fCx[0])    fXhit = fCx[0];
-  if (y < -fDyPCB/2.) fYhit = -fDyPCB/2.;
-    
-  if (x > fCx[fNsec-1]) fXhit = fCx[fNsec-1];
-  if (y > fDyPCB/2.)    fYhit = fDyPCB/2.;
-    
-}
-//----------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
-{
-  SetHit(xhit, yhit);
-}
-
-//----------------------------------------------------------
-void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
-{
-// Initialises iteration over pads for charge distribution algorithm
-//
-    //
-    // Find the wire position (center of charge distribution)
-    Float_t x0a = GetAnod(xhit);
-    fXhit = x0a;
-    fYhit = yhit;
-    //
-    // and take fNsigma*sigma around this center
-    Float_t x01 = x0a  - dx ;
-    Float_t x02 = x0a  + dx;
-    Float_t y01 = yhit - dy;
-    Float_t y02 = yhit + dy;
-
-    // check the limits after adding (fNsigma*sigma)
-    if (x01 <  fCx[0])   x01 =  fCx[0];
-    if (y01 < -fDyPCB/2) y01 = -fDyPCB/2;
-
-    if (x02 >= fCx[fNsec-1]) x02 = fCx[fNsec-1]; // still ok ? (CF)
-    if (y02 >= fDyPCB/2.) y02 = fDyPCB/2.;
-
-   
-    Int_t isec=-1;
-    for (Int_t i=fNsec-1; i > 0; i--) {
-      if (x02 >= fCx[i-1]) {
-       isec=i;
-       if (TMath::Abs(fCx[isec] - fCx[isec-1]) < 0.1 && isec > 1) isec--;
-       break;
-      }
-    }
-
-    //    y02 += Dpy(isec);// why ? (CF)
-   
-    //
-    // find the pads over which the charge distributes
-    GetPadI(x01,y01,fIxmin,fIymin);
-    GetPadI(x02,y02,fIxmax,fIymax);
-    
-    if (fIxmax > fNpx) fIxmax=fNpx;
-    if (fIymax > fNpyS[isec]) fIymax = fNpyS[isec];    
-    if (fIxmin < 1) fIxmin = 1;    // patch for the moment (Ch. Finck)
-    if (fIymin < 1) fIymin = 1;    
-
-    fXmin = x01;
-    fXmax = x02;    
-    fYmin = y01;
-    fYmax = y02;    
-  
-    // 
-    // Set current pad to lower left corner
-    if (fIxmax < fIxmin) fIxmax = fIxmin;
-    if (fIymax < fIymin) fIymax = fIymin;    
-    fIx = fIxmin;
-    fIy = fIymin;
-    
-    GetPadC(fIx,fIy,fX,fY);
-    fSector = Sector(fIx,fIy);
-    AliDebug(4,Form("xhit,yhit,dx,dy=%e,%e,%e,%e ix,iy=%3d,%3d",
-                   xhit,yhit,dx,dy,fIx,fIy));
-}
-
-//----------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
-{
-  FirstPad(xhit, yhit, dx, dy);
-}
-//----------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::NextPad()
-{
-  // Stepper for the iteration over pads
-  //
-  // Step to next pad in the integration region
-  //  step from left to right    
-  if (fIx != fIxmax) {
-    fIx++;
-    GetPadC(fIx,fIy,fX,fY);
-    fSector=Sector(fIx,fIy);
-    //  step up 
-  } else if (fIy != fIymax) {
-    fIx=fIxmin;
-    fIy++;
-    GetPadC(fIx,fIy,fX,fY);
-    fSector=Sector(fIx,fIy);
-  } else {
-    fIx=-999;
-    fIy=-999;
-  }
+/// Maximum number of Pads in x
+
+  return fSlatSegmentation->MaxPadIndexX()+1;
 }
-//-------------------------------------------------------------------------
-Int_t AliMUONSt345SlatSegmentation::MorePads()
+
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Npy() const
 {
-  // Stopping condition for the iterator over pads
-  //
-  // Are there more pads in the integration region
-    
-  return  (fIx != -999  || fIy != -999);
+/// Maximum number of Pads in y
+
+  return fSlatSegmentation->MaxPadIndexY()+1;
 }
-//--------------------------------------------------------------------------
-Int_t AliMUONSt345SlatSegmentation::Sector(Int_t ix, Int_t iy) 
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::Print(Option_t* /*opt*/) const
 {
-  //
-  // Determine segmentation zone from pad coordinates
-  //
-  Int_t isec = -1;
-  for (Int_t i = 0; i < fNsec; i++) {
-    if (ix <= fNpxS[i]) {
-      isec = i;
-      break;
-    }
-  }
-  if (isec == -1) AliWarning(Form("Sector = %d  with ix %d and iy %d, Npx %d",
-                                 isec, ix, iy, fNpx));
+/// Printing
 
-  return isec;
+  cout << "DetElemId=" << fDetElemId << " PlaneType=" 
+  << fPlaneType << " Npx,Npy=" << Npx() << "," << Npy() << " fSlat=" << fSlat 
+  << " fSlatSegmentation=" << fSlatSegmentation
+  << " fSlatSegmentation->Slat()=" << fSlatSegmentation->Slat() << endl;
+}
 
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Sector(Int_t ix, Int_t /*iy*/)
+{
+/// Calculate sector from pad coordinates
+
+  return fSlat->FindPCBIndex(ix);
 }
-//-----------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::
-IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) 
+
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Sector(Float_t x, Float_t y)
 {
-  //  Returns integration limits for current pad
-  //
-  x1=fXhit-fX-Dpx(fSector)/2.;
-  x2=x1+Dpx(fSector);
-  y1=fYhit-fY-Dpy(fSector)/2.;
-  y2=y1+Dpy(fSector);    
+/// Calculate sector from pad coordinates
+
+  return fSlat->FindPCBIndex(x,y);
+}
 
-  AliDebug(4,Form("xhit,yhit=%e,%e x,y=%e,%e, x1,x2,y1,y2=%e,%e,%e,%e",fXhit,fYhit,fX,fY,x1,x2,y1,y2));
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::SetCorrFunc(Int_t /*isec*/,TF1* /*func*/)
+{
+/// Not implemented
 
+  AliFatal("Not Implemented");
 }
-//-----------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::
-Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) 
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::SetDAnod(float /*d*/)
 {
-  // Returns list of next neighbours for given Pad (iX, iY)
-  Int_t i=0;
-  //  step right
-  if (iX+1 <= fNpx) {
-    Xlist[i]=iX+1;
-    Ylist[i++]=iY;
-  }
-  //  step left    
-  if (iX-1 > 0) {
-    Xlist[i]=iX-1;
-    Ylist[i++]=iY;
-  } 
-  Int_t sector = Sector(iX,iY);
-  //  step up
-  if (iY+1 <= fNpyS[sector]) {
-    Xlist[i]=iX;
-    Ylist[i++]=iY+1;
-  }
-  //  step down    
-  if (iY-1 > 0) {
-    Xlist[i]=iX;
-    Ylist[i++]=iY-1;
-  }
-  *Nlist=i;
+/// Not implemented
+
+  AliFatal("Not Implemented");
 }
 
-//--------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::Init(Int_t detectionElementId)
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::SetHit(Float_t x, Float_t y, Float_t)
 {
+/// Set hit position
+/// Sets virtual hit position, needed for evaluating pad response 
+/// outside the tracking program 
+
+  fXhit = x;
+  fYhit = y;
+       
   //
-  //  Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
-  //  These arrays help in converting from real to pad co-ordinates and
-  //  vice versa
-  //   
-  //  Segmentation is defined by rectangular modules approximating
-  //  concentric circles as shown below
-  //
-  //  PCB module size in cm
-  //  printf("\n Initialise Segmentation SlatModule \n");
-
-  
-  //  printf(" fBending: %d \n",fBending);
-
-  if (fInitDone) return; // security if init is already done in AliMUONFactory
-  fDxPCB=40;
-  fDyPCB=40;
-
-  //  Calculate padsize along x
-  (*fDpxD)[fNsec-1]=fDpx;
-  (*fDpyD)[fNsec-1]=fDpy;
-  if (fNsec > 1) {
-    for (Int_t i=fNsec-1; i>=0; i--){ // fNsec-2
-      if (!fBending) {
-       (*fDpxD)[i]=fDpx;
-       (*fDpyD)[i]=(*fDpyD)[fNsec-1]/(*fNDiv)[i];
-      } else {
-       (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
-       (*fDpyD)[i]=fDpy;
-      }
-    }
-  }
-  //
-  // fill the arrays defining the pad segmentation boundaries
-  //
-  //  
-  //  Loop over sectors (isec=0 for secto close to the beam pipe)
-  Float_t totalLength = 0;
-  for (Int_t isec=0; isec<4; isec++) totalLength += fPcbBoards[isec]*fDxPCB;  // !!!!
-
-  fNpy = 0;   // maximum number of pads in y
-  for (Int_t isec=0; isec<4; isec++) {
-    if (isec==0) {
-      fNpxS[0] = 0;
-      fNpyS[0] = 0;
-      fCx[0]   = -totalLength/2;
-    } else {
-      fNpxS[isec] = fNpxS[isec-1] + fPcbBoards[isec]*Int_t(fDxPCB/(*fDpxD)[isec]+0.5); 
-      fNpyS[isec] = Int_t(fDyPCB/(*fDpyD)[isec]+0.5);
-      if (fNpyS[isec] >= fNpy) fNpy = fNpyS[isec]; 
-      fCx[isec]= fCx[isec-1] + fPcbBoards[isec]*fDxPCB;
-    }
-  } // sectors
-
-  fNpx = fNpxS[3];  // maximum number of pads in x
-  fCy = fDyPCB/2.;
+  // insure we're within the slat limits. If not, issue a simple
+  // warning, as this might be correct (due to clustering/fitting algorithm
+  // that is allowed to go a little bit outside limits).
+  // That should only be considered an error in case the point is way
+  // outside (but by how much is the question you'll have to determine
+  // by yourself...)
   //
-  fId = detectionElementId;
+  if ( fXhit < -fSlat->DX() || fXhit > fSlat->DX() ||
+       fYhit < -fSlat->DY() || fYhit > fSlat->DY() )
+       {
+    Double_t dx = - fSlat->DX() + TMath::Abs(fXhit);
+    Double_t dy = - fSlat->DY() + TMath::Abs(fYhit);
+    dx = ( dx > 0 ? dx : 0);
+    dy = ( dy > 0 ? dy : 0);
+               AliWarning(Form("Hit outside slat %s limits (x,y)hit = (%e,%e). "
+                    "Outside by (%e,%e) cm. Might be ok though.",
+                    fSlat->GetID(),fXhit,fYhit,dx,dy));
+       }  
+}
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::SetPad(Int_t ix, Int_t iy)
+{
+/// Set pad position.
+/// Sets virtual pad coordinates, needed for evaluating pad response 
+/// outside the tracking program.
+
+  fCurrentPad = 
+       fSlatSegmentation->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
+  if ( !fCurrentPad.IsValid() )
+       {
+               AliError(Form("Setting current pad to invalid ! (ix,iy)=(%4d,%4d)",ix,iy));
+       }
+}
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::SetPadSize(float /*p1*/,float /*p2*/)
+{
+/// Not implemented
+
+  AliFatal("Not Implemented");
+}
+
+//_____________________________________________________________________________
+Int_t 
+AliMUONSt345SlatSegmentation::SigGenCond(Float_t /*x*/, Float_t /*y*/, Float_t /*z*/)
+{
+/// Not implemented
+
+  AliFatal("Not Implemented");
+  return 0;
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONSt345SlatSegmentation::SigGenInit(Float_t,Float_t,Float_t)
+{
+/// Not implemented
 
-  fInitDone = kTRUE;
+  AliFatal("Not Implemented");
 }