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