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