AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHi...
[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.3  2000/06/29 12:34:09  morsch
19 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
20 it usable with any other geometry class. The link to the object to which it belongs is
21 established via an index. This assumes that there exists a global geometry manager
22 from which the pointer to the parent object can be obtained (in our case gAlice).
23
24 Revision 1.2  2000/06/15 07:58:48  morsch
25 Code from MUON-dev joined
26
27 Revision 1.1.2.1  2000/06/09 21:37:30  morsch
28 AliMUONSegmentationV01 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 //___________________________________________
48 ClassImp(AliMUONSegmentationV01)
49
50 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
51 {
52 // Dummy copy constructor
53 }
54 AliMUONSegmentationV01::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
70 Float_t AliMUONSegmentationV01::Dpx(Int_t isec)
71 {
72 //
73 // Returns x-pad size for given sector isec
74    return fDpxD[isec];
75 }
76
77 Float_t AliMUONSegmentationV01::Dpy(Int_t isec)
78 {
79 //
80 // Returns y-pad size for given sector isec
81    return fDpy;
82 }
83     
84 void   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
96 void 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
111 void AliMUONSegmentationV01::Init(Int_t chamber)
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
172 Int_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
188 void AliMUONSegmentationV01::
189 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
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
218 void AliMUONSegmentationV01::
219 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
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
238 void AliMUONSegmentationV01::
239 SetPad(Int_t ix, Int_t iy)
240 {
241     //
242     // Sets virtual pad coordinates, needed for evaluating pad response 
243     // outside the tracking program 
244     GetPadC(ix,iy,fx,fy);
245     fSector=Sector(ix,iy);
246 }
247
248
249 void AliMUONSegmentationV01::
250 FirstPad(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
268     GetPadI(x01,y01,fixmin,fiymin);
269     GetPadI(x02,y02,fixmax,fiymax);
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;
281     GetPadC(fix,fiy,fx,fy);
282 }
283
284
285 void 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       
304         GetPadC(fix,fiy,xc,yc);
305 //      get x-pad coordiante for first pad in row (fix)
306         GetPadI(fxmin,yc,fix,iyc);
307     } else {
308         printf("\n Error: Stepping outside integration region\n ");
309     }
310     GetPadC(fix,fiy,fx,fy);
311     fSector=Sector(fix,fiy);
312     if (MorePads() && 
313         (fSector ==-1 || fSector==0)) 
314         NextPad();
315 }
316
317 Int_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
329 void AliMUONSegmentationV01::
330 IntegrationLimits(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
340 void AliMUONSegmentationV01::
341 Neighbours(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 
364     AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
365     AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
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 
402     AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
403     AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
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
442 void 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
456 void 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 }
498 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
499 {
500     (*fCorr)[isec]=func;
501 }
502
503 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec)
504
505     return (TF1*) (*fCorr)[isec];
506 }
507
508 AliMUONSegmentationV01& AliMUONSegmentationV01::operator 
509 =(const AliMUONSegmentationV01 & rhs)
510 {
511 // Dummy assignment operator
512     return *this;
513 }