/**************************************************************************
- * 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
-//*********************************************************
-
-#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(),
- fBending(0),
- fId(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)
+//_____________________________________________________________________________
+AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation()
+: AliMUONVGeometryDESegmentation(),
+fDetElemId(-1),
+fPlaneType(AliMp::kBendingPlane),
+fSlat(0),
+fSlatSegmentation(0),
+fPadIterator(0),
+fCurrentPad(),
+fXhit(FMAX),
+fYhit(FMAX)
{
- // default constructor
+/// Default ctor
+ AliDebug(1,Form("this=%p default (empty) ctor",this));
}
-//___________________________________________
-AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(Bool_t bending)
- : AliMUONVGeometryDESegmentation(),
- fBending(bending),
- 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)
+//_____________________________________________________________________________
+AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(
+ AliMpVSegmentation* segmentation,
+ Int_t detElemId, AliMp::PlaneType 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==AliMp::kBendingPlane)?"Bending":"NonBending" ),
+ fSlatSegmentation));
+}
+
+//_____________________________________________________________________________
+AliMUONSt345SlatSegmentation::~AliMUONSt345SlatSegmentation()
{
- // 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;
+/// Destructor
+
+ AliDebug(1,Form("dtor this=%p",this));
+ delete fPadIterator;
}
-//----------------------------------------------------------------------
-AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(const AliMUONSt345SlatSegmentation& rhs) : AliMUONVGeometryDESegmentation(rhs)
+
+//_____________________________________________________________________________
+TF1*
+AliMUONSt345SlatSegmentation::CorrFunc(Int_t /*isec*/) const
{
- AliFatal("Not implemented.");
+/// 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;
}
-//----------------------------------------------------------------------
-AliMUONSt345SlatSegmentation::~AliMUONSt345SlatSegmentation()
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::Draw(Option_t* /*opt*/)
{
- // Destructor
- if (fNDiv) delete fNDiv;
- if (fDpxD) delete fDpxD;
- if (fDpyD) delete fDpyD;
+/// Not implemented
+
+ AliFatal("Not Implemented");
}
-//----------------------------------------------------------------------
-AliMUONSt345SlatSegmentation& AliMUONSt345SlatSegmentation::operator=(const AliMUONSt345SlatSegmentation& rhs)
+
+//_____________________________________________________________________________
+Float_t
+AliMUONSt345SlatSegmentation::Dpx() const
{
- // Protected assignement operator
- if (this == &rhs) return *this;
- AliFatal("Not implemented.");
- return *this;
+/// Not implemented
+
+ AliFatal("Not Implemented");
+ return 0.0;
}
+//_____________________________________________________________________________
+Float_t
+AliMUONSt345SlatSegmentation::Dpy() const
+{
+/// Not implemented
+
+ AliFatal("Not Implemented");
+ return 0.0;
+}
-//------------------------------------------------------------------------
-Float_t AliMUONSt345SlatSegmentation::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t * /*dummy*/)
+//_____________________________________________________________________________
+Float_t
+AliMUONSt345SlatSegmentation::Dpx(int ipcb) const
{
- // 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);
+/// Get pad size in x
+
+ AliMpPCB* pcb = fSlat->GetPCB(ipcb);
+ if (!pcb)
+ {
+ AliFatal("pcb is null!");
+ }
+ return pcb->PadSizeX();
}
-//____________________________________________________________________________
-Float_t AliMUONSt345SlatSegmentation::Dpx(Int_t isec) const
+
+//_____________________________________________________________________________
+Float_t
+AliMUONSt345SlatSegmentation::Dpy(int ipcb) const
{
- // Return x-strip width
- return (*fDpxD)[isec];
-}
+/// Get pad size in y
+
+ AliMpPCB* pcb = fSlat->GetPCB(ipcb);
+ if (!pcb)
+ {
+ AliFatal("pcb is null!");
+ }
+ return pcb->PadSizeY();
+}
-//____________________________________________________________________________
-Float_t AliMUONSt345SlatSegmentation::Dpy(Int_t isec) const
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit,Float_t /*zhit*/,
+ Float_t dx, Float_t dy)
{
- // Return y-strip width
- return (*fDpyD)[isec];
+/// 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() )
+ {
+ AliError(Form("Cannot get a valid pad for (xhit,yhit,dx,dy)=(%e,%e,%e,%e)",xhit,yhit,dx,dy));
+ }
+
+ 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
-{
- // 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;
+
+//_____________________________________________________________________________
+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;
+}
-//--------------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
+//______________________________________________________________________________
+const AliMpVSegmentation*
+AliMUONSt345SlatSegmentation::GetMpSegmentation() const
{
- if (ix<1 || ix>Npx() || iy<1 || iy>Npy() ){
- AliWarning(Form("ix or iy out of boundaries: Npx=%d and Npy=%d",Npx(),Npy()));
- x=-99999.; y=-99999.;
- }
- else {
- // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
- // Find sector isec
- Int_t isec = Sector(ix,iy);
- if (isec == -1) printf("\n PadC %d %d %d %d \n ", isec, fId, ix, iy);
- if (iy > fNpyS[isec]) {
- x=-99999.; y=-99999.;
- 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;
- }
- }
+/// 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::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
+void
+AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy,
+ Float_t& x, Float_t& y)
{
-// Returns pad coordinates (ix,iy) for given real coordinates (x,y)
-
- // Find sector isec
- Int_t isec=-1;
- for (Int_t i=fNsec-1; i > 0; i--) {
- if (x >= fCx[i-1]) {
- isec=i;
- if (fCx[isec] == fCx[isec-1] && isec > 1) isec--;
- break;
- }
- }
-
- 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;
- }
+/// 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)
+
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y, Float_t /*z*/,
+Int_t& ix, Int_t& iy)
{
- GetPadI(x, y, ix, iy);
+/// Returns pad coordinates (ix,iy) for given real coordinates (x,y)
+
+ GetPadI(x,y,ix,iy);
}
-//_______________________________________________________________
-void AliMUONSt345SlatSegmentation::SetPadDivision(Int_t ndiv[4])
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y,
+ Int_t& ix, Int_t& iy)
{
- // 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];
+/// Returns pad coordinates (ix,iy) for given real coordinates (x,y)
+
+ AliMpPad pad = fSlatSegmentation->PadByPosition(TVector2(x,y), kTRUE);
+
+ if ( pad != AliMpPad::Invalid() )
+ {
+ ix = pad.GetIndices().GetFirst();
+ iy = pad.GetIndices().GetSecond();
+ }
+ else
+ {
+ ix = iy = -1;
+ }
}
-//____________________________________________________________________________
-void AliMUONSt345SlatSegmentation::SetPadSize(Float_t p1, Float_t p2)
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::GiveTestPoints(Int_t& /*n*/,
+ Float_t* /*x*/, Float_t* /*y*/) const
{
- // Sets the padsize
- fDpx=p1;
- fDpy=p2;
+/// Not implemented
+
+ AliFatal("Not Implemented");
}
-//_______________________________________________________________
-void AliMUONSt345SlatSegmentation::SetPcbBoards(Int_t n[4])
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONSt345SlatSegmentation::HasPad(Float_t x, Float_t y, Float_t z)
{
- //
- // Set PcbBoard segmentation zones for each density
- // n[0] PcbBoards for maximum density sector fNDiv[0]
- // n[1] PcbBoards for next density sector fNDiv[1] etc ...
- for (Int_t i=0; i<4; i++) fPcbBoards[i]=n[i];
+/// Returns true if a pad exists in the given position
+
+ Int_t ix, iy;
+ GetPadI(x,y,z,ix,iy);
+ return HasPad(ix,iy);
}
-//-------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::SetPad(Int_t ix, Int_t iy)
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONSt345SlatSegmentation::HasPad(Int_t ix, Int_t iy)
{
- //
- // Sets virtual pad coordinates, needed for evaluating pad response
- // outside the tracking program
- GetPadC(ix,iy,fX,fY);
- fSector=Sector(ix,iy);
+/// Returns true if a pad with given indices exists
+
+ return fSlatSegmentation->HasPad(AliMpIntPair(ix,iy));
}
-//---------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::SetHit(Float_t x, Float_t y)
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::IntegrationLimits(Float_t& x1, Float_t& x2,
+ Float_t& y1, Float_t& y2)
{
- // Set current hit
- //
- fXhit = x;
- fYhit = y;
-
- if (x < 0) fXhit = 0;
- if (y < 0) fYhit = 0;
-
- if (x >= fCx[fNsec-1]) fXhit = fCx[fNsec-1];
- if (y >= fDyPCB) fYhit = fDyPCB;
-
-}
-//----------------------------------------------------------------------------
-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;
- if (x01 < 0) x01 = 0;
- if (y01 < 0) y01 = 0;
-
- if (x02 >= fCx[fNsec-1]) x02 = fCx[fNsec-1];
-
-
- Int_t isec=-1;
- for (Int_t i=fNsec-1; i > 0; i--) {
- if (x02 >= fCx[i-1]) {
- isec=i;
- if (fCx[isec] == fCx[isec-1] && isec > 1) isec--;
- break;
+/// 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.
+
+ return -10;
+}
+
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Ix()
+{
+/// Current pad cursor during disintegration
+/// x, y-coordinate
+
+ if ( fPadIterator )
+ {
+ return fPadIterator->CurrentItem().GetIndices().GetFirst();
+ }
+ else
+ {
+ return -1;
}
- }
- y02 += Dpy(isec);
- if (y02 >= fDyPCB) y02 = fDyPCB;
-
- //
- // 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];
-
- 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);
-/*
- printf("\n \n First Pad: %d %d %f %f %d %d %d %f" ,
- fIxmin, fIxmax, fXmin, fXmax, fNpx, fId, isec, Dpy(isec));
- printf("\n \n First Pad: %d %d %f %f %d %d %d %f",
- fIymin, fIymax, fYmin, fYmax, fNpyS[isec], fId, isec, Dpy(isec));
-*/
-}
-
-
-
-//----------------------------------------------------------------------
-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=-1;
- fIy=-1;
- }
- // printf("\n Next Pad %d %d %f %f %d %d %d %d %d ",
}
-//-------------------------------------------------------------------------
-Int_t AliMUONSt345SlatSegmentation::MorePads()
+
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Iy()
{
- // Stopping condition for the iterator over pads
- //
- // Are there more pads in the integration region
-
- return (fIx != -1 || fIy != -1);
+/// Current pad cursor during disintegration
+/// x, y-coordinate
+
+ if ( fPadIterator )
+ {
+ return fPadIterator->CurrentItem().GetIndices().GetSecond();
+ }
+ else
+ {
+ return -1;
+ }
}
-//--------------------------------------------------------------------------
-Int_t AliMUONSt345SlatSegmentation::Sector(Int_t ix, Int_t iy)
+
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::MorePads()
{
- //
- // 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) printf("\n Sector: Attention isec ! %d %d %d %d \n",
- fId, ix, iy,fNpxS[3]);
+/// Iterate over pads - condition
- return isec;
+ 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::
-IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::NextPad()
{
- // 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);
- // printf("\n Integration Limits %f %f %f %f %d %f", x1, x2, y1, y2, fSector, Dpx(fSector));
-
-}
-//-----------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::
-Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
-{
- // 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;
+/// Iterate over pads - stepper
+
+ if ( fPadIterator )
+ {
+ fPadIterator->Next();
+ fCurrentPad = fPadIterator->CurrentItem();
+ }
+ else
+ {
+ AliError("PadIterator not initialized. Please use First() first ;-)");
+ }
}
-//--------------------------------------------------------------------------
-void AliMUONSt345SlatSegmentation::Init(Int_t detectionElementId)
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Npx() const
{
- //
- // 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);
-
- 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]);
- fNpyS[isec] = Int_t(fDyPCB/(*fDpyD)[isec]);
- 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.;
- //
- fId = detectionElementId;
+/// Maximum number of Pads in x
+
+ return fSlatSegmentation->MaxPadIndexX()+1;
}
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Npy() const
+{
+/// Maximum number of Pads in y
+ return fSlatSegmentation->MaxPadIndexY()+1;
+}
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::Print(Option_t* /*opt*/) const
+{
+/// Printing
+ 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);
+}
+//_____________________________________________________________________________
+Int_t
+AliMUONSt345SlatSegmentation::Sector(Float_t x, Float_t y)
+{
+/// Calculate sector from pad coordinates
+
+ return fSlat->FindPCBIndex(x,y);
+}
+
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::SetCorrFunc(Int_t /*isec*/,TF1* /*func*/)
+{
+/// Not implemented
+ AliFatal("Not Implemented");
+}
+//_____________________________________________________________________________
+void
+AliMUONSt345SlatSegmentation::SetDAnod(float /*d*/)
+{
+/// Not implemented
+ AliFatal("Not Implemented");
+}
+//_____________________________________________________________________________
+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;
+
+ //
+ // 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...)
+ //
+ 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
+
+ AliFatal("Not Implemented");
+}