Introduction of the Copyright and cvs Log
[u/mrichter/AliRoot.git] / MUON / AliMUONSegResV01.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 */
19
20 /////////////////////////////////////////////////////
21 //  Segmentation and Response classes version 01   //
22 /////////////////////////////////////////////////////
23
24 #include <TTUBE.h>
25 #include <TNode.h> 
26 #include <TBox.h> 
27 #include <TRandom.h> 
28
29 #include "AliMUONSegResV01.h"
30 #include "AliRun.h"
31 #include "AliMC.h"
32 #include "iostream.h"
33
34 //___________________________________________
35 ClassImp(AliMUONsegmentationV01)
36
37 Float_t AliMUONsegmentationV01::Dpx(Int_t isec)
38 {
39    return fDpxD[isec];
40 }
41
42 Float_t AliMUONsegmentationV01::Dpy(Int_t )
43 {
44    return fDpy;
45 }
46
47 AliMUONsegmentationV01::AliMUONsegmentationV01() 
48 {
49     fNsec=4;
50     fRSec.Set(fNsec);    
51     fNDiv.Set(fNsec);      
52     fDpxD.Set(fNsec);      
53     fRSec[0]=fRSec[1]=fRSec[2]=fRSec[3]=0;     
54     fNDiv[0]=fNDiv[1]=fNDiv[2]=fNDiv[3]=0;     
55     fDpxD[0]=fDpxD[1]=fDpxD[2]=fDpxD[3]=0;     
56     fCorr = new TObjArray(3);
57     (*fCorr)[0]=0;
58     (*fCorr)[1]=0;
59     (*fCorr)[2]=0;
60
61     
62 void   AliMUONsegmentationV01::SetSegRadii(Float_t  r[4])
63 {
64     for (Int_t i=0; i<4; i++) {
65         fRSec[i]=r[i];
66         //printf("\n R %d %f \n",i,fRSec[i]);
67         
68     }
69 }
70
71
72 void AliMUONsegmentationV01::SetPadDivision(Int_t ndiv[4])
73 {
74 //
75 // Defines the pad size perp. to the anode wire (y) for different sectors. 
76 //
77     for (Int_t i=0; i<4; i++) {
78         fNDiv[i]=ndiv[i];
79         //printf("\n Ndiv %d %d \n",i,fNDiv[i]);
80     }
81     ndiv[0]=ndiv[1];
82 }
83
84
85 void AliMUONsegmentationV01::Init(AliMUONchamber* )
86 {
87 //
88 //  Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
89 //  These arrays help in converting from real to pad co-ordinates and
90 //  vice versa
91 //
92     Int_t isec;
93     //printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n");
94     fNpy=Int_t(fRSec[fNsec-1]/fDpy)+1;
95
96     fDpxD[fNsec-1]=fDpx;
97     if (fNsec > 1) {
98         for (Int_t i=fNsec-2; i>=0; i--){
99             fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i];
100             //printf("\n test ---dx %d %f \n",i,fDpxD[i]);
101         }
102     }
103 //
104 // fill the arrays defining the pad segmentation boundaries
105     Float_t ry;
106     Int_t   dnx;
107     Int_t   add;
108 //
109 //  loop over sections
110     for(isec=0; isec<fNsec; isec++) {
111 //  
112 //  loop over pads along the aode wires
113         for (Int_t iy=1; iy<=fNpy; iy++) {
114 //
115             Float_t x=iy*fDpy-fDpy/2;
116             if (x > fRSec[isec]) {
117                 fNpxS[isec][iy]=0;
118                  fCx[isec][iy]=0;
119             } else {
120                 ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x);
121                 if (isec > 1) {
122                     dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
123                     if (isec < fNsec-1) {
124                         if (TMath::Odd((Long_t)dnx)) dnx++;             
125                     }
126                     fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
127                     fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
128                 } else if (isec == 1) {
129                     dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
130                     fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
131                     add=4 - (fNpxS[isec][iy])%4;
132                     if (add < 4) fNpxS[isec][iy]+=add; 
133                     dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
134                     fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
135                 } else {
136                     dnx=Int_t(ry/fDpxD[isec]);
137                     fNpxS[isec][iy]=dnx;
138                     fCx[isec][iy]=dnx*fDpxD[isec];
139                 }
140             }
141         } // y-pad loop
142     } // sector loop
143     //   
144     // for debugging only 
145    
146     //printf("segmentationv01 - I was here ! \n");
147 }
148
149 Int_t AliMUONsegmentationV01::Sector(Int_t ix, Int_t iy)
150 {
151     Int_t absix=TMath::Abs(ix);
152     Int_t absiy=TMath::Abs(iy);
153     Int_t isec=0;
154     for (Int_t i=0; i<fNsec; i++) {
155         if (absix<=fNpxS[i][absiy]){
156             isec=i;
157             break;
158         }
159     }
160     return isec;
161 }
162
163     void AliMUONsegmentationV01::
164     GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
165 {
166 //  returns pad coordinates (ix,iy) for given real coordinates (x,y)
167 //
168     iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1;
169     if (iy >  fNpy) iy= fNpy;
170     if (iy < -fNpy) iy=-fNpy;
171 //
172 //  Find sector isec
173     Int_t isec=-1;
174     Float_t absx=TMath::Abs(x);
175     Int_t absiy=TMath::Abs(iy);
176     for (Int_t i=0; i < fNsec; i++) {
177         if (absx <= fCx[i][absiy]) {
178             isec=i;
179             break;
180         }
181     }
182     if (isec>0) {
183         ix= Int_t((absx-fCx[isec-1][absiy])/fDpxD[isec])
184             +fNpxS[isec-1][absiy]+1;
185     } else if (isec == 0) {
186         ix= Int_t(absx/fDpxD[isec])+1;
187     } else {
188         ix=fNpxS[fNsec-1][absiy]+1;     
189     }
190 //    printf("\n something %d %d \n",isec,absiy);
191     
192     ix = (x>0) ? ix:-ix;
193 }
194
195 void AliMUONsegmentationV01::
196 GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
197 {
198 //  returns real coordinates (x,y) for given pad coordinates (ix,iy)
199 //
200     y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
201 //
202 //  Find sector isec
203     Int_t isec=AliMUONsegmentationV01::Sector(ix,iy);
204 //
205     Int_t absix=TMath::Abs(ix);
206     Int_t absiy=TMath::Abs(iy);
207     if (isec) {
208         x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*fDpxD[isec];
209         x=(ix>0) ?  x-fDpxD[isec]/2 : -x+fDpxD[isec]/2;
210     } else {
211         x=y=0;
212     }
213 }
214
215 void AliMUONsegmentationV01::
216 SetPad(Int_t ix, Int_t iy)
217 {
218     GetPadCxy(ix,iy,fx,fy);
219     fSector=Sector(ix,iy);
220 }
221
222
223 void AliMUONsegmentationV01::
224 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
225 {
226     //
227     // Find the wire position (center of charge distribution)
228     Float_t x0a=GetAnod(xhit);
229     fxhit=x0a;
230     fyhit=yhit;
231     
232     //
233     // and take fNsigma*sigma around this center
234     Float_t x01=x0a  - dx;
235     Float_t x02=x0a  + dx;
236     Float_t y01=yhit - dy;
237     Float_t y02=yhit + dy;
238     //
239     // find the pads over which the charge distributes
240     GetPadIxy(x01,y01,fixmin,fiymin);
241     GetPadIxy(x02,y02,fixmax,fiymax);
242     fxmin=x01;
243     fxmax=x02;
244     fymin=y01;
245     fymax=y02;
246     
247     // 
248     // Set current pad to lower left corner
249     if (fixmax < fixmin) fixmax=fixmin;
250     if (fiymax < fiymin) fiymax=fiymin;    
251     fix=fixmin;
252     fiy=fiymin;
253     GetPadCxy(fix,fiy,fx,fy);
254 }
255
256
257 void AliMUONsegmentationV01::NextPad()
258 {
259   // 
260   // Step to next pad in integration region
261     Float_t xc,yc;
262     Int_t   iyc;
263     
264 //  step from left to right    
265     if (fx < fxmax && fx != 0) {
266         if (fix==-1) fix++;
267         fix++;
268 //  step up 
269     } else if (fiy != fiymax) {
270         if (fiy==-1) fiy++;
271         fiy++;
272 //      get y-position of next row (yc), xc not used here       
273         GetPadCxy(fix,fiy,xc,yc);
274 //      get x-pad coordiante for 1 pad in row (fix)
275         GetPadIxy(fxmin,yc,fix,iyc);
276     } else {
277         printf("\n Error: Stepping outside integration region\n ");
278     }
279     GetPadCxy(fix,fiy,fx,fy);
280     fSector=Sector(fix,fiy);
281     if (MorePads() && 
282         (fSector ==-1 || fSector==0 || 
283          TMath::Abs(fx)<1.5 || TMath::Abs(fy)<1.5)) 
284         NextPad();
285     
286 //    printf("\n this pad %f %f %d %d \n",fx,fy,fix,fiy);
287     
288 }
289
290 Int_t AliMUONsegmentationV01::MorePads()
291 //
292 // Are there more pads in the integration region
293 {
294     if ((fx >= fxmax  && fiy >= fiymax) || fy==0) {
295         return 0;
296     } else {
297         return 1;
298     }
299 }
300
301 void AliMUONsegmentationV01::
302 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
303 {
304     x1=fxhit-fx-Dpx(fSector)/2.;
305     x2=x1+Dpx(fSector);
306     y1=fyhit-fy-Dpy(fSector)/2.;
307     y2=y1+Dpy(fSector);    
308 }
309
310 void AliMUONsegmentationV01::
311 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
312 {
313     const Float_t epsilon=fDpy/1000;
314     
315     Float_t x,y;
316     Int_t   ixx, iyy, isec1;
317 //
318     Int_t   isec0=AliMUONsegmentationV01::Sector(iX,iY);
319     Int_t i=0;
320 //    
321 //  step right
322     Xlist[i]=iX+1;
323     Ylist[i++]=iY;
324 //
325 //  step left    
326     Xlist[i]=iX-1;
327     Ylist[i++]=iY;
328 //
329 //  step up 
330     AliMUONsegmentationV01::GetPadCxy(iX,iY,x,y);
331     AliMUONsegmentationV01::GetPadIxy(x+epsilon,y+fDpy,ixx,iyy);
332     Xlist[i]=ixx;
333     Ylist[i++]=iY+1;
334     isec1=AliMUONsegmentationV01::Sector(ixx,iyy);
335     if (isec1==isec0) {
336 //
337 //  no sector boundary crossing
338         Xlist[i]=ixx+1;
339         Ylist[i++]=iY+1;
340         
341         Xlist[i]=ixx-1;
342         Ylist[i++]=iY+1;
343     } else if (isec1 < isec0) {
344 // finer segmentation
345         Xlist[i]=ixx+1;
346         Ylist[i++]=iY+1;
347         
348         Xlist[i]=ixx-1;
349         Ylist[i++]=iY+1;
350         
351         Xlist[i]=ixx-2;
352         Ylist[i++]=iY+1;
353     } else {
354 // coarser segmenation  
355
356         if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
357             Xlist[i]=ixx-1;
358             Ylist[i++]=iY+1;
359         } else {
360             Xlist[i]=ixx+1;
361             Ylist[i++]=iY+1;
362         }
363     }
364 //
365 // step down 
366     AliMUONsegmentationV01::GetPadCxy(iX,iY,x,y);
367     AliMUONsegmentationV01::GetPadIxy(x+epsilon,y-fDpy,ixx,iyy);
368     Xlist[i]=ixx;
369     Ylist[i++]=iY-1;
370     isec1=AliMUONsegmentationV01::Sector(ixx,iyy);
371     if (isec1==isec0) {
372 //
373 //  no sector boundary crossing
374     Xlist[i]=ixx+1;
375     Ylist[i++]=iY-1;
376         
377     Xlist[i]=ixx-1;
378     Ylist[i++]=iY-1;
379     } else if (isec1 < isec0) {
380 // finer segmentation
381         Xlist[i]=ixx+1;
382         Ylist[i++]=iY-1;
383         
384         Xlist[i]=ixx-1;
385         Ylist[i++]=iY-1;
386         
387         Xlist[i]=ixx-2;
388         Ylist[i++]=iY-1;
389     } else {
390 // coarser segmentation 
391
392         if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
393             Xlist[i]=ixx-1;
394             Ylist[i++]=iY-1;
395         } else {
396             Xlist[i]=ixx+1;
397             Ylist[i++]=iY-1;
398         }
399
400     }
401     *Nlist=i;
402 }
403
404 void AliMUONsegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
405 {
406     n=3;
407     x[0]=(fRSec[0]+fRSec[1])/2/TMath::Sqrt(2.);
408     y[0]=x[0];
409     x[1]=(fRSec[1]+fRSec[2])/2/TMath::Sqrt(2.);
410     y[1]=x[1];
411     x[2]=(fRSec[2]+fRSec[3])/2/TMath::Sqrt(2.);
412     y[2]=x[2];
413 }
414
415 void AliMUONsegmentationV01::Draw(Option_t *)
416 {
417     TBox *box;
418     
419     Float_t dx=0.95/fCx[3][1]/2;
420     Float_t dy=0.95/(Float_t(Npy()))/2;
421     Float_t x0,y0,x1,y1;
422     Float_t xc=0.5;
423     Float_t yc=0.5;
424     
425     for (Int_t iy=1; iy<Npy(); iy++)
426     {
427         for (Int_t isec=0; isec<4; isec++) {
428             if (isec==0) {
429                 x0=0;
430                 x1=fCx[isec][iy]*dx;
431             } else {
432                 x0=fCx[isec-1][iy]*dx;
433                 x1=fCx[isec][iy]*dx;
434             }
435             y0=Float_t(iy-1)*dy;
436             y1=y0+dy;
437             box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
438             box->SetFillColor(isec+1);
439             box->Draw();
440
441             box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
442             box->SetFillColor(isec+1);
443             box->Draw();
444
445             box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
446             box->SetFillColor(isec+1);
447             box->Draw();
448
449             box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
450             box->SetFillColor(isec+1);
451             box->Draw();
452         }
453     }
454 }
455 void AliMUONsegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
456 {
457     (*fCorr)[isec]=func;
458     
459 }
460
461 TF1* AliMUONsegmentationV01::CorrFunc(Int_t isec)
462
463     return (TF1*) (*fCorr)[isec];
464 }
465