Adopt to const declaration of some of the methods in AliSegmentation.
[u/mrichter/AliRoot.git] / MUON / AliMUONSegmentationV01.cxx
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$
18 Revision 1.7  2000/10/02 21:28:09  fca
19 Removal of useless dependecies via forward declarations
20
21 Revision 1.6  2000/10/02 16:58:29  egangler
22 Cleaning of the code :
23 -> coding conventions
24 -> void Streamers
25 -> some useless includes removed or replaced by "class" statement
26
27 Revision 1.5  2000/07/13 16:19:44  fca
28 Mainly coding conventions + some small bug fixes
29
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.
33
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).
39
40 Revision 1.2  2000/06/15 07:58:48  morsch
41 Code from MUON-dev joined
42
43 Revision 1.1.2.1  2000/06/09 21:37:30  morsch
44 AliMUONSegmentationV01 code  from  AliMUONSegResV01.cxx
45
46 */
47
48
49 /////////////////////////////////////////////////////
50 //  Segmentation and Response classes version 01   //
51 /////////////////////////////////////////////////////
52
53 #include <TBox.h> 
54 #include <TF1.h> 
55 #include <TObjArray.h>
56 #include <iostream.h>
57
58 #include "AliMUONSegmentationV01.h"
59 #include "AliMUON.h"
60
61
62
63 //___________________________________________
64 ClassImp(AliMUONSegmentationV01)
65
66 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
67 {
68 // Dummy copy constructor
69 }
70 AliMUONSegmentationV01::AliMUONSegmentationV01() 
71 {
72 // Default constructor
73     fNsec=4;
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);
81     (*fCorr)[0]=0;
82     (*fCorr)[1]=0;
83     (*fCorr)[2]=0;
84
85
86 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
87 {
88 //
89 // Returns x-pad size for given sector isec
90    Float_t dpx = (*fDpxD)[isec];
91    return dpx;
92 }
93
94 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
95 {
96 //
97 // Returns y-pad size for given sector isec
98    return fDpy;
99 }
100     
101 void   AliMUONSegmentationV01::SetSegRadii(Float_t  r[4])
102 {
103 //
104 // Set the radii of the segmentation zones 
105     for (Int_t i=0; i<4; i++) {
106         (*fRSec)[i]=r[i];
107         printf("\n R %d %f \n",i,(*fRSec)[i]);
108         
109     }
110 }
111
112
113 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
114 {
115 //
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
118 // fDpx
119 // 
120     for (Int_t i=0; i<4; i++) {
121         (*fNDiv)[i]=ndiv[i];
122         printf("\n Ndiv %d %d \n",i,(*fNDiv)[i]);
123     }
124     ndiv[0]=ndiv[1];
125 }
126
127
128 void AliMUONSegmentationV01::Init(Int_t chamber)
129 {
130 //
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
133 //  vice versa.
134 //  This version approximates concentric segmentation zones
135 //
136     Int_t isec;
137     printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n");
138     fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
139
140     (*fDpxD)[fNsec-1]=fDpx;
141     if (fNsec > 1) {
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]);
145         }
146     }
147 //
148 // fill the arrays defining the pad segmentation boundaries
149     Float_t ry;
150     Int_t   dnx;
151     Int_t   add;
152 //
153 //  loop over sections
154     for(isec=0; isec<fNsec; isec++) {
155 //  
156 //  loop over pads along the aode wires
157         for (Int_t iy=1; iy<=fNpy; iy++) {
158 //
159             Float_t x=iy*fDpy-fDpy/2;
160             if (x > (*fRSec)[isec]) {
161                 fNpxS[isec][iy]=0;
162                 fCx[isec][iy]=0;
163             } else {
164                 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
165                 if (isec > 1) {
166                     dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
167                     if (isec < fNsec-1) {
168                         if (TMath::Odd((Long_t)dnx)) dnx++;             
169                     }
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];
179                 } else {
180                     dnx=Int_t(ry/(*fDpxD)[isec]);
181                     fNpxS[isec][iy]=dnx;
182                     fCx[isec][iy]=dnx*(*fDpxD)[isec];
183                 }
184             }
185         } // y-pad loop
186     } // sector loop
187 }
188
189 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
190 {
191 // Returns sector number for given pad position
192 //
193     Int_t absix=TMath::Abs(ix);
194     Int_t absiy=TMath::Abs(iy);
195     Int_t isec=0;
196     for (Int_t i=0; i<fNsec; i++) {
197         if (absix<=fNpxS[i][absiy]){
198             isec=i;
199             break;
200         }
201     }
202     return isec;
203 }
204
205 void AliMUONSegmentationV01::
206 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
207 {
208 //  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
209 //
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;
213 //
214 //  Find sector isec
215     Int_t isec=-1;
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]) {
220             isec=i;
221             break;
222         }
223     }
224     if (isec>0) {
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;
229     } else {
230         ix=fNpxS[fNsec-1][absiy]+1;     
231     }
232     ix = (x>0) ? ix:-ix;
233 }
234
235 void AliMUONSegmentationV01::
236 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
237 {
238 //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
239 //
240     y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
241 //
242 //  Find sector isec
243     Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
244 //
245     Int_t absix=TMath::Abs(ix);
246     Int_t absiy=TMath::Abs(iy);
247     if (isec) {
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;
250     } else {
251         x=y=0;
252     }
253 }
254
255 void AliMUONSegmentationV01::
256 SetPad(Int_t ix, Int_t iy)
257 {
258     //
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);
263 }
264
265
266 void AliMUONSegmentationV01::
267 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
268 {
269 // Initialises iteration over pads for charge distribution algorithm
270 //
271     //
272     // Find the wire position (center of charge distribution)
273     Float_t x0a=GetAnod(xhit);
274     fXhit=x0a;
275     fYhit=yhit;
276     
277     //
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;
283     //
284     // find the pads over which the charge distributes
285
286     GetPadI(x01,y01,fIxmin,fIymin);
287     GetPadI(x02,y02,fIxmax,fIymax);
288     fXmin=x01;
289     fXmax=x02;
290     fYmin=y01;
291     fYmax=y02;
292     
293     // 
294     // Set current pad to lower left corner
295     if (fIxmax < fIxmin) fIxmax=fIxmin;
296     if (fIymax < fIymin) fIymax=fIymin;    
297     fIx=fIxmin;
298     fIy=fIymin;
299     GetPadC(fIx,fIy,fX,fY);
300 }
301
302
303 void AliMUONSegmentationV01::NextPad()
304 {
305 // Stepper for the iteration over pads
306 //
307 // Step to next pad in the integration region
308   // 
309   // Step to next pad in integration region
310     Float_t xc,yc;
311     Int_t   iyc;
312     
313 //  step from left to right    
314
315     if (fX < fXmax && fX != 0) {
316         if (fIx==-1) fIx++;
317         fIx++;
318 //  step up 
319     } else if (fIy != fIymax) {
320         if (fIy==-1) fIy++;
321         fIy++;
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);
326     } else {
327         printf("\n Error: Stepping outside integration region\n ");
328     }
329     GetPadC(fIx,fIy,fX,fY);
330     fSector=Sector(fIx,fIy);
331     if (MorePads() && 
332         (fSector ==-1 || fSector==0)) 
333         NextPad();
334 }
335
336 Int_t AliMUONSegmentationV01::MorePads()
337 // Stopping condition for the iterator over pads
338 //
339 // Are there more pads in the integration region
340 {
341     if ((fX >= fXmax  && fIy >= fIymax) || fY==0) {
342         return 0;
343     } else {
344         return 1;
345     }
346 }
347
348 void AliMUONSegmentationV01::
349 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
350 {
351 //  Returns integration limits for current pad
352 //
353     x1=fXhit-fX-Dpx(fSector)/2.;
354     x2=x1+Dpx(fSector);
355     y1=fYhit-fY-Dpy(fSector)/2.;
356     y2=y1+Dpy(fSector);    
357 }
358
359 void AliMUONSegmentationV01::
360 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
361 {
362 // Returns list of next neighbours for given Pad (iX, iY)
363 //
364     const Float_t kEpsilon=fDpy/1000;
365     
366     Float_t x,y;
367     Int_t   ixx, iyy, isec1;
368 //
369     Int_t   isec0=AliMUONSegmentationV01::Sector(iX,iY);
370     Int_t i=0;
371 //    
372 //  step right
373     Xlist[i]=iX+1;
374     if (Xlist[i]==0) Xlist[i]++;
375     Ylist[i++]=iY;
376 //
377 //  step left    
378     Xlist[i]=iX-1;
379     if (Xlist[i]==0) Xlist[i]--;
380     Ylist[i++]=iY;
381 //
382 //  step up 
383     AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
384     AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
385     Xlist[i]=ixx;
386     Ylist[i++]=iyy;
387     isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
388     if (isec1==isec0) {
389 //
390 //  no sector boundary crossing
391 //      Xlist[i]=ixx+1;
392 //      Ylist[i++]=iY+1;
393         
394 //      Xlist[i]=ixx-1;
395 //      Ylist[i++]=iY+1;
396     } else if (isec1 < isec0) {
397 // finer segmentation
398 //      Xlist[i]=ixx+1;
399 //      Ylist[i++]=iY+1;
400         
401         Xlist[i]=ixx-1;
402         Ylist[i++]=iyy;
403         
404 //      Xlist[i]=ixx-2;
405 //      Ylist[i++]=iY+1;
406     } else {
407 // coarser segmenation  
408 /*
409         if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
410             Xlist[i]=ixx-1;
411             Ylist[i++]=iY+1;
412         } else {
413             Xlist[i]=ixx+1;
414             Ylist[i++]=iY+1;
415         }
416 */
417     }
418
419 //
420 // step down 
421     AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
422     AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
423     Xlist[i]=ixx;
424     Ylist[i++]=iyy;
425     isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
426     if (isec1==isec0) {
427 //
428 //  no sector boundary crossing
429 /*
430     Xlist[i]=ixx+1;
431     Ylist[i++]=iY-1;
432         
433     Xlist[i]=ixx-1;
434     Ylist[i++]=iY-1;
435 */
436     } else if (isec1 < isec0) {
437 // finer segmentation
438 //      Xlist[i]=ixx+1;
439 //      Ylist[i++]=iY-1;
440         
441         Xlist[i]=ixx-1;
442         Ylist[i++]=iyy;
443         
444 //      Xlist[i]=ixx-2;
445 //      Ylist[i++]=iY-1;
446     } else {
447 // coarser segmentation 
448 /*
449         if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
450             Xlist[i]=ixx-1;
451             Ylist[i++]=iY-1;
452         } else {
453             Xlist[i]=ixx+1;
454             Ylist[i++]=iY-1;
455         }
456 */
457     }
458     *Nlist=i;
459 }
460
461 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
462 {
463 // Returns test point on the pad plane.
464 // Used during determination of the segmoid correction of the COG-method
465
466     n=3;
467     x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
468     y[0]=x[0];
469     x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
470     y[1]=x[1];
471     x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
472     y[2]=x[2];
473 }
474
475 void AliMUONSegmentationV01::Draw(const char *) const
476 {
477 // Draws the segmentation zones
478 //
479     TBox *box;
480     
481     Float_t dx=0.95/fCx[3][1]/2;
482     Float_t dy=0.95/(Float_t(Npy()))/2;
483     Float_t x0,y0,x1,y1;
484     Float_t xc=0.5;
485     Float_t yc=0.5;
486     
487     for (Int_t iy=1; iy<Npy(); iy++)
488     {
489         for (Int_t isec=0; isec<4; isec++) {
490             if (isec==0) {
491                 x0=0;
492                 x1=fCx[isec][iy]*dx;
493             } else {
494                 x0=fCx[isec-1][iy]*dx;
495                 x1=fCx[isec][iy]*dx;
496             }
497             y0=Float_t(iy-1)*dy;
498             y1=y0+dy;
499             box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
500             box->SetFillColor(isec+1);
501             box->Draw();
502
503             box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
504             box->SetFillColor(isec+1);
505             box->Draw();
506
507             box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
508             box->SetFillColor(isec+1);
509             box->Draw();
510
511             box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
512             box->SetFillColor(isec+1);
513             box->Draw();
514         }
515     }
516 }
517 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
518 {
519     (*fCorr)[isec]=func;
520 }
521
522 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
523
524     return (TF1*) (*fCorr)[isec];
525 }
526
527 AliMUONSegmentationV01& AliMUONSegmentationV01::operator 
528 =(const AliMUONSegmentationV01 & rhs)
529 {
530 // Dummy assignment operator
531     return *this;
532 }