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.4 2000/07/03 11:54:57 morsch
19 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
20 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
22 Revision 1.3 2000/06/29 12:34:09 morsch
23 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
24 it usable with any other geometry class. The link to the object to which it belongs is
25 established via an index. This assumes that there exists a global geometry manager
26 from which the pointer to the parent object can be obtained (in our case gAlice).
28 Revision 1.2 2000/06/15 07:58:48 morsch
29 Code from MUON-dev joined
31 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
32 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
37 /////////////////////////////////////////////////////
38 // Segmentation and Response classes version 01 //
39 /////////////////////////////////////////////////////
43 #include <TObjArray.h>
46 #include "AliMUONSegmentationV01.h"
51 //___________________________________________
52 ClassImp(AliMUONSegmentationV01)
54 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
56 // Dummy copy constructor
58 AliMUONSegmentationV01::AliMUONSegmentationV01()
60 // Default constructor
65 fRSec[0]=fRSec[1]=fRSec[2]=fRSec[3]=0;
66 fNDiv[0]=fNDiv[1]=fNDiv[2]=fNDiv[3]=0;
67 fDpxD[0]=fDpxD[1]=fDpxD[2]=fDpxD[3]=0;
68 fCorr = new TObjArray(3);
74 Float_t AliMUONSegmentationV01::Dpx(Int_t isec)
77 // Returns x-pad size for given sector isec
81 Float_t AliMUONSegmentationV01::Dpy(Int_t isec)
84 // Returns y-pad size for given sector isec
88 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
91 // Set the radii of the segmentation zones
92 for (Int_t i=0; i<4; i++) {
94 printf("\n R %d %f \n",i,fRSec[i]);
100 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
103 // Defines the pad size perp. to the anode wire (y) for different sectors.
104 // Pad sizes are defined as integral fractions ndiv of a basis pad size
107 for (Int_t i=0; i<4; i++) {
109 printf("\n Ndiv %d %d \n",i,fNDiv[i]);
115 void AliMUONSegmentationV01::Init(Int_t chamber)
118 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
119 // These arrays help in converting from real to pad co-ordinates and
121 // This version approximates concentric segmentation zones
124 printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n");
125 fNpy=Int_t(fRSec[fNsec-1]/fDpy)+1;
129 for (Int_t i=fNsec-2; i>=0; i--){
130 fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i];
131 printf("\n test ---dx %d %f \n",i,fDpxD[i]);
135 // fill the arrays defining the pad segmentation boundaries
140 // loop over sections
141 for(isec=0; isec<fNsec; isec++) {
143 // loop over pads along the aode wires
144 for (Int_t iy=1; iy<=fNpy; iy++) {
146 Float_t x=iy*fDpy-fDpy/2;
147 if (x > fRSec[isec]) {
151 ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x);
153 dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
154 if (isec < fNsec-1) {
155 if (TMath::Odd((Long_t)dnx)) dnx++;
157 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
158 fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
159 } else if (isec == 1) {
160 dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
161 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
162 add=4 - (fNpxS[isec][iy])%4;
163 if (add < 4) fNpxS[isec][iy]+=add;
164 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
165 fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
167 dnx=Int_t(ry/fDpxD[isec]);
169 fCx[isec][iy]=dnx*fDpxD[isec];
176 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
178 // Returns sector number for given pad position
180 Int_t absix=TMath::Abs(ix);
181 Int_t absiy=TMath::Abs(iy);
183 for (Int_t i=0; i<fNsec; i++) {
184 if (absix<=fNpxS[i][absiy]){
192 void AliMUONSegmentationV01::
193 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
195 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
197 iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1;
198 if (iy > fNpy) iy= fNpy;
199 if (iy < -fNpy) iy=-fNpy;
203 Float_t absx=TMath::Abs(x);
204 Int_t absiy=TMath::Abs(iy);
205 for (Int_t i=0; i < fNsec; i++) {
206 if (absx <= fCx[i][absiy]) {
212 ix= Int_t((absx-fCx[isec-1][absiy])/fDpxD[isec])
213 +fNpxS[isec-1][absiy]+1;
214 } else if (isec == 0) {
215 ix= Int_t(absx/fDpxD[isec])+1;
217 ix=fNpxS[fNsec-1][absiy]+1;
222 void AliMUONSegmentationV01::
223 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
225 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
227 y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
230 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
232 Int_t absix=TMath::Abs(ix);
233 Int_t absiy=TMath::Abs(iy);
235 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*fDpxD[isec];
236 x=(ix>0) ? x-fDpxD[isec]/2 : -x+fDpxD[isec]/2;
242 void AliMUONSegmentationV01::
243 SetPad(Int_t ix, Int_t iy)
246 // Sets virtual pad coordinates, needed for evaluating pad response
247 // outside the tracking program
248 GetPadC(ix,iy,fx,fy);
249 fSector=Sector(ix,iy);
253 void AliMUONSegmentationV01::
254 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
256 // Initialises iteration over pads for charge distribution algorithm
259 // Find the wire position (center of charge distribution)
260 Float_t x0a=GetAnod(xhit);
265 // and take fNsigma*sigma around this center
266 Float_t x01=x0a - dx;
267 Float_t x02=x0a + dx;
268 Float_t y01=yhit - dy;
269 Float_t y02=yhit + dy;
271 // find the pads over which the charge distributes
272 GetPadI(x01,y01,fixmin,fiymin);
273 GetPadI(x02,y02,fixmax,fiymax);
280 // Set current pad to lower left corner
281 if (fixmax < fixmin) fixmax=fixmin;
282 if (fiymax < fiymin) fiymax=fiymin;
285 GetPadC(fix,fiy,fx,fy);
289 void AliMUONSegmentationV01::NextPad()
291 // Stepper for the iteration over pads
293 // Step to next pad in the integration region
295 // Step to next pad in integration region
299 // step from left to right
300 if (fx < fxmax && fx != 0) {
304 } else if (fiy != fiymax) {
307 // get y-position of next row (yc), xc not used here
308 GetPadC(fix,fiy,xc,yc);
309 // get x-pad coordiante for first pad in row (fix)
310 GetPadI(fxmin,yc,fix,iyc);
312 printf("\n Error: Stepping outside integration region\n ");
314 GetPadC(fix,fiy,fx,fy);
315 fSector=Sector(fix,fiy);
317 (fSector ==-1 || fSector==0))
321 Int_t AliMUONSegmentationV01::MorePads()
322 // Stopping condition for the iterator over pads
324 // Are there more pads in the integration region
326 if ((fx >= fxmax && fiy >= fiymax) || fy==0) {
333 void AliMUONSegmentationV01::
334 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
336 // Returns integration limits for current pad
338 x1=fxhit-fx-Dpx(fSector)/2.;
340 y1=fyhit-fy-Dpy(fSector)/2.;
344 void AliMUONSegmentationV01::
345 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
347 // Returns list of next neighbours for given Pad (iX, iY)
349 const Float_t kEpsilon=fDpy/1000;
352 Int_t ixx, iyy, isec1;
354 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
359 if (Xlist[i]==0) Xlist[i]++;
364 if (Xlist[i]==0) Xlist[i]--;
368 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
369 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
372 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
375 // no sector boundary crossing
381 } else if (isec1 < isec0) {
382 // finer segmentation
392 // coarser segmenation
394 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
406 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
407 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
410 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
413 // no sector boundary crossing
421 } else if (isec1 < isec0) {
422 // finer segmentation
432 // coarser segmentation
434 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
446 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
448 // Returns test point on the pad plane.
449 // Used during determination of the segmoid correction of the COG-method
452 x[0]=(fRSec[0]+fRSec[1])/2/TMath::Sqrt(2.);
454 x[1]=(fRSec[1]+fRSec[2])/2/TMath::Sqrt(2.);
456 x[2]=(fRSec[2]+fRSec[3])/2/TMath::Sqrt(2.);
460 void AliMUONSegmentationV01::Draw(const char *)
462 // Draws the segmentation zones
466 Float_t dx=0.95/fCx[3][1]/2;
467 Float_t dy=0.95/(Float_t(Npy()))/2;
472 for (Int_t iy=1; iy<Npy(); iy++)
474 for (Int_t isec=0; isec<4; isec++) {
479 x0=fCx[isec-1][iy]*dx;
484 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
485 box->SetFillColor(isec+1);
488 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
489 box->SetFillColor(isec+1);
492 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
493 box->SetFillColor(isec+1);
496 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
497 box->SetFillColor(isec+1);
502 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
507 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec)
509 return (TF1*) (*fCorr)[isec];
512 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
513 =(const AliMUONSegmentationV01 & rhs)
515 // Dummy assignment operator