]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSegmentationSlatModule.cxx
properly take care of chamber edges in GetPadI
[u/mrichter/AliRoot.git] / MUON / AliMUONSegmentationSlatModule.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 /* $Id$ */
17
18 /////////////////////////////////////////////////////
19 //  Segmentation classes for slat modules          //
20 //  to be used with AluMUONSegmentationSlat        //
21 /////////////////////////////////////////////////////
22
23 #include <TArrayI.h>
24 #include <TArrayF.h>
25
26 #include "AliMUONSegmentationSlatModule.h"
27 #include "AliLog.h"
28
29 //___________________________________________
30 ClassImp(AliMUONSegmentationSlatModule)
31
32 AliMUONSegmentationSlatModule::AliMUONSegmentationSlatModule()  
33   : AliMUONSegmentationV0()
34 {
35 // Default constructor
36     fNDiv = 0;      
37     fDpxD = 0;  
38 }
39
40 AliMUONSegmentationSlatModule::AliMUONSegmentationSlatModule(Int_t nsec) 
41   : AliMUONSegmentationV0()
42 {
43 // Non default constructor
44     fNsec = nsec;
45     fNDiv = new TArrayI(fNsec);      
46     fDpxD = new TArrayF(fNsec);      
47     (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;     
48     (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;     
49 }
50
51 //----------------------------------------------------------------------
52 AliMUONSegmentationSlatModule::AliMUONSegmentationSlatModule(
53                                   const AliMUONSegmentationSlatModule& rhs)
54   :  AliMUONSegmentationV0(rhs) 
55 {
56 // Protected copy constructor
57
58   AliFatal("Not implemented.");
59 }
60
61
62 AliMUONSegmentationSlatModule::~AliMUONSegmentationSlatModule() 
63 {
64 // Destructor
65     if (fNDiv) delete fNDiv;
66     if (fDpxD) delete fDpxD;
67 }
68
69 //----------------------------------------------------------------------
70 AliMUONSegmentationSlatModule& 
71 AliMUONSegmentationSlatModule::operator=(        
72                                  const AliMUONSegmentationSlatModule& rhs)
73 {
74 // Protected assignement operator
75
76   if (this == &rhs) return *this;
77
78   AliFatal("Not implemented.");
79     
80   return *this;  
81 }    
82           
83 void AliMUONSegmentationSlatModule::SetPcbBoards(Int_t n[4])
84 {
85 //
86 // Set Pcb Board segmentation zones
87     for (Int_t i=0; i<4; i++) fPcbBoards[i]=n[i];
88 }
89
90
91 void AliMUONSegmentationSlatModule::SetPadDivision(Int_t ndiv[4])
92 {
93 //
94 // Defines the pad size perp. to the anode wire (y) for different sectors. 
95 // Pad sizes are defined as integral fractions ndiv of a basis pad size
96 // fDpx
97 // 
98     for (Int_t i=0; i<4; i++) {
99         (*fNDiv)[i]=ndiv[i];
100     }
101     ndiv[0]=ndiv[1];
102 }
103
104 Float_t AliMUONSegmentationSlatModule::Dpx(Int_t isec) const
105 {
106 // Return x-strip width
107     return (*fDpxD)[isec];
108
109
110
111 Float_t AliMUONSegmentationSlatModule::Dpy(Int_t /*isec*/) const
112 {
113 // Return y-strip width
114
115     return fDpy;
116 }
117
118
119 void AliMUONSegmentationSlatModule::
120 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy) 
121 {
122 //  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
123 //
124     iy = Int_t(y/fDpy)+1;
125     if (iy >  fNpy) iy= fNpy;
126 //
127 //  Find sector isec
128     
129     Int_t isec=-1;
130     for (Int_t i=fNsec-1; i > 0; i--) {
131         if (x >= fCx[i-1]) {
132             isec=i;
133             if (fCx[isec] == fCx[isec-1]  && isec > 1) isec--;
134             break;
135         }
136     }
137
138     if (isec>0) {
139         ix= Int_t((x-fCx[isec-1])/(*fDpxD)[isec])
140             +fNpxS[isec-1]+1;
141     } else if (isec == 0) {
142         ix= Int_t(x/(*fDpxD)[isec])+1;
143     } else {
144         ix=0;
145         iy=0;
146     }
147 }
148
149 void AliMUONSegmentationSlatModule::
150 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y) 
151 {
152 //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
153 //
154     y = Float_t(iy*fDpy)-fDpy/2.;
155 //
156 //  Find sector isec
157     Int_t isec=AliMUONSegmentationSlatModule::Sector(ix,iy);
158     if (isec == -1) printf("\n PadC %d %d %d  %d \n ", isec, fId, ix, iy);
159 //
160     if (isec>0) {
161         x = fCx[isec-1]+(ix-fNpxS[isec-1])*(*fDpxD)[isec];
162         x = x-(*fDpxD)[isec]/2;
163     } else {
164         x=y=0;
165     }
166 }
167 //-------------------------------------------------------------------------
168 void AliMUONSegmentationSlatModule::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
169 {
170   GetPadI(x, y, ix, iy);
171 }
172 //-------------------------------------------------------------------------
173 void AliMUONSegmentationSlatModule::
174 SetPad(Int_t ix, Int_t iy)
175 {
176     //
177     // Sets virtual pad coordinates, needed for evaluating pad response 
178     // outside the tracking program 
179     GetPadC(ix,iy,fX,fY);
180     fSector=Sector(ix,iy);
181 }
182
183 void AliMUONSegmentationSlatModule::
184 SetHit(Float_t x, Float_t y)
185 {
186 // Set current hit 
187 //
188     fXhit = x;
189     fYhit = y;
190     
191     if (x < 0) fXhit = 0;
192     if (y < 0) fYhit = 0;
193     
194     if (x >= fCx[fNsec-1]) fXhit = fCx[fNsec-1];
195     if (y >= fDyPCB)       fYhit = fDyPCB;
196
197     
198 }
199 //----------------------------------------------------------
200 void AliMUONSegmentationSlatModule::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
201 {
202   SetHit(xhit, yhit);
203 }
204 //----------------------------------------------------------
205 void AliMUONSegmentationSlatModule::
206 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
207 {
208 // Initialises iteration over pads for charge distribution algorithm
209 //
210     //
211     // Find the wire position (center of charge distribution)
212     Float_t x0a=GetAnod(xhit);
213     fXhit=x0a;
214     fYhit=yhit;
215     //
216     // and take fNsigma*sigma around this center
217     Float_t x01=x0a  - dx;
218     Float_t x02=x0a  + dx;
219     Float_t y01=yhit - dy;
220     Float_t y02=yhit + dy;
221     if (x01 < 0) x01 = 0;
222     if (y01 < 0) y01 = 0;
223
224     if (x02 >= fCx[fNsec-1]) x02 = fCx[fNsec-1];
225
226     
227
228     Int_t isec=-1;
229     for (Int_t i=fNsec-1; i > 0; i--) {
230         if (x02 >= fCx[i-1]) {
231             isec=i;
232             if (fCx[isec] == fCx[isec-1] && isec > 1) isec--;
233             break;
234         }
235     }
236     y02 += Dpy(isec);
237     if (y02 >= fDyPCB) y02 = fDyPCB;
238    
239     //
240     // find the pads over which the charge distributes
241     GetPadI(x01,y01,fIxmin,fIymin);
242     GetPadI(x02,y02,fIxmax,fIymax);
243     
244     if (fIxmax > fNpx) fIxmax=fNpx;
245     if (fIymax > fNpyS[isec]) fIymax = fNpyS[isec];    
246
247     fXmin=x01;
248     fXmax=x02;    
249     fYmin=y01;
250     fYmax=y02;    
251   
252     // 
253     // Set current pad to lower left corner
254     if (fIxmax < fIxmin) fIxmax=fIxmin;
255     if (fIymax < fIymin) fIymax=fIymin;    
256     fIx=fIxmin;
257     fIy=fIymin;
258     
259     GetPadC(fIx,fIy,fX,fY);
260     fSector=Sector(fIx,fIy);
261 /*
262     printf("\n \n First Pad: %d %d %f %f %d %d %d %f" , 
263            fIxmin, fIxmax, fXmin, fXmax, fNpx, fId, isec, Dpy(isec));    
264     printf("\n \n First Pad: %d %d %f %f %d %d %d %f",
265            fIymin, fIymax, fYmin, fYmax,  fNpyS[isec], fId, isec, Dpy(isec));
266 */
267 }
268 //----------------------------------------------------------------------
269 void AliMUONSegmentationSlatModule::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
270 {
271   FirstPad(xhit, yhit, dx, dy);
272 }
273 //----------------------------------------------------------------------
274 void AliMUONSegmentationSlatModule::NextPad()
275 {
276 // Stepper for the iteration over pads
277 //
278 // Step to next pad in the integration region
279 //  step from left to right    
280     if (fIx != fIxmax) {
281         fIx++;
282         GetPadC(fIx,fIy,fX,fY);
283         fSector=Sector(fIx,fIy);
284 //  step up 
285     } else if (fIy != fIymax) {
286         fIx=fIxmin;
287         fIy++;
288         GetPadC(fIx,fIy,fX,fY);
289         fSector=Sector(fIx,fIy);
290
291     } else {
292         fIx=-1;
293         fIy=-1;
294     }
295 //    printf("\n Next Pad %d %d %f %f %d %d %d %d %d ", 
296 }
297
298
299 Int_t AliMUONSegmentationSlatModule::MorePads()
300 {
301 // Stopping condition for the iterator over pads
302 //
303 // Are there more pads in the integration region
304     
305     return  (fIx != -1  || fIy != -1);
306 }
307
308
309 Int_t AliMUONSegmentationSlatModule::Sector(Int_t ix, Int_t iy) 
310 {
311 //
312 // Determine segmentation zone from pad coordinates
313 //
314     Int_t isec=-1;
315     for (Int_t i=0; i < fNsec; i++) {
316         if (ix <= fNpxS[i]) {
317             isec=i;
318             break;
319         }
320     }
321     if (isec == -1) printf("\n Sector: Attention isec ! %d %d %d %d \n",
322                            fId, ix, iy,fNpxS[3]);
323
324     return isec;
325
326 }
327
328 void AliMUONSegmentationSlatModule::
329 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) 
330 {
331 //  Returns integration limits for current pad
332 //
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 //    printf("\n Integration Limits %f %f %f %f %d %f", x1, x2, y1, y2, fSector, Dpx(fSector));
339
340 }
341
342 void AliMUONSegmentationSlatModule::
343 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) 
344 {
345 // Returns list of next neighbours for given Pad (iX, iY)
346 //
347 //
348     Int_t i=0;
349 //    
350 //  step right
351     if (iX+1 <= fNpx) {
352         Xlist[i]=iX+1;
353         Ylist[i++]=iY;
354     }
355 //
356 //  step left    
357     if (iX-1 > 0) {
358         Xlist[i]=iX-1;
359         Ylist[i++]=iY;
360     }
361
362 //    
363 //  step up
364     if (iY+1 <= fNpy) {
365         Xlist[i]=iX;
366         Ylist[i++]=iY+1;
367     }
368 //
369 //  step down    
370     if (iY-1 > 0) {
371         Xlist[i]=iX;
372         Ylist[i++]=iY-1;
373     }
374
375     *Nlist=i;
376 }
377
378
379 void AliMUONSegmentationSlatModule::Init(Int_t chamber)
380 {
381 //
382 //  Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
383 //  These arrays help in converting from real to pad co-ordinates and
384 //  vice versa
385 //   
386 //  Segmentation is defined by rectangular modules approximating
387 //  concentric circles as shown below
388 //
389 //  PCB module size in cm
390   // printf("\n Initialise Segmentation SlatModule \n");
391
392     fDxPCB=40;
393     fDyPCB=40;
394 //
395 // number of pad rows per PCB
396 //    
397     Int_t nPyPCB=Int_t(fDyPCB/fDpy);
398 //
399 // maximum number of pad rows    
400     fNpy=nPyPCB;
401 //
402 //  Calculate padsize along x
403     (*fDpxD)[fNsec-1]=fDpx;
404     if (fNsec > 1) {
405         for (Int_t i=fNsec-2; i>=0; i--){
406             (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
407         }
408     }
409 //
410 // fill the arrays defining the pad segmentation boundaries
411 //
412 //  
413 //  Loop over sectors (isec=0 is the dead space surounding the beam pipe)
414     for (Int_t isec=0; isec<4; isec++) {
415         if (isec==0) {
416             fNpxS[0] = 0;
417             fNpyS[0] = 0;
418             fCx[0]   = 0;
419         } else {
420             fNpxS[isec]=fNpxS[isec-1] + fPcbBoards[isec]*Int_t(fDxPCB/(*fDpxD)[isec]);
421             fNpyS[isec]=fNpy;
422             fCx[isec]=fCx[isec-1] + fPcbBoards[isec]*fDxPCB;
423         }
424     } // sectors
425 // maximum number of pad rows    
426     fNpy=nPyPCB;
427     fNpx=fNpxS[3];
428 //
429     fId = chamber;
430 }
431
432
433
434
435
436
437
438
439
440
441
442