1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 Revision 1.6 2000/10/02 16:58:29 egangler
19 Cleaning of the code :
22 -> some useless includes removed or replaced by "class" statement
24 Revision 1.5 2000/07/13 16:19:44 fca
25 Mainly coding conventions + some small bug fixes
27 Revision 1.4 2000/07/03 11:54:57 morsch
28 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
29 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
31 Revision 1.3 2000/06/29 12:34:09 morsch
32 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
33 it usable with any other geometry class. The link to the object to which it belongs is
34 established via an index. This assumes that there exists a global geometry manager
35 from which the pointer to the parent object can be obtained (in our case gAlice).
37 Revision 1.2 2000/06/15 07:58:48 morsch
38 Code from MUON-dev joined
40 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
41 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
46 /////////////////////////////////////////////////////
47 // Segmentation and Response classes version 01 //
48 /////////////////////////////////////////////////////
52 #include <TObjArray.h>
55 #include "AliMUONSegmentationV01.h"
60 //___________________________________________
61 ClassImp(AliMUONSegmentationV01)
63 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
65 // Dummy copy constructor
67 AliMUONSegmentationV01::AliMUONSegmentationV01()
69 // Default constructor
74 fRSec[0]=fRSec[1]=fRSec[2]=fRSec[3]=0;
75 fNDiv[0]=fNDiv[1]=fNDiv[2]=fNDiv[3]=0;
76 fDpxD[0]=fDpxD[1]=fDpxD[2]=fDpxD[3]=0;
77 fCorr = new TObjArray(3);
83 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
86 // Returns x-pad size for given sector isec
87 return fDpxD.At(isec);
90 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
93 // Returns y-pad size for given sector isec
97 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
100 // Set the radii of the segmentation zones
101 for (Int_t i=0; i<4; i++) {
103 printf("\n R %d %f \n",i,fRSec[i]);
109 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
112 // Defines the pad size perp. to the anode wire (y) for different sectors.
113 // Pad sizes are defined as integral fractions ndiv of a basis pad size
116 for (Int_t i=0; i<4; i++) {
118 printf("\n Ndiv %d %d \n",i,fNDiv[i]);
124 void AliMUONSegmentationV01::Init(Int_t chamber)
127 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
128 // These arrays help in converting from real to pad co-ordinates and
130 // This version approximates concentric segmentation zones
133 printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n");
134 fNpy=Int_t(fRSec[fNsec-1]/fDpy)+1;
138 for (Int_t i=fNsec-2; i>=0; i--){
139 fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i];
140 printf("\n test ---dx %d %f \n",i,fDpxD[i]);
144 // fill the arrays defining the pad segmentation boundaries
149 // loop over sections
150 for(isec=0; isec<fNsec; isec++) {
152 // loop over pads along the aode wires
153 for (Int_t iy=1; iy<=fNpy; iy++) {
155 Float_t x=iy*fDpy-fDpy/2;
156 if (x > fRSec[isec]) {
160 ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x);
162 dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
163 if (isec < fNsec-1) {
164 if (TMath::Odd((Long_t)dnx)) dnx++;
166 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
167 fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
168 } else if (isec == 1) {
169 dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
170 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
171 add=4 - (fNpxS[isec][iy])%4;
172 if (add < 4) fNpxS[isec][iy]+=add;
173 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
174 fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
176 dnx=Int_t(ry/fDpxD[isec]);
178 fCx[isec][iy]=dnx*fDpxD[isec];
185 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
187 // Returns sector number for given pad position
189 Int_t absix=TMath::Abs(ix);
190 Int_t absiy=TMath::Abs(iy);
192 for (Int_t i=0; i<fNsec; i++) {
193 if (absix<=fNpxS[i][absiy]){
201 void AliMUONSegmentationV01::
202 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
204 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
206 iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1;
207 if (iy > fNpy) iy= fNpy;
208 if (iy < -fNpy) iy=-fNpy;
212 Float_t absx=TMath::Abs(x);
213 Int_t absiy=TMath::Abs(iy);
214 for (Int_t i=0; i < fNsec; i++) {
215 if (absx <= fCx[i][absiy]) {
221 ix= Int_t((absx-fCx[isec-1][absiy])/fDpxD[isec])
222 +fNpxS[isec-1][absiy]+1;
223 } else if (isec == 0) {
224 ix= Int_t(absx/fDpxD[isec])+1;
226 ix=fNpxS[fNsec-1][absiy]+1;
231 void AliMUONSegmentationV01::
232 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
234 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
236 y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
239 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
241 Int_t absix=TMath::Abs(ix);
242 Int_t absiy=TMath::Abs(iy);
244 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*fDpxD[isec];
245 x=(ix>0) ? x-fDpxD[isec]/2 : -x+fDpxD[isec]/2;
251 void AliMUONSegmentationV01::
252 SetPad(Int_t ix, Int_t iy)
255 // Sets virtual pad coordinates, needed for evaluating pad response
256 // outside the tracking program
257 GetPadC(ix,iy,fX,fY);
258 fSector=Sector(ix,iy);
262 void AliMUONSegmentationV01::
263 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
265 // Initialises iteration over pads for charge distribution algorithm
268 // Find the wire position (center of charge distribution)
269 Float_t x0a=GetAnod(xhit);
274 // and take fNsigma*sigma around this center
275 Float_t x01=x0a - dx;
276 Float_t x02=x0a + dx;
277 Float_t y01=yhit - dy;
278 Float_t y02=yhit + dy;
280 // find the pads over which the charge distributes
281 GetPadI(x01,y01,fIxmin,fIymin);
282 GetPadI(x02,y02,fIxmax,fIymax);
289 // Set current pad to lower left corner
290 if (fIxmax < fIxmin) fIxmax=fIxmin;
291 if (fIymax < fIymin) fIymax=fIymin;
294 GetPadC(fIx,fIy,fX,fY);
298 void AliMUONSegmentationV01::NextPad()
300 // Stepper for the iteration over pads
302 // Step to next pad in the integration region
304 // Step to next pad in integration region
308 // step from left to right
309 if (fX < fXmax && fX != 0) {
313 } else if (fIy != fIymax) {
316 // get y-position of next row (yc), xc not used here
317 GetPadC(fIx,fIy,xc,yc);
318 // get x-pad coordiante for first pad in row (fIx)
319 GetPadI(fXmin,yc,fIx,iyc);
321 printf("\n Error: Stepping outside integration region\n ");
323 GetPadC(fIx,fIy,fX,fY);
324 fSector=Sector(fIx,fIy);
326 (fSector ==-1 || fSector==0))
330 Int_t AliMUONSegmentationV01::MorePads()
331 // Stopping condition for the iterator over pads
333 // Are there more pads in the integration region
335 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
342 void AliMUONSegmentationV01::
343 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
345 // Returns integration limits for current pad
347 x1=fXhit-fX-Dpx(fSector)/2.;
349 y1=fYhit-fY-Dpy(fSector)/2.;
353 void AliMUONSegmentationV01::
354 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
356 // Returns list of next neighbours for given Pad (iX, iY)
358 const Float_t kEpsilon=fDpy/1000;
361 Int_t ixx, iyy, isec1;
363 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
368 if (Xlist[i]==0) Xlist[i]++;
373 if (Xlist[i]==0) Xlist[i]--;
377 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
378 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
381 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
384 // no sector boundary crossing
390 } else if (isec1 < isec0) {
391 // finer segmentation
401 // coarser segmenation
403 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
415 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
416 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
419 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
422 // no sector boundary crossing
430 } else if (isec1 < isec0) {
431 // finer segmentation
441 // coarser segmentation
443 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
455 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
457 // Returns test point on the pad plane.
458 // Used during determination of the segmoid correction of the COG-method
461 x[0]=(fRSec[0]+fRSec[1])/2/TMath::Sqrt(2.);
463 x[1]=(fRSec[1]+fRSec[2])/2/TMath::Sqrt(2.);
465 x[2]=(fRSec[2]+fRSec[3])/2/TMath::Sqrt(2.);
469 void AliMUONSegmentationV01::Draw(const char *)
471 // Draws the segmentation zones
475 Float_t dx=0.95/fCx[3][1]/2;
476 Float_t dy=0.95/(Float_t(Npy()))/2;
481 for (Int_t iy=1; iy<Npy(); iy++)
483 for (Int_t isec=0; isec<4; isec++) {
488 x0=fCx[isec-1][iy]*dx;
493 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
494 box->SetFillColor(isec+1);
497 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
498 box->SetFillColor(isec+1);
501 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
502 box->SetFillColor(isec+1);
505 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
506 box->SetFillColor(isec+1);
511 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
516 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec)
518 return (TF1*) (*fCorr)[isec];
521 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
522 =(const AliMUONSegmentationV01 & rhs)
524 // Dummy assignment operator