AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHi...
[u/mrichter/AliRoot.git] / MUON / AliMUONSegmentationV01.cxx
CommitLineData
a9e2aefa 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/*
17$Log$
a30a000f 18Revision 1.3 2000/06/29 12:34:09 morsch
19AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
20it usable with any other geometry class. The link to the object to which it belongs is
21established via an index. This assumes that there exists a global geometry manager
22from which the pointer to the parent object can be obtained (in our case gAlice).
23
d81db581 24Revision 1.2 2000/06/15 07:58:48 morsch
25Code from MUON-dev joined
26
a9e2aefa 27Revision 1.1.2.1 2000/06/09 21:37:30 morsch
28AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
29
30*/
31
32
33/////////////////////////////////////////////////////
34// Segmentation and Response classes version 01 //
35/////////////////////////////////////////////////////
36
37#include <TBox.h>
38#include <TF1.h>
39#include <TObjArray.h>
40#include <iostream.h>
41
42#include "AliMUONSegmentationV01.h"
43#include "AliMUON.h"
44
45
46
47//___________________________________________
48ClassImp(AliMUONSegmentationV01)
49
50AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
51{
52// Dummy copy constructor
53}
54AliMUONSegmentationV01::AliMUONSegmentationV01()
55{
56// Default constructor
57 fNsec=4;
58 fRSec.Set(fNsec);
59 fNDiv.Set(fNsec);
60 fDpxD.Set(fNsec);
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);
65 (*fCorr)[0]=0;
66 (*fCorr)[1]=0;
67 (*fCorr)[2]=0;
68}
69
70Float_t AliMUONSegmentationV01::Dpx(Int_t isec)
71{
72//
73// Returns x-pad size for given sector isec
74 return fDpxD[isec];
75}
76
77Float_t AliMUONSegmentationV01::Dpy(Int_t isec)
78{
79//
80// Returns y-pad size for given sector isec
81 return fDpy;
82}
83
84void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
85{
86//
87// Set the radii of the segmentation zones
88 for (Int_t i=0; i<4; i++) {
89 fRSec[i]=r[i];
90 printf("\n R %d %f \n",i,fRSec[i]);
91
92 }
93}
94
95
96void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
97{
98//
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
101// fDpx
102//
103 for (Int_t i=0; i<4; i++) {
104 fNDiv[i]=ndiv[i];
105 printf("\n Ndiv %d %d \n",i,fNDiv[i]);
106 }
107 ndiv[0]=ndiv[1];
108}
109
110
d81db581 111void AliMUONSegmentationV01::Init(Int_t chamber)
a9e2aefa 112{
113//
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
116// vice versa.
117// This version approximates concentric segmentation zones
118//
119 Int_t isec;
120 printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n");
121 fNpy=Int_t(fRSec[fNsec-1]/fDpy)+1;
122
123 fDpxD[fNsec-1]=fDpx;
124 if (fNsec > 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]);
128 }
129 }
130//
131// fill the arrays defining the pad segmentation boundaries
132 Float_t ry;
133 Int_t dnx;
134 Int_t add;
135//
136// loop over sections
137 for(isec=0; isec<fNsec; isec++) {
138//
139// loop over pads along the aode wires
140 for (Int_t iy=1; iy<=fNpy; iy++) {
141//
142 Float_t x=iy*fDpy-fDpy/2;
143 if (x > fRSec[isec]) {
144 fNpxS[isec][iy]=0;
145 fCx[isec][iy]=0;
146 } else {
147 ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x);
148 if (isec > 1) {
149 dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
150 if (isec < fNsec-1) {
151 if (TMath::Odd((Long_t)dnx)) dnx++;
152 }
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];
162 } else {
163 dnx=Int_t(ry/fDpxD[isec]);
164 fNpxS[isec][iy]=dnx;
165 fCx[isec][iy]=dnx*fDpxD[isec];
166 }
167 }
168 } // y-pad loop
169 } // sector loop
170}
171
172Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
173{
174// Returns sector number for given pad position
175//
176 Int_t absix=TMath::Abs(ix);
177 Int_t absiy=TMath::Abs(iy);
178 Int_t isec=0;
179 for (Int_t i=0; i<fNsec; i++) {
180 if (absix<=fNpxS[i][absiy]){
181 isec=i;
182 break;
183 }
184 }
185 return isec;
186}
187
188void AliMUONSegmentationV01::
a30a000f 189GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
a9e2aefa 190{
191// Returns pad coordinates (ix,iy) for given real coordinates (x,y)
192//
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;
196//
197// Find sector isec
198 Int_t isec=-1;
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]) {
203 isec=i;
204 break;
205 }
206 }
207 if (isec>0) {
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;
212 } else {
213 ix=fNpxS[fNsec-1][absiy]+1;
214 }
215 ix = (x>0) ? ix:-ix;
216}
217
218void AliMUONSegmentationV01::
a30a000f 219GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
a9e2aefa 220{
221// Returns real coordinates (x,y) for given pad coordinates (ix,iy)
222//
223 y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
224//
225// Find sector isec
226 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
227//
228 Int_t absix=TMath::Abs(ix);
229 Int_t absiy=TMath::Abs(iy);
230 if (isec) {
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;
233 } else {
234 x=y=0;
235 }
236}
237
238void AliMUONSegmentationV01::
239SetPad(Int_t ix, Int_t iy)
240{
241 //
242 // Sets virtual pad coordinates, needed for evaluating pad response
243 // outside the tracking program
a30a000f 244 GetPadC(ix,iy,fx,fy);
a9e2aefa 245 fSector=Sector(ix,iy);
246}
247
248
249void AliMUONSegmentationV01::
250FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
251{
252// Initialises iteration over pads for charge distribution algorithm
253//
254 //
255 // Find the wire position (center of charge distribution)
256 Float_t x0a=GetAnod(xhit);
257 fxhit=x0a;
258 fyhit=yhit;
259
260 //
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;
266 //
267 // find the pads over which the charge distributes
a30a000f 268 GetPadI(x01,y01,fixmin,fiymin);
269 GetPadI(x02,y02,fixmax,fiymax);
a9e2aefa 270 fxmin=x01;
271 fxmax=x02;
272 fymin=y01;
273 fymax=y02;
274
275 //
276 // Set current pad to lower left corner
277 if (fixmax < fixmin) fixmax=fixmin;
278 if (fiymax < fiymin) fiymax=fiymin;
279 fix=fixmin;
280 fiy=fiymin;
a30a000f 281 GetPadC(fix,fiy,fx,fy);
a9e2aefa 282}
283
284
285void AliMUONSegmentationV01::NextPad()
286{
287// Stepper for the iteration over pads
288//
289// Step to next pad in the integration region
290 //
291 // Step to next pad in integration region
292 Float_t xc,yc;
293 Int_t iyc;
294
295// step from left to right
296 if (fx < fxmax && fx != 0) {
297 if (fix==-1) fix++;
298 fix++;
299// step up
300 } else if (fiy != fiymax) {
301 if (fiy==-1) fiy++;
302 fiy++;
303// get y-position of next row (yc), xc not used here
a30a000f 304 GetPadC(fix,fiy,xc,yc);
a9e2aefa 305// get x-pad coordiante for first pad in row (fix)
a30a000f 306 GetPadI(fxmin,yc,fix,iyc);
a9e2aefa 307 } else {
308 printf("\n Error: Stepping outside integration region\n ");
309 }
a30a000f 310 GetPadC(fix,fiy,fx,fy);
a9e2aefa 311 fSector=Sector(fix,fiy);
312 if (MorePads() &&
313 (fSector ==-1 || fSector==0))
314 NextPad();
315}
316
317Int_t AliMUONSegmentationV01::MorePads()
318// Stopping condition for the iterator over pads
319//
320// Are there more pads in the integration region
321{
322 if ((fx >= fxmax && fiy >= fiymax) || fy==0) {
323 return 0;
324 } else {
325 return 1;
326 }
327}
328
329void AliMUONSegmentationV01::
330IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
331{
332// Returns integration limits for current pad
333//
334 x1=fxhit-fx-Dpx(fSector)/2.;
335 x2=x1+Dpx(fSector);
336 y1=fyhit-fy-Dpy(fSector)/2.;
337 y2=y1+Dpy(fSector);
338}
339
340void AliMUONSegmentationV01::
341Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
342{
343// Returns list of next neighbours for given Pad (iX, iY)
344//
345 const Float_t kEpsilon=fDpy/1000;
346
347 Float_t x,y;
348 Int_t ixx, iyy, isec1;
349//
350 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
351 Int_t i=0;
352//
353// step right
354 Xlist[i]=iX+1;
355 if (Xlist[i]==0) Xlist[i]++;
356 Ylist[i++]=iY;
357//
358// step left
359 Xlist[i]=iX-1;
360 if (Xlist[i]==0) Xlist[i]--;
361 Ylist[i++]=iY;
362//
363// step up
a30a000f 364 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
365 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
a9e2aefa 366 Xlist[i]=ixx;
367 Ylist[i++]=iyy;
368 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
369 if (isec1==isec0) {
370//
371// no sector boundary crossing
372// Xlist[i]=ixx+1;
373// Ylist[i++]=iY+1;
374
375// Xlist[i]=ixx-1;
376// Ylist[i++]=iY+1;
377 } else if (isec1 < isec0) {
378// finer segmentation
379// Xlist[i]=ixx+1;
380// Ylist[i++]=iY+1;
381
382 Xlist[i]=ixx-1;
383 Ylist[i++]=iyy;
384
385// Xlist[i]=ixx-2;
386// Ylist[i++]=iY+1;
387 } else {
388// coarser segmenation
389/*
390 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
391 Xlist[i]=ixx-1;
392 Ylist[i++]=iY+1;
393 } else {
394 Xlist[i]=ixx+1;
395 Ylist[i++]=iY+1;
396 }
397*/
398 }
399
400//
401// step down
a30a000f 402 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
403 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
a9e2aefa 404 Xlist[i]=ixx;
405 Ylist[i++]=iyy;
406 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
407 if (isec1==isec0) {
408//
409// no sector boundary crossing
410/*
411 Xlist[i]=ixx+1;
412 Ylist[i++]=iY-1;
413
414 Xlist[i]=ixx-1;
415 Ylist[i++]=iY-1;
416*/
417 } else if (isec1 < isec0) {
418// finer segmentation
419// Xlist[i]=ixx+1;
420// Ylist[i++]=iY-1;
421
422 Xlist[i]=ixx-1;
423 Ylist[i++]=iyy;
424
425// Xlist[i]=ixx-2;
426// Ylist[i++]=iY-1;
427 } else {
428// coarser segmentation
429/*
430 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
431 Xlist[i]=ixx-1;
432 Ylist[i++]=iY-1;
433 } else {
434 Xlist[i]=ixx+1;
435 Ylist[i++]=iY-1;
436 }
437*/
438 }
439 *Nlist=i;
440}
441
442void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
443{
444// Returns test point on the pad plane.
445// Used during determination of the segmoid correction of the COG-method
446
447 n=3;
448 x[0]=(fRSec[0]+fRSec[1])/2/TMath::Sqrt(2.);
449 y[0]=x[0];
450 x[1]=(fRSec[1]+fRSec[2])/2/TMath::Sqrt(2.);
451 y[1]=x[1];
452 x[2]=(fRSec[2]+fRSec[3])/2/TMath::Sqrt(2.);
453 y[2]=x[2];
454}
455
456void AliMUONSegmentationV01::Draw()
457{
458// Draws the segmentation zones
459//
460 TBox *box;
461
462 Float_t dx=0.95/fCx[3][1]/2;
463 Float_t dy=0.95/(Float_t(Npy()))/2;
464 Float_t x0,y0,x1,y1;
465 Float_t xc=0.5;
466 Float_t yc=0.5;
467
468 for (Int_t iy=1; iy<Npy(); iy++)
469 {
470 for (Int_t isec=0; isec<4; isec++) {
471 if (isec==0) {
472 x0=0;
473 x1=fCx[isec][iy]*dx;
474 } else {
475 x0=fCx[isec-1][iy]*dx;
476 x1=fCx[isec][iy]*dx;
477 }
478 y0=Float_t(iy-1)*dy;
479 y1=y0+dy;
480 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
481 box->SetFillColor(isec+1);
482 box->Draw();
483
484 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
485 box->SetFillColor(isec+1);
486 box->Draw();
487
488 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
489 box->SetFillColor(isec+1);
490 box->Draw();
491
492 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
493 box->SetFillColor(isec+1);
494 box->Draw();
495 }
496 }
497}
498void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
499{
500 (*fCorr)[isec]=func;
501}
502
503TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec)
504{
505 return (TF1*) (*fCorr)[isec];
506}
507
508AliMUONSegmentationV01& AliMUONSegmentationV01::operator
509=(const AliMUONSegmentationV01 & rhs)
510{
511// Dummy assignment operator
512 return *this;
513}