]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSt345SlatSegmentation.cxx
Initialize arrays in constructor (Ivana)
[u/mrichter/AliRoot.git] / MUON / AliMUONSt345SlatSegmentation.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 //  This class works with local coordinates
21 //  of the slats via the class AliMUONGeometrySegmentation
22 //  This class contains the size of the slats and the
23 //  and the differents PCB densities. 
24 //  (from old AliMUONSegmentationSlatModule)
25 //  Gines, Subatech, Nov04
26 //*********************************************************
27
28 #include <TArrayI.h>
29 #include <TArrayF.h>
30 #include "AliMUONSt345SlatSegmentation.h"
31 #include "AliLog.h"
32
33 ClassImp(AliMUONSt345SlatSegmentation)
34
35
36 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation() 
37   : AliMUONVGeometryDESegmentation(),
38         fBending(0),
39         fId(0),
40         fNsec(0),
41         fNDiv(0),
42         fDpxD(0),
43         fDpyD(0),
44         fDpx(0),
45         fDpy(0),
46         fNpx(999999),
47         fNpy(999999),
48         fWireD(0.0),
49         fXhit(0.),
50         fYhit(0.),
51         fIx(0),
52         fIy(0),
53         fX(0.),
54         fY(0.),
55         fIxmin(0),
56         fIxmax(0),
57         fIymin(0),
58         fIymax(0)
59 {
60   // default constructor
61
62 }
63
64 //___________________________________________
65 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(Bool_t bending) 
66   :     AliMUONVGeometryDESegmentation(),
67         fBending(bending),
68         fId(0),
69         fNsec(0),
70         fNDiv(0),
71         fDpxD(0),
72         fDpyD(0),
73         fDpx(0),
74         fDpy(0),
75         fNpx(999999),
76         fNpy(999999),
77         fWireD(0.25),
78         fXhit(0.),
79         fYhit(0.),
80         fIx(0),
81         fIy(0),
82         fX(0.),
83         fY(0.),
84         fIxmin(0),
85         fIxmax(0),
86         fIymin(0),
87         fIymax(0)
88 {
89   // Non default constructor
90   fNsec = 4;  // 4 sector densities at most per slat 
91   fNDiv = new TArrayI(fNsec);      
92   fDpxD = new TArrayF(fNsec);      
93   fDpyD = new TArrayF(fNsec);      
94   (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;     
95   (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;       
96   (*fDpyD)[0]=(*fDpyD)[1]=(*fDpyD)[2]=(*fDpyD)[3]=0;       
97 }
98 //----------------------------------------------------------------------
99 AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(const AliMUONSt345SlatSegmentation& rhs) 
100 :       AliMUONVGeometryDESegmentation(rhs),
101         fBending(0),
102         fId(0),
103         fDpx(0),
104         fDpy(0),
105         fNpx(999999),
106         fNpy(999999),
107         fWireD(0.25),
108         fXhit(0.),
109         fYhit(0.),
110         fIx(0),
111         fIy(0),
112         fX(0.),
113         fY(0.),
114         fIxmin(0),
115         fIxmax(0),
116         fIymin(0),
117         fIymax(0)
118 {
119   // default constructor
120 }
121 //----------------------------------------------------------------------
122 AliMUONSt345SlatSegmentation::~AliMUONSt345SlatSegmentation() 
123 {
124   // Destructor
125   if (fNDiv) delete fNDiv;
126   if (fDpxD) delete fDpxD;
127   if (fDpyD) delete fDpyD;
128 }
129 //----------------------------------------------------------------------
130 AliMUONSt345SlatSegmentation& AliMUONSt345SlatSegmentation::operator=(const AliMUONSt345SlatSegmentation& rhs)
131 {
132   // Protected assignement operator
133   if (this == &rhs) return *this;
134   AliFatal("Not implemented.");
135   return *this;  
136 }
137
138
139 //------------------------------------------------------------------------
140 Float_t AliMUONSt345SlatSegmentation::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t * /*dummy*/)
141 {
142   // Returns the square of the distance between 1 pad
143   // labelled by its Channel numbers and a coordinate
144   Float_t x,y;
145   GetPadC(iX,iY,x,y);
146   return (x-X)*(x-X) + (y-Y)*(y-Y);
147 }
148 //____________________________________________________________________________
149 Float_t AliMUONSt345SlatSegmentation::Dpx(Int_t isec) const
150 {
151   // Return x-strip width
152   return (*fDpxD)[isec];
153
154
155 //____________________________________________________________________________
156 Float_t AliMUONSt345SlatSegmentation::Dpy(Int_t  isec) const
157 {
158   // Return y-strip width
159   return (*fDpyD)[isec];
160 }
161 //_____________________________________________________________________________
162 Float_t AliMUONSt345SlatSegmentation::GetAnod(Float_t xhit) const
163 {
164   // Returns for a hit position xhit the position of the nearest anode wire    
165   Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5;
166   return fWireD*wire;
167 }
168
169
170
171 //--------------------------------------------------------------------------------
172 void AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y) 
173 {
174   if (ix<1 || ix>Npx() || iy<1 || iy>Npy() ){
175     AliWarning(Form("ix or iy out of boundaries: Npx=%d and Npy=%d",Npx(),Npy()));
176     x=-99999.; y=-99999.;
177   }
178   else { 
179     //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
180     //  Find sector isec
181     Int_t isec = Sector(ix,iy);
182     if (isec == -1) printf("\n PadC %d %d %d  %d \n ", isec, fId, ix, iy);
183     if (iy > fNpyS[isec]) {
184       x=-99999.; y=-99999.;
185       return;
186     }
187     if (isec>0) {
188       x = fCx[isec-1]+(ix-fNpxS[isec-1])*(*fDpxD)[isec];
189       x = x-(*fDpxD)[isec]/2;
190       y = Float_t(iy*(*fDpyD)[isec])-(*fDpyD)[isec]/2.- fCy;  // !!!  
191     } else {
192       x=y=0;
193     }
194   }
195 }
196
197
198 //_____________________________________________________________________________
199 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy) 
200 {
201 //  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
202   
203   //  Find sector isec    
204   Int_t isec=-1;
205   for (Int_t i=fNsec-1; i > 0; i--) {
206     if (x >= fCx[i-1]) {
207       isec=i;
208       if (fCx[isec] == fCx[isec-1]  && isec > 1) isec--;
209       break;
210     }
211   }
212   
213   if (isec>0) {
214     ix= Int_t((x-fCx[isec-1])/(*fDpxD)[isec])
215       +fNpxS[isec-1]+1;
216     iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
217   } else if (isec == 0) {
218     ix= Int_t(x/(*fDpxD)[isec])+1;
219     iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
220   } else {
221     ix=0;
222     iy=0;
223   }
224 }
225 //-------------------------------------------------------------------------
226 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
227 {
228   GetPadI(x, y, ix, iy);
229 }
230 //_______________________________________________________________
231 void AliMUONSt345SlatSegmentation::SetPadDivision(Int_t ndiv[4])
232 {
233   // Defines the pad size perp. to the anode wire (y) for different sectors. 
234   // Pad sizes are defined as integral fractions ndiv of a basis pad size
235   // fDpx
236   // 
237   for (Int_t i=0; i<4; i++) {
238     (*fNDiv)[i]=ndiv[i];
239   }
240   ndiv[0]=ndiv[1];
241 }
242 //____________________________________________________________________________
243 void AliMUONSt345SlatSegmentation::SetPadSize(Float_t p1, Float_t p2)
244 {
245   //  Sets the padsize 
246   fDpx=p1;
247   fDpy=p2;
248 }
249 //_______________________________________________________________          
250 void AliMUONSt345SlatSegmentation::SetPcbBoards(Int_t n[4])
251 {
252   //
253   // Set PcbBoard segmentation zones for each density
254   // n[0] PcbBoards for maximum density sector fNDiv[0]
255   // n[1] PcbBoards for next density sector fNDiv[1] etc ...
256   for (Int_t i=0; i<4; i++) fPcbBoards[i]=n[i];
257 }
258 //-------------------------------------------------------------------------
259 void AliMUONSt345SlatSegmentation::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 void AliMUONSt345SlatSegmentation::SetHit(Float_t x, Float_t y)
269 {
270   // Set current hit 
271   //
272   fXhit = x;
273   fYhit = y;
274     
275   if (x < 0) fXhit = 0;
276   if (y < 0) fYhit = 0;
277     
278   if (x >= fCx[fNsec-1]) fXhit = fCx[fNsec-1];
279   if (y >= fDyPCB)       fYhit = fDyPCB;
280     
281 }
282 //----------------------------------------------------------------------------
283 void AliMUONSt345SlatSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
284 {
285   SetHit(xhit, yhit);
286 }
287
288 //----------------------------------------------------------
289 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
290 {
291 // Initialises iteration over pads for charge distribution algorithm
292 //
293     //
294     // Find the wire position (center of charge distribution)
295     Float_t x0a=GetAnod(xhit);
296     fXhit=x0a;
297     fYhit=yhit;
298     //
299     // and take fNsigma*sigma around this center
300     Float_t x01=x0a  - dx;
301     Float_t x02=x0a  + dx;
302     Float_t y01=yhit - dy;
303     Float_t y02=yhit + dy;
304     if (x01 < 0) x01 = 0;
305     if (y01 < 0) y01 = 0;
306
307     if (x02 >= fCx[fNsec-1]) x02 = fCx[fNsec-1];
308
309    
310     Int_t isec=-1;
311     for (Int_t i=fNsec-1; i > 0; i--) {
312         if (x02 >= fCx[i-1]) {
313             isec=i;
314             if (fCx[isec] == fCx[isec-1] && isec > 1) isec--;
315             break;
316         }
317     }
318     y02 += Dpy(isec);
319     if (y02 >= fDyPCB) y02 = fDyPCB;
320    
321     //
322     // find the pads over which the charge distributes
323     GetPadI(x01,y01,fIxmin,fIymin);
324     GetPadI(x02,y02,fIxmax,fIymax);
325     
326     if (fIxmax > fNpx) fIxmax=fNpx;
327     if (fIymax > fNpyS[isec]) fIymax = fNpyS[isec];    
328
329     fXmin=x01;
330     fXmax=x02;    
331     fYmin=y01;
332     fYmax=y02;    
333   
334     // 
335     // Set current pad to lower left corner
336     if (fIxmax < fIxmin) fIxmax=fIxmin;
337     if (fIymax < fIymin) fIymax=fIymin;    
338     fIx=fIxmin;
339     fIy=fIymin;
340     
341     GetPadC(fIx,fIy,fX,fY);
342     fSector=Sector(fIx,fIy);
343 /*
344     printf("\n \n First Pad: %d %d %f %f %d %d %d %f" , 
345            fIxmin, fIxmax, fXmin, fXmax, fNpx, fId, isec, Dpy(isec));    
346     printf("\n \n First Pad: %d %d %f %f %d %d %d %f",
347            fIymin, fIymax, fYmin, fYmax,  fNpyS[isec], fId, isec, Dpy(isec));
348 */
349 }
350
351
352
353 //----------------------------------------------------------------------
354 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
355 {
356   FirstPad(xhit, yhit, dx, dy);
357 }
358 //----------------------------------------------------------------------
359 void AliMUONSt345SlatSegmentation::NextPad()
360 {
361   // Stepper for the iteration over pads
362   //
363   // Step to next pad in the integration region
364   //  step from left to right    
365   if (fIx != fIxmax) {
366     fIx++;
367     GetPadC(fIx,fIy,fX,fY);
368     fSector=Sector(fIx,fIy);
369     //  step up 
370   } else if (fIy != fIymax) {
371     fIx=fIxmin;
372     fIy++;
373     GetPadC(fIx,fIy,fX,fY);
374     fSector=Sector(fIx,fIy);
375
376   } else {
377     fIx=-1;
378     fIy=-1;
379   }
380   //    printf("\n Next Pad %d %d %f %f %d %d %d %d %d ", 
381 }
382 //-------------------------------------------------------------------------
383 Int_t AliMUONSt345SlatSegmentation::MorePads()
384 {
385   // Stopping condition for the iterator over pads
386   //
387   // Are there more pads in the integration region
388     
389   return  (fIx != -1  || fIy != -1);
390 }
391 //--------------------------------------------------------------------------
392 Int_t AliMUONSt345SlatSegmentation::Sector(Int_t ix, Int_t iy) 
393 {
394   //
395   // Determine segmentation zone from pad coordinates
396   //
397   Int_t isec=-1;
398   for (Int_t i=0; i < fNsec; i++) {
399     if (ix <= fNpxS[i]) {
400       isec=i;
401       break;
402     }
403   }
404   if (isec == -1) printf("\n Sector: Attention isec ! %d %d %d %d \n",
405                          fId, ix, iy,fNpxS[3]);
406
407   return isec;
408
409 }
410 //-----------------------------------------------------------------------------
411 void AliMUONSt345SlatSegmentation::
412 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) 
413 {
414   //  Returns integration limits for current pad
415   //
416   x1=fXhit-fX-Dpx(fSector)/2.;
417   x2=x1+Dpx(fSector);
418   y1=fYhit-fY-Dpy(fSector)/2.;
419   y2=y1+Dpy(fSector);    
420   //    printf("\n Integration Limits %f %f %f %f %d %f", x1, x2, y1, y2, fSector, Dpx(fSector));
421
422 }
423 //-----------------------------------------------------------------------------
424 void AliMUONSt345SlatSegmentation::
425 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) 
426 {
427   // Returns list of next neighbours for given Pad (iX, iY)
428   Int_t i=0;
429   //  step right
430   if (iX+1 <= fNpx) {
431     Xlist[i]=iX+1;
432     Ylist[i++]=iY;
433   }
434   //  step left    
435   if (iX-1 > 0) {
436     Xlist[i]=iX-1;
437     Ylist[i++]=iY;
438   } 
439   Int_t sector = Sector(iX,iY);
440   //  step up
441   if (iY+1 <= fNpyS[sector]) {
442     Xlist[i]=iX;
443     Ylist[i++]=iY+1;
444   }
445   //  step down    
446   if (iY-1 > 0) {
447     Xlist[i]=iX;
448     Ylist[i++]=iY-1;
449   }
450   *Nlist=i;
451 }
452
453 //--------------------------------------------------------------------------
454 void AliMUONSt345SlatSegmentation::Init(Int_t detectionElementId)
455 {
456   //
457   //  Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
458   //  These arrays help in converting from real to pad co-ordinates and
459   //  vice versa
460   //   
461   //  Segmentation is defined by rectangular modules approximating
462   //  concentric circles as shown below
463   //
464   //  PCB module size in cm
465   //  printf("\n Initialise Segmentation SlatModule \n");
466
467   
468   //  printf(" fBending: %d \n",fBending);
469
470   fDxPCB=40;
471   fDyPCB=40;
472
473   //  Calculate padsize along x
474   (*fDpxD)[fNsec-1]=fDpx;
475   (*fDpyD)[fNsec-1]=fDpy;
476   if (fNsec > 1) {
477     for (Int_t i=fNsec-1; i>=0; i--){ // fNsec-2
478       if (!fBending) {
479         (*fDpxD)[i]=fDpx;
480         (*fDpyD)[i]=(*fDpyD)[fNsec-1]/(*fNDiv)[i];
481       } else {
482         (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
483         (*fDpyD)[i]=fDpy;
484       }
485     }
486   }
487   //
488   // fill the arrays defining the pad segmentation boundaries
489   //
490   //  
491   //  Loop over sectors (isec=0 for secto close to the beam pipe)
492   Float_t totalLength = 0;
493   for (Int_t isec=0; isec<4; isec++) totalLength += fPcbBoards[isec]*fDxPCB;  // !!!!
494
495   fNpy = 0;   // maximum number of pads in y
496   for (Int_t isec=0; isec<4; isec++) {
497     if (isec==0) {
498       fNpxS[0] = 0;
499       fNpyS[0] = 0;
500       fCx[0]   = -totalLength/2;
501     } else {
502       fNpxS[isec] = fNpxS[isec-1] + fPcbBoards[isec]*Int_t(fDxPCB/(*fDpxD)[isec]); 
503       fNpyS[isec] = Int_t(fDyPCB/(*fDpyD)[isec]);
504       if (fNpyS[isec] >= fNpy) fNpy = fNpyS[isec]; 
505       fCx[isec]= fCx[isec-1] + fPcbBoards[isec]*fDxPCB;
506     }
507   } // sectors
508
509   fNpx = fNpxS[3];  // maximum number of pads in x
510   fCy = fDyPCB/2.;
511   //
512   fId = detectionElementId;
513 }
514
515
516
517
518
519
520
521
522
523
524