* provided "as is" without express or implied warranty. *
**************************************************************************/
-/*
-$Log$
-Revision 1.3 2000/06/29 12:34:09 morsch
-AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
-it usable with any other geometry class. The link to the object to which it belongs is
-established via an index. This assumes that there exists a global geometry manager
-from which the pointer to the parent object can be obtained (in our case gAlice).
-
-Revision 1.2 2000/06/15 07:58:48 morsch
-Code from MUON-dev joined
-
-Revision 1.1.2.1 2000/06/09 21:37:30 morsch
-AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
-
-*/
-
+/* $Id$ */
/////////////////////////////////////////////////////
// Segmentation and Response classes version 01 //
/////////////////////////////////////////////////////
#include <TBox.h>
+#include <TTUBE.h>
+#include <TBRIK.h>
+#include <TNode.h>
+#include <TGeometry.h>
#include <TF1.h>
+#include <TVector3.h>
#include <TObjArray.h>
-#include <iostream.h>
#include "AliMUONSegmentationV01.h"
#include "AliMUON.h"
+#include "AliMUONChamber.h"
+#include "AliRun.h"
ClassImp(AliMUONSegmentationV01)
AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
+ : AliMUONSegmentationV0(segmentation)
{
-// Dummy copy constructor
+// Protected copy constructor
+
+ Fatal("AliMUONSegmentationV01", "Not implemented.");
}
+
AliMUONSegmentationV01::AliMUONSegmentationV01()
+ : AliMUONSegmentationV0()
{
// Default constructor
- fNsec=4;
- fRSec.Set(fNsec);
- fNDiv.Set(fNsec);
- fDpxD.Set(fNsec);
- fRSec[0]=fRSec[1]=fRSec[2]=fRSec[3]=0;
- fNDiv[0]=fNDiv[1]=fNDiv[2]=fNDiv[3]=0;
- fDpxD[0]=fDpxD[1]=fDpxD[2]=fDpxD[3]=0;
- fCorr = new TObjArray(3);
- (*fCorr)[0]=0;
- (*fCorr)[1]=0;
- (*fCorr)[2]=0;
+ fRSec = 0;
+ fNDiv = 0;
+ fDpxD = 0;
+ fCorrA = 0;
+ fSector = -1;
+}
+
+AliMUONSegmentationV01::AliMUONSegmentationV01(Int_t nsec)
+ : AliMUONSegmentationV0()
+{
+// Non default constructor
+
+ fNsec = nsec;
+ fRSec = new TArrayF(fNsec);
+ fNDiv = new TArrayI(fNsec);
+ fDpxD = new TArrayF(fNsec);
+
+
+ (*fRSec)[0]=(*fRSec)[1]=(*fRSec)[2]=(*fRSec)[3]=0;
+ (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
+ (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
+ fCorrA = new TObjArray(3);
+ fCorrA->AddAt(0,0);
+ fCorrA->AddAt(0,1);
+ fCorrA->AddAt(0,2);
+ fOffsetY=0;
+ fSector = -1;
}
-Float_t AliMUONSegmentationV01::Dpx(Int_t isec)
+AliMUONSegmentationV01::~AliMUONSegmentationV01()
+{
+// Destructor
+ if (fRSec) delete fRSec;
+ if (fNDiv) delete fNDiv;
+ if (fDpxD) delete fDpxD;
+ if (fCorrA) {
+ fCorrA->Delete();
+ delete fCorrA;
+ }
+}
+
+
+Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
{
//
// Returns x-pad size for given sector isec
- return fDpxD[isec];
+ Float_t dpx = (*fDpxD)[isec];
+ return dpx;
}
-Float_t AliMUONSegmentationV01::Dpy(Int_t isec)
+Float_t AliMUONSegmentationV01::Dpy(Int_t /*isec*/) const
{
//
// Returns y-pad size for given sector isec
//
// Set the radii of the segmentation zones
for (Int_t i=0; i<4; i++) {
- fRSec[i]=r[i];
- printf("\n R %d %f \n",i,fRSec[i]);
-
+ (*fRSec)[i]=r[i];
}
}
// fDpx
//
for (Int_t i=0; i<4; i++) {
- fNDiv[i]=ndiv[i];
- printf("\n Ndiv %d %d \n",i,fNDiv[i]);
+ (*fNDiv)[i]=ndiv[i];
}
ndiv[0]=ndiv[1];
}
// This version approximates concentric segmentation zones
//
Int_t isec;
- printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n");
- fNpy=Int_t(fRSec[fNsec-1]/fDpy)+1;
+ //printf("\n Initialise Segmentation V01\n");
+
+
+ fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
- fDpxD[fNsec-1]=fDpx;
+ (*fDpxD)[fNsec-1]=fDpx;
if (fNsec > 1) {
for (Int_t i=fNsec-2; i>=0; i--){
- fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i];
- printf("\n test ---dx %d %f \n",i,fDpxD[i]);
+ (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
}
}
//
for (Int_t iy=1; iy<=fNpy; iy++) {
//
Float_t x=iy*fDpy-fDpy/2;
- if (x > fRSec[isec]) {
+ if (x > (*fRSec)[isec]) {
fNpxS[isec][iy]=0;
fCx[isec][iy]=0;
} else {
- ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x);
+ ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
if (isec > 1) {
- dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
+ dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
if (isec < fNsec-1) {
if (TMath::Odd((Long_t)dnx)) dnx++;
}
fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
- fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
+ fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
} else if (isec == 1) {
- dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
+ dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
add=4 - (fNpxS[isec][iy])%4;
if (add < 4) fNpxS[isec][iy]+=add;
dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
- fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
+ fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
} else {
- dnx=Int_t(ry/fDpxD[isec]);
+ dnx=Int_t(ry/(*fDpxD)[isec]);
fNpxS[isec][iy]=dnx;
- fCx[isec][iy]=dnx*fDpxD[isec];
+ fCx[isec][iy]=dnx*(*fDpxD)[isec];
}
}
} // y-pad loop
} // sector loop
+// reference to chamber
+ AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
+ fChamber=&(pMUON->Chamber(chamber));
+ fZ = fChamber->Z();
+ fId=chamber;
}
+//______________________________________________________________________
Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
{
// Returns sector number for given pad position
return isec;
}
-void AliMUONSegmentationV01::
-GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
+//______________________________________________________________________
+void AliMUONSegmentationV01::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
{
// Returns pad coordinates (ix,iy) for given real coordinates (x,y)
//
- iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1;
+ iy = (y-fOffsetY >0)?
+ Int_t((y-fOffsetY)/fDpy)+1
+ :
+ Int_t((y-fOffsetY)/fDpy)-1;
+
if (iy > fNpy) iy= fNpy;
if (iy < -fNpy) iy=-fNpy;
//
}
}
if (isec>0) {
- ix= Int_t((absx-fCx[isec-1][absiy])/fDpxD[isec])
+ ix= Int_t((absx-fCx[isec-1][absiy])/(*fDpxD)[isec])
+fNpxS[isec-1][absiy]+1;
} else if (isec == 0) {
- ix= Int_t(absx/fDpxD[isec])+1;
+ ix= Int_t(absx/(*fDpxD)[isec])+1;
} else {
ix=fNpxS[fNsec-1][absiy]+1;
}
ix = (x>0) ? ix:-ix;
}
+//________________________________________________________________
+void AliMUONSegmentationV01::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
+{
+ GetPadI(x, y, ix, iy);
+}
+//________________________________________________________________
void AliMUONSegmentationV01::
GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
{
// Returns real coordinates (x,y) for given pad coordinates (ix,iy)
//
- y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
+ y = (iy>0) ?
+ Float_t(iy*fDpy)-fDpy/2.+fOffsetY
+ :
+ Float_t(iy*fDpy)+fDpy/2.+fOffsetY;
+
//
// Find sector isec
Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
Int_t absix=TMath::Abs(ix);
Int_t absiy=TMath::Abs(iy);
if (isec) {
- x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*fDpxD[isec];
- x=(ix>0) ? x-fDpxD[isec]/2 : -x+fDpxD[isec]/2;
+ x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*(*fDpxD)[isec];
+ x=(ix>0) ? x-(*fDpxD)[isec]/2 : -x+(*fDpxD)[isec]/2;
} else {
x=y=0;
}
+
+}
+//________________________________________________________________
+
+void AliMUONSegmentationV01::
+GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y, Float_t &z)
+{
+// Returns real coordinates (x,y,z) for given pad coordinates (ix,iy)
+//
+ GetPadC(ix,iy,x,y);
+
+ // To be properly interfaced with chamber geometry (AliMUONSt1GeometryBuilderV2) ???
+ TVector3 scale[4];
+ scale[0] = TVector3( 1, 1, 1); // quadrant I
+ scale[1] = TVector3(-1, 1, -1); // quadrant II
+ scale[2] = TVector3(-1, -1, 1); // quadrant III
+ scale[3] = TVector3( 1, -1, -1); // quadrant IV
+
+ Int_t iQuadrant;
+
+ if (ix > 0) {
+ if (iy > 0) {
+ iQuadrant = 0;
+ } else {
+ iQuadrant = 3;
+ }
+ } else {
+ if (iy > 0) {
+ iQuadrant = 1;
+ } else {
+ iQuadrant = 2;
+ }
+ }
+ if (TMath::Abs(fZ) < 600) {
+ z = fZ + scale[iQuadrant].Z()*6.5/2.; // Station 1
+ } else {
+ z = fZ; // Station 2
+ }
}
void AliMUONSegmentationV01::
//
// Sets virtual pad coordinates, needed for evaluating pad response
// outside the tracking program
- GetPadC(ix,iy,fx,fy);
+ GetPadC(ix,iy,fX,fY);
fSector=Sector(ix,iy);
}
-
-void AliMUONSegmentationV01::
-FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
+//______________________________________________________________________
+void AliMUONSegmentationV01::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;
+ fXhit=x0a;
+ fYhit=yhit;
//
// and take fNsigma*sigma around this center
Float_t y02=yhit + dy;
//
// find the pads over which the charge distributes
- GetPadI(x01,y01,fixmin,fiymin);
- GetPadI(x02,y02,fixmax,fiymax);
- fxmin=x01;
- fxmax=x02;
- fymin=y01;
- fymax=y02;
+
+ GetPadI(x01,y01,fIxmin,fIymin);
+ GetPadI(x02,y02,fIxmax,fIymax);
+ 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);
+ if (fIxmax < fIxmin) fIxmax=fIxmin;
+ if (fIymax < fIymin) fIymax=fIymin;
+ fIx=fIxmin;
+ fIy=fIymin;
+ GetPadC(fIx,fIy,fX,fY);
+
+ // added
+ if (fSector == -1) {
+ fSector=Sector(fIx,fIy);
+ }
}
Int_t iyc;
// step from left to right
- if (fx < fxmax && fx != 0) {
- if (fix==-1) fix++;
- fix++;
+
+ if (fX < fXmax && fX != 0) {
+ if (fIx==-1) fIx++;
+ fIx++;
// step up
- } else if (fiy != fiymax) {
- if (fiy==-1) fiy++;
- fiy++;
+ } else if (fIy != fIymax) {
+ if (fIy==-1) fIy++;
+ fIy++;
// get y-position of next row (yc), xc not used here
- GetPadC(fix,fiy,xc,yc);
-// get x-pad coordiante for first pad in row (fix)
- GetPadI(fxmin,yc,fix,iyc);
+ GetPadC(fIx,fIy,xc,yc);
+// get x-pad coordiante for first pad in row (fIx)
+ GetPadI(fXmin,yc,fIx,iyc);
} else {
- printf("\n Error: Stepping outside integration region\n ");
+ fIx=-1;
+ fIy=-1;
}
- GetPadC(fix,fiy,fx,fy);
- fSector=Sector(fix,fiy);
+ GetPadC(fIx,fIy,fX,fY);
+ fSector=Sector(fIx,fIy);
if (MorePads() &&
(fSector ==-1 || fSector==0))
NextPad();
}
Int_t AliMUONSegmentationV01::MorePads()
+
+{
// Stopping condition for the iterator over pads
//
// Are there more pads in the integration region
-{
- if ((fx >= fxmax && fiy >= fiymax) || fy==0) {
+ return (fIx != -1 || fIy != -1);
+/*
+ if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
return 0;
} else {
return 1;
}
+*/
+}
+//______________________________________________________________________
+void AliMUONSegmentationV01::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
+{
+ FirstPad(xhit, yhit, dx, dy);
}
+
void AliMUONSegmentationV01::
IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
{
// Returns integration limits for current pad
//
- x1=fxhit-fx-Dpx(fSector)/2.;
+ x1=fXhit-fX-Dpx(fSector)/2.;
x2=x1+Dpx(fSector);
- y1=fyhit-fy-Dpy(fSector)/2.;
+ y1=fYhit-fY-Dpy(fSector)/2.;
y2=y1+Dpy(fSector);
}
*Nlist=i;
}
-void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
+void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
{
// Returns test point on the pad plane.
// Used during determination of the segmoid correction of the COG-method
n=3;
- x[0]=(fRSec[0]+fRSec[1])/2/TMath::Sqrt(2.);
+ x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
y[0]=x[0];
- x[1]=(fRSec[1]+fRSec[2])/2/TMath::Sqrt(2.);
+ x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
y[1]=x[1];
- x[2]=(fRSec[2]+fRSec[3])/2/TMath::Sqrt(2.);
+ x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
y[2]=x[2];
}
-void AliMUONSegmentationV01::Draw()
+void AliMUONSegmentationV01::Draw(const char* opt) const
{
+
// Draws the segmentation zones
//
+ if (!strcmp(opt,"eventdisplay")) {
+ const int kColorMUON = kBlue;
+
+ TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
+ TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
+ TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
+ TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
+
+ char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
+ char nameSense1[9], nameSense2[9];
+ TNode *node, *nodeF;
+
+ sprintf(nameChamber,"C_MUON%d",fId+1);
+ sprintf(nameSense,"S_MUON%d",fId+1);
+ sprintf(nameSense1,"S1_MUON%d",fId+1);
+ sprintf(nameSense2,"S2_MUON%d",fId+1);
+ sprintf(nameFrame,"F_MUON%d",fId+1);
+
+ TNode* top=gAlice->GetGeometry()->GetNode("alice");
+
+ Float_t rmin = (*fRSec)[0]-3;
+ Float_t rmax = (*fRSec)[3]+3;
+ new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
+ rmin = (*fRSec)[0];
+ rmax = (*fRSec)[3];
+ new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
+ Float_t dx=(rmax-rmin)/2;
+ Float_t dy=3.;
+ Float_t dz=0.25;
+ TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
+ top->cd();
+ sprintf(nameNode,"MUON%d",100+fId+1);
+ node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,fChamber->Z(),"");
+ node->SetLineColor(kColorMUON);
+ AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
+ (pMUON->Nodes())->Add(node);
+ node->cd();
+ sprintf(nameNode,"MUON%d",200+fId+1);
+ node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
+ node->SetLineColor(kColorMUON);
+ node->cd();
+ Float_t dr=dx+rmin;
+ sprintf(nameNode,"MUON%d",300+fId+1);
+ nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
+ nodeF->SetLineColor(kColorMUON);
+ node->cd();
+ sprintf(nameNode,"MUON%d",400+fId+1);
+ nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
+ nodeF->SetLineColor(kColorMUON);
+ node->cd();
+ sprintf(nameNode,"MUON%d",500+fId+1);
+ nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
+ nodeF->SetLineColor(kColorMUON);
+ node ->cd();
+ sprintf(nameNode,"MUON%d",600+fId+1);
+ nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
+ nodeF->SetLineColor(kColorMUON);
+ } else {
TBox *box;
Float_t dx=0.95/fCx[3][1]/2;
Float_t xc=0.5;
Float_t yc=0.5;
- for (Int_t iy=1; iy<Npy(); iy++)
- {
- for (Int_t isec=0; isec<4; isec++) {
- if (isec==0) {
- x0=0;
- x1=fCx[isec][iy]*dx;
- } else {
- x0=fCx[isec-1][iy]*dx;
- x1=fCx[isec][iy]*dx;
- }
- y0=Float_t(iy-1)*dy;
- y1=y0+dy;
- box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
- box->SetFillColor(isec+1);
- box->Draw();
-
- box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
- box->SetFillColor(isec+1);
- box->Draw();
-
- box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
- box->SetFillColor(isec+1);
- box->Draw();
-
- box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
- box->SetFillColor(isec+1);
- box->Draw();
+ for (Int_t iy=1; iy<Npy(); iy++) {
+ for (Int_t isec=0; isec<4; isec++) {
+ if (isec==0) {
+ x0=0;
+ x1=fCx[isec][iy]*dx;
+ } else {
+ x0=fCx[isec-1][iy]*dx;
+ x1=fCx[isec][iy]*dx;
}
+ y0=Float_t(iy-1)*dy;
+ y1=y0+dy;
+ box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
+ box->SetFillColor(isec+1);
+ box->Draw();
+
+ box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
+ box->SetFillColor(isec+1);
+ box->Draw();
+
+ box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
+ box->SetFillColor(isec+1);
+ box->Draw();
+
+ box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
+ box->SetFillColor(isec+1);
+ box->Draw();
+ }
}
+ }
}
void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
{
- (*fCorr)[isec]=func;
+// Set the correction function
+ fCorrA->AddAt(func,isec);
}
-TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec)
+TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
{
- return (TF1*) (*fCorr)[isec];
+// Get correction function
+ //PH return (TF1*) (*fCorrA)[isec];
+ return (TF1*) fCorrA->At(isec);
}
-AliMUONSegmentationV01& AliMUONSegmentationV01::operator
-=(const AliMUONSegmentationV01 & rhs)
+AliMUONSegmentationV01&
+AliMUONSegmentationV01::operator =(const AliMUONSegmentationV01 & rhs)
{
-// Dummy assignment operator
- return *this;
+// Protected assignement operator
+
+ if (this == &rhs) return *this;
+
+ Fatal("operator=", "Not implemented.");
+
+ return *this;
}
+