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.3 2000/06/29 12:34:09 morsch
19 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
20 it usable with any other geometry class. The link to the object to which it belongs is
21 established via an index. This assumes that there exists a global geometry manager
22 from which the pointer to the parent object can be obtained (in our case gAlice).
24 Revision 1.2 2000/06/15 07:58:48 morsch
25 Code from MUON-dev joined
27 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
28 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
33 /////////////////////////////////////////////////////
34 // Segmentation and Response classes version 01 //
35 /////////////////////////////////////////////////////
39 #include <TObjArray.h>
42 #include "AliMUONSegmentationV01.h"
47 //___________________________________________
48 ClassImp(AliMUONSegmentationV01)
50 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
52 // Dummy copy constructor
54 AliMUONSegmentationV01::AliMUONSegmentationV01()
56 // Default constructor
61 fRSec[0]=fRSec[1]=fRSec[2]=fRSec[3]=0;
62 fNDiv[0]=fNDiv[1]=fNDiv[2]=fNDiv[3]=0;
63 fDpxD[0]=fDpxD[1]=fDpxD[2]=fDpxD[3]=0;
64 fCorr = new TObjArray(3);
70 Float_t AliMUONSegmentationV01::Dpx(Int_t isec)
73 // Returns x-pad size for given sector isec
77 Float_t AliMUONSegmentationV01::Dpy(Int_t isec)
80 // Returns y-pad size for given sector isec
84 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
87 // Set the radii of the segmentation zones
88 for (Int_t i=0; i<4; i++) {
90 printf("\n R %d %f \n",i,fRSec[i]);
96 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
99 // Defines the pad size perp. to the anode wire (y) for different sectors.
100 // Pad sizes are defined as integral fractions ndiv of a basis pad size
103 for (Int_t i=0; i<4; i++) {
105 printf("\n Ndiv %d %d \n",i,fNDiv[i]);
111 void AliMUONSegmentationV01::Init(Int_t chamber)
114 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
115 // These arrays help in converting from real to pad co-ordinates and
117 // This version approximates concentric segmentation zones
120 printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n");
121 fNpy=Int_t(fRSec[fNsec-1]/fDpy)+1;
125 for (Int_t i=fNsec-2; i>=0; i--){
126 fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i];
127 printf("\n test ---dx %d %f \n",i,fDpxD[i]);
131 // fill the arrays defining the pad segmentation boundaries
136 // loop over sections
137 for(isec=0; isec<fNsec; isec++) {
139 // loop over pads along the aode wires
140 for (Int_t iy=1; iy<=fNpy; iy++) {
142 Float_t x=iy*fDpy-fDpy/2;
143 if (x > fRSec[isec]) {
147 ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x);
149 dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
150 if (isec < fNsec-1) {
151 if (TMath::Odd((Long_t)dnx)) dnx++;
153 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
154 fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
155 } else if (isec == 1) {
156 dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
157 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
158 add=4 - (fNpxS[isec][iy])%4;
159 if (add < 4) fNpxS[isec][iy]+=add;
160 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
161 fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
163 dnx=Int_t(ry/fDpxD[isec]);
165 fCx[isec][iy]=dnx*fDpxD[isec];
172 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
174 // Returns sector number for given pad position
176 Int_t absix=TMath::Abs(ix);
177 Int_t absiy=TMath::Abs(iy);
179 for (Int_t i=0; i<fNsec; i++) {
180 if (absix<=fNpxS[i][absiy]){
188 void AliMUONSegmentationV01::
189 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
191 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
193 iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1;
194 if (iy > fNpy) iy= fNpy;
195 if (iy < -fNpy) iy=-fNpy;
199 Float_t absx=TMath::Abs(x);
200 Int_t absiy=TMath::Abs(iy);
201 for (Int_t i=0; i < fNsec; i++) {
202 if (absx <= fCx[i][absiy]) {
208 ix= Int_t((absx-fCx[isec-1][absiy])/fDpxD[isec])
209 +fNpxS[isec-1][absiy]+1;
210 } else if (isec == 0) {
211 ix= Int_t(absx/fDpxD[isec])+1;
213 ix=fNpxS[fNsec-1][absiy]+1;
218 void AliMUONSegmentationV01::
219 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
221 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
223 y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
226 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
228 Int_t absix=TMath::Abs(ix);
229 Int_t absiy=TMath::Abs(iy);
231 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*fDpxD[isec];
232 x=(ix>0) ? x-fDpxD[isec]/2 : -x+fDpxD[isec]/2;
238 void AliMUONSegmentationV01::
239 SetPad(Int_t ix, Int_t iy)
242 // Sets virtual pad coordinates, needed for evaluating pad response
243 // outside the tracking program
244 GetPadC(ix,iy,fx,fy);
245 fSector=Sector(ix,iy);
249 void AliMUONSegmentationV01::
250 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
252 // Initialises iteration over pads for charge distribution algorithm
255 // Find the wire position (center of charge distribution)
256 Float_t x0a=GetAnod(xhit);
261 // and take fNsigma*sigma around this center
262 Float_t x01=x0a - dx;
263 Float_t x02=x0a + dx;
264 Float_t y01=yhit - dy;
265 Float_t y02=yhit + dy;
267 // find the pads over which the charge distributes
268 GetPadI(x01,y01,fixmin,fiymin);
269 GetPadI(x02,y02,fixmax,fiymax);
276 // Set current pad to lower left corner
277 if (fixmax < fixmin) fixmax=fixmin;
278 if (fiymax < fiymin) fiymax=fiymin;
281 GetPadC(fix,fiy,fx,fy);
285 void AliMUONSegmentationV01::NextPad()
287 // Stepper for the iteration over pads
289 // Step to next pad in the integration region
291 // Step to next pad in integration region
295 // step from left to right
296 if (fx < fxmax && fx != 0) {
300 } else if (fiy != fiymax) {
303 // get y-position of next row (yc), xc not used here
304 GetPadC(fix,fiy,xc,yc);
305 // get x-pad coordiante for first pad in row (fix)
306 GetPadI(fxmin,yc,fix,iyc);
308 printf("\n Error: Stepping outside integration region\n ");
310 GetPadC(fix,fiy,fx,fy);
311 fSector=Sector(fix,fiy);
313 (fSector ==-1 || fSector==0))
317 Int_t AliMUONSegmentationV01::MorePads()
318 // Stopping condition for the iterator over pads
320 // Are there more pads in the integration region
322 if ((fx >= fxmax && fiy >= fiymax) || fy==0) {
329 void AliMUONSegmentationV01::
330 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
332 // Returns integration limits for current pad
334 x1=fxhit-fx-Dpx(fSector)/2.;
336 y1=fyhit-fy-Dpy(fSector)/2.;
340 void AliMUONSegmentationV01::
341 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
343 // Returns list of next neighbours for given Pad (iX, iY)
345 const Float_t kEpsilon=fDpy/1000;
348 Int_t ixx, iyy, isec1;
350 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
355 if (Xlist[i]==0) Xlist[i]++;
360 if (Xlist[i]==0) Xlist[i]--;
364 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
365 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
368 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
371 // no sector boundary crossing
377 } else if (isec1 < isec0) {
378 // finer segmentation
388 // coarser segmenation
390 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
402 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
403 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
406 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
409 // no sector boundary crossing
417 } else if (isec1 < isec0) {
418 // finer segmentation
428 // coarser segmentation
430 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
442 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
444 // Returns test point on the pad plane.
445 // Used during determination of the segmoid correction of the COG-method
448 x[0]=(fRSec[0]+fRSec[1])/2/TMath::Sqrt(2.);
450 x[1]=(fRSec[1]+fRSec[2])/2/TMath::Sqrt(2.);
452 x[2]=(fRSec[2]+fRSec[3])/2/TMath::Sqrt(2.);
456 void AliMUONSegmentationV01::Draw()
458 // Draws the segmentation zones
462 Float_t dx=0.95/fCx[3][1]/2;
463 Float_t dy=0.95/(Float_t(Npy()))/2;
468 for (Int_t iy=1; iy<Npy(); iy++)
470 for (Int_t isec=0; isec<4; isec++) {
475 x0=fCx[isec-1][iy]*dx;
480 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
481 box->SetFillColor(isec+1);
484 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
485 box->SetFillColor(isec+1);
488 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
489 box->SetFillColor(isec+1);
492 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
493 box->SetFillColor(isec+1);
498 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
503 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec)
505 return (TF1*) (*fCorr)[isec];
508 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
509 =(const AliMUONSegmentationV01 & rhs)
511 // Dummy assignment operator