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