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.7 2000/10/02 21:28:09 fca
19 Removal of useless dependecies via forward declarations
21 Revision 1.6 2000/10/02 16:58:29 egangler
22 Cleaning of the code :
25 -> some useless includes removed or replaced by "class" statement
27 Revision 1.5 2000/07/13 16:19:44 fca
28 Mainly coding conventions + some small bug fixes
30 Revision 1.4 2000/07/03 11:54:57 morsch
31 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
32 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
34 Revision 1.3 2000/06/29 12:34:09 morsch
35 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
36 it usable with any other geometry class. The link to the object to which it belongs is
37 established via an index. This assumes that there exists a global geometry manager
38 from which the pointer to the parent object can be obtained (in our case gAlice).
40 Revision 1.2 2000/06/15 07:58:48 morsch
41 Code from MUON-dev joined
43 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
44 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
49 /////////////////////////////////////////////////////
50 // Segmentation and Response classes version 01 //
51 /////////////////////////////////////////////////////
55 #include <TObjArray.h>
58 #include "AliMUONSegmentationV01.h"
63 //___________________________________________
64 ClassImp(AliMUONSegmentationV01)
66 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
68 // Dummy copy constructor
70 AliMUONSegmentationV01::AliMUONSegmentationV01()
72 // Default constructor
74 fRSec = new TArrayF(fNsec);
75 fNDiv = new TArrayI(fNsec);
76 fDpxD = new TArrayF(fNsec);
77 (*fRSec)[0]=(*fRSec)[1]=(*fRSec)[2]=(*fRSec)[3]=0;
78 (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
79 (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
80 fCorr = new TObjArray(3);
86 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
89 // Returns x-pad size for given sector isec
90 Float_t dpx = (*fDpxD)[isec];
94 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
97 // Returns y-pad size for given sector isec
101 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
104 // Set the radii of the segmentation zones
105 for (Int_t i=0; i<4; i++) {
107 printf("\n R %d %f \n",i,(*fRSec)[i]);
113 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
116 // Defines the pad size perp. to the anode wire (y) for different sectors.
117 // Pad sizes are defined as integral fractions ndiv of a basis pad size
120 for (Int_t i=0; i<4; i++) {
122 printf("\n Ndiv %d %d \n",i,(*fNDiv)[i]);
128 void AliMUONSegmentationV01::Init(Int_t chamber)
131 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
132 // These arrays help in converting from real to pad co-ordinates and
134 // This version approximates concentric segmentation zones
137 printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n");
138 fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
140 (*fDpxD)[fNsec-1]=fDpx;
142 for (Int_t i=fNsec-2; i>=0; i--){
143 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
144 printf("\n test ---dx %d %f \n",i,(*fDpxD)[i]);
148 // fill the arrays defining the pad segmentation boundaries
153 // loop over sections
154 for(isec=0; isec<fNsec; isec++) {
156 // loop over pads along the aode wires
157 for (Int_t iy=1; iy<=fNpy; iy++) {
159 Float_t x=iy*fDpy-fDpy/2;
160 if (x > (*fRSec)[isec]) {
164 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
166 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
167 if (isec < fNsec-1) {
168 if (TMath::Odd((Long_t)dnx)) dnx++;
170 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
171 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
172 } else if (isec == 1) {
173 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
174 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
175 add=4 - (fNpxS[isec][iy])%4;
176 if (add < 4) fNpxS[isec][iy]+=add;
177 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
178 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
180 dnx=Int_t(ry/(*fDpxD)[isec]);
182 fCx[isec][iy]=dnx*(*fDpxD)[isec];
189 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
191 // Returns sector number for given pad position
193 Int_t absix=TMath::Abs(ix);
194 Int_t absiy=TMath::Abs(iy);
196 for (Int_t i=0; i<fNsec; i++) {
197 if (absix<=fNpxS[i][absiy]){
205 void AliMUONSegmentationV01::
206 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
208 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
210 iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1;
211 if (iy > fNpy) iy= fNpy;
212 if (iy < -fNpy) iy=-fNpy;
216 Float_t absx=TMath::Abs(x);
217 Int_t absiy=TMath::Abs(iy);
218 for (Int_t i=0; i < fNsec; i++) {
219 if (absx <= fCx[i][absiy]) {
225 ix= Int_t((absx-fCx[isec-1][absiy])/(*fDpxD)[isec])
226 +fNpxS[isec-1][absiy]+1;
227 } else if (isec == 0) {
228 ix= Int_t(absx/(*fDpxD)[isec])+1;
230 ix=fNpxS[fNsec-1][absiy]+1;
235 void AliMUONSegmentationV01::
236 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
238 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
240 y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
243 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
245 Int_t absix=TMath::Abs(ix);
246 Int_t absiy=TMath::Abs(iy);
248 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*(*fDpxD)[isec];
249 x=(ix>0) ? x-(*fDpxD)[isec]/2 : -x+(*fDpxD)[isec]/2;
255 void AliMUONSegmentationV01::
256 SetPad(Int_t ix, Int_t iy)
259 // Sets virtual pad coordinates, needed for evaluating pad response
260 // outside the tracking program
261 GetPadC(ix,iy,fX,fY);
262 fSector=Sector(ix,iy);
266 void AliMUONSegmentationV01::
267 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
269 // Initialises iteration over pads for charge distribution algorithm
272 // Find the wire position (center of charge distribution)
273 Float_t x0a=GetAnod(xhit);
278 // and take fNsigma*sigma around this center
279 Float_t x01=x0a - dx;
280 Float_t x02=x0a + dx;
281 Float_t y01=yhit - dy;
282 Float_t y02=yhit + dy;
284 // find the pads over which the charge distributes
286 GetPadI(x01,y01,fIxmin,fIymin);
287 GetPadI(x02,y02,fIxmax,fIymax);
294 // Set current pad to lower left corner
295 if (fIxmax < fIxmin) fIxmax=fIxmin;
296 if (fIymax < fIymin) fIymax=fIymin;
299 GetPadC(fIx,fIy,fX,fY);
303 void AliMUONSegmentationV01::NextPad()
305 // Stepper for the iteration over pads
307 // Step to next pad in the integration region
309 // Step to next pad in integration region
313 // step from left to right
315 if (fX < fXmax && fX != 0) {
319 } else if (fIy != fIymax) {
322 // get y-position of next row (yc), xc not used here
323 GetPadC(fIx,fIy,xc,yc);
324 // get x-pad coordiante for first pad in row (fIx)
325 GetPadI(fXmin,yc,fIx,iyc);
327 printf("\n Error: Stepping outside integration region\n ");
329 GetPadC(fIx,fIy,fX,fY);
330 fSector=Sector(fIx,fIy);
332 (fSector ==-1 || fSector==0))
336 Int_t AliMUONSegmentationV01::MorePads()
337 // Stopping condition for the iterator over pads
339 // Are there more pads in the integration region
341 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
348 void AliMUONSegmentationV01::
349 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
351 // Returns integration limits for current pad
353 x1=fXhit-fX-Dpx(fSector)/2.;
355 y1=fYhit-fY-Dpy(fSector)/2.;
359 void AliMUONSegmentationV01::
360 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
362 // Returns list of next neighbours for given Pad (iX, iY)
364 const Float_t kEpsilon=fDpy/1000;
367 Int_t ixx, iyy, isec1;
369 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
374 if (Xlist[i]==0) Xlist[i]++;
379 if (Xlist[i]==0) Xlist[i]--;
383 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
384 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
387 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
390 // no sector boundary crossing
396 } else if (isec1 < isec0) {
397 // finer segmentation
407 // coarser segmenation
409 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
421 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
422 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
425 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
428 // no sector boundary crossing
436 } else if (isec1 < isec0) {
437 // finer segmentation
447 // coarser segmentation
449 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
461 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
463 // Returns test point on the pad plane.
464 // Used during determination of the segmoid correction of the COG-method
467 x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
469 x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
471 x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
475 void AliMUONSegmentationV01::Draw(const char *) const
477 // Draws the segmentation zones
481 Float_t dx=0.95/fCx[3][1]/2;
482 Float_t dy=0.95/(Float_t(Npy()))/2;
487 for (Int_t iy=1; iy<Npy(); iy++)
489 for (Int_t isec=0; isec<4; isec++) {
494 x0=fCx[isec-1][iy]*dx;
499 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
500 box->SetFillColor(isec+1);
503 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
504 box->SetFillColor(isec+1);
507 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
508 box->SetFillColor(isec+1);
511 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
512 box->SetFillColor(isec+1);
517 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
522 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
524 return (TF1*) (*fCorr)[isec];
527 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
528 =(const AliMUONSegmentationV01 & rhs)
530 // Dummy assignment operator