]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSt345SlatSegmentation.cxx
Allowing modularity of the MUON geometry during the generation (geant) phase with...
[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 %d or iy %d out of boundaries: Npx=%d and Npy=%d",ix, iy, Npx(), Npy()));
176     x=-99999.; y=-99999.;
177
178   } else { 
179
180     //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
181     //  Find sector isec
182     Int_t isec = Sector(ix,iy);
183     if (isec == -1) AliWarning(Form("isector = %d  with ix %d, iy %d", isec, ix, iy));
184     if (iy > fNpyS[isec]) {
185       x=-99999.; y=-99999.;
186       return;
187     }
188     if (isec>0) {
189       x = fCx[isec-1]+(ix-fNpxS[isec-1])*(*fDpxD)[isec];
190       x = x-(*fDpxD)[isec]/2;
191       y = Float_t(iy*(*fDpyD)[isec])-(*fDpyD)[isec]/2.- fCy;  // !!!  
192     } else {
193       x = y = 0;
194     }
195   }
196 }
197
198
199 //_____________________________________________________________________________
200 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy) 
201 {
202 //  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
203
204   //  Find sector isec    
205   Int_t isec=-1;
206   for (Int_t i=fNsec-1; i > 0; i--) {
207     if (x >= fCx[i-1]) {
208       isec=i;
209       if (fCx[isec] == fCx[isec-1]  && isec > 1) isec--;
210       break;
211     }
212   }
213   if (isec == -1) AliWarning(Form("isector equal to %d  with xl %f, yl %f", isec, x, y));
214   if (isec>0) {
215     ix= Int_t((x-fCx[isec-1])/(*fDpxD)[isec])
216       +fNpxS[isec-1]+1;
217     iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
218   } else if (isec == 0) {
219     ix= Int_t(x/(*fDpxD)[isec])+1;
220     iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
221   } else {
222     ix=0;
223     iy=0;
224   }
225 }
226 //-------------------------------------------------------------------------
227 void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
228 {
229   GetPadI(x, y, ix, iy);
230 }
231 //_______________________________________________________________
232 void AliMUONSt345SlatSegmentation::SetPadDivision(Int_t ndiv[4])
233 {
234   // Defines the pad size perp. to the anode wire (y) for different sectors. 
235   // Pad sizes are defined as integral fractions ndiv of a basis pad size
236   // fDpx
237   // 
238   for (Int_t i=0; i<4; i++) {
239     (*fNDiv)[i]=ndiv[i];
240   }
241   ndiv[0]=ndiv[1];
242 }
243 //____________________________________________________________________________
244 void AliMUONSt345SlatSegmentation::SetPadSize(Float_t p1, Float_t p2)
245 {
246   //  Sets the padsize 
247   fDpx=p1;
248   fDpy=p2;
249 }
250 //_______________________________________________________________          
251 void AliMUONSt345SlatSegmentation::SetPcbBoards(Int_t n[4])
252 {
253   //
254   // Set PcbBoard segmentation zones for each density
255   // n[0] PcbBoards for maximum density sector fNDiv[0]
256   // n[1] PcbBoards for next density sector fNDiv[1] etc ...
257   for (Int_t i=0; i<4; i++) fPcbBoards[i]=n[i];
258 }
259 //-------------------------------------------------------------------------
260 void AliMUONSt345SlatSegmentation::SetPad(Int_t ix, Int_t iy)
261 {
262   //
263   // Sets virtual pad coordinates, needed for evaluating pad response 
264   // outside the tracking program 
265   GetPadC(ix,iy,fX,fY);
266   fSector=Sector(ix,iy);
267 }
268 //---------------------------------------------------------------------------
269 void AliMUONSt345SlatSegmentation::SetHit(Float_t x, Float_t y)
270 {
271   // Set current hit 
272   //
273   fXhit = x;
274   fYhit = y;
275     
276   if (x <  fCx[0])    fXhit = fCx[0];
277   if (y < -fDyPCB/2.) fYhit = -fDyPCB/2.;
278     
279   if (x > fCx[fNsec-1]) fXhit = fCx[fNsec-1];
280   if (y > fDyPCB/2.)    fYhit = fDyPCB/2.;
281     
282 }
283 //----------------------------------------------------------------------------
284 void AliMUONSt345SlatSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
285 {
286   SetHit(xhit, yhit);
287 }
288
289 //----------------------------------------------------------
290 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
291 {
292 // Initialises iteration over pads for charge distribution algorithm
293 //
294     //
295     // Find the wire position (center of charge distribution)
296     Float_t x0a = GetAnod(xhit);
297     fXhit = x0a;
298     fYhit = yhit;
299     //
300     // and take fNsigma*sigma around this center
301     Float_t x01 = x0a  - dx ;
302     Float_t x02 = x0a  + dx;
303     Float_t y01 = yhit - dy;
304     Float_t y02 = yhit + dy;
305
306     // check the limits after adding (fNsigma*sigma)
307     if (x01 <  fCx[0])   x01 =  fCx[0];
308     if (y01 < -fDyPCB/2) y01 = -fDyPCB/2;
309
310     if (x02 >= fCx[fNsec-1]) x02 = fCx[fNsec-1]; // still ok ? (CF)
311
312    
313     Int_t isec=-1;
314     for (Int_t i=fNsec-1; i > 0; i--) {
315       if (x02 >= fCx[i-1]) {
316         isec=i;
317         if (fCx[isec] == fCx[isec-1] && isec > 1) isec--;
318         break;
319       }
320     }
321
322     y02 += Dpy(isec);// why ? (CF)
323     if (y02 >= fDyPCB/2.) y02 = fDyPCB/2;
324    
325     //
326     // find the pads over which the charge distributes
327     GetPadI(x01,y01,fIxmin,fIymin);
328     GetPadI(x02,y02,fIxmax,fIymax);
329     
330     if (fIxmax > fNpx) fIxmax=fNpx;
331     if (fIymax > fNpyS[isec]) fIymax = fNpyS[isec];    
332     if (fIxmin < 1) fIxmin = 1;    // patch for the moment (Ch. Finck)
333     if (fIymin < 1) fIymin = 1;    
334
335     fXmin = x01;
336     fXmax = x02;    
337     fYmin = y01;
338     fYmax = y02;    
339   
340     // 
341     // Set current pad to lower left corner
342     if (fIxmax < fIxmin) fIxmax = fIxmin;
343     if (fIymax < fIymin) fIymax = fIymin;    
344     fIx = fIxmin;
345     fIy = fIymin;
346     
347     GetPadC(fIx,fIy,fX,fY);
348     fSector = Sector(fIx,fIy);
349 /*
350     printf("\n \n First Pad: %d %d %f %f %d %d %d %f" , 
351            fIxmin, fIxmax, fXmin, fXmax, fNpx, fId, isec, Dpy(isec));    
352     printf("\n \n First Pad: %d %d %f %f %d %d %d %f",
353            fIymin, fIymax, fYmin, fYmax,  fNpyS[isec], fId, isec, Dpy(isec));
354 */
355 }
356
357
358
359 //----------------------------------------------------------------------
360 void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
361 {
362   FirstPad(xhit, yhit, dx, dy);
363 }
364 //----------------------------------------------------------------------
365 void AliMUONSt345SlatSegmentation::NextPad()
366 {
367   // Stepper for the iteration over pads
368   //
369   // Step to next pad in the integration region
370   //  step from left to right    
371   if (fIx != fIxmax) {
372     fIx++;
373     GetPadC(fIx,fIy,fX,fY);
374     fSector=Sector(fIx,fIy);
375     //  step up 
376   } else if (fIy != fIymax) {
377     fIx=fIxmin;
378     fIy++;
379     GetPadC(fIx,fIy,fX,fY);
380     fSector=Sector(fIx,fIy);
381
382   } else {
383     fIx=-999;
384     fIy=-999;
385   }
386 }
387 //-------------------------------------------------------------------------
388 Int_t AliMUONSt345SlatSegmentation::MorePads()
389 {
390   // Stopping condition for the iterator over pads
391   //
392   // Are there more pads in the integration region
393     
394   return  (fIx != -999  || fIy != -999);
395 }
396 //--------------------------------------------------------------------------
397 Int_t AliMUONSt345SlatSegmentation::Sector(Int_t ix, Int_t iy) 
398 {
399   //
400   // Determine segmentation zone from pad coordinates
401   //
402   Int_t isec = -1;
403   for (Int_t i = 0; i < fNsec; i++) {
404     if (ix <= fNpxS[i]) {
405       isec = i;
406       break;
407     }
408   }
409   if (isec == -1) AliWarning(Form("Sector = %d  with ix %d and iy %d, Npx %d",
410                                   isec, ix, iy, fNpx));
411
412   return isec;
413
414 }
415 //-----------------------------------------------------------------------------
416 void AliMUONSt345SlatSegmentation::
417 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) 
418 {
419   //  Returns integration limits for current pad
420   //
421   x1=fXhit-fX-Dpx(fSector)/2.;
422   x2=x1+Dpx(fSector);
423   y1=fYhit-fY-Dpy(fSector)/2.;
424   y2=y1+Dpy(fSector);    
425   //  printf("\n Integration Limits %f %f %f %f %d %f", x1, x2, y1, y2, fSector, Dpx(fSector));
426
427 }
428 //-----------------------------------------------------------------------------
429 void AliMUONSt345SlatSegmentation::
430 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) 
431 {
432   // Returns list of next neighbours for given Pad (iX, iY)
433   Int_t i=0;
434   //  step right
435   if (iX+1 <= fNpx) {
436     Xlist[i]=iX+1;
437     Ylist[i++]=iY;
438   }
439   //  step left    
440   if (iX-1 > 0) {
441     Xlist[i]=iX-1;
442     Ylist[i++]=iY;
443   } 
444   Int_t sector = Sector(iX,iY);
445   //  step up
446   if (iY+1 <= fNpyS[sector]) {
447     Xlist[i]=iX;
448     Ylist[i++]=iY+1;
449   }
450   //  step down    
451   if (iY-1 > 0) {
452     Xlist[i]=iX;
453     Ylist[i++]=iY-1;
454   }
455   *Nlist=i;
456 }
457
458 //--------------------------------------------------------------------------
459 void AliMUONSt345SlatSegmentation::Init(Int_t detectionElementId)
460 {
461   //
462   //  Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
463   //  These arrays help in converting from real to pad co-ordinates and
464   //  vice versa
465   //   
466   //  Segmentation is defined by rectangular modules approximating
467   //  concentric circles as shown below
468   //
469   //  PCB module size in cm
470   //  printf("\n Initialise Segmentation SlatModule \n");
471
472   
473   //  printf(" fBending: %d \n",fBending);
474
475   fDxPCB=40;
476   fDyPCB=40;
477
478   //  Calculate padsize along x
479   (*fDpxD)[fNsec-1]=fDpx;
480   (*fDpyD)[fNsec-1]=fDpy;
481   if (fNsec > 1) {
482     for (Int_t i=fNsec-1; i>=0; i--){ // fNsec-2
483       if (!fBending) {
484         (*fDpxD)[i]=fDpx;
485         (*fDpyD)[i]=(*fDpyD)[fNsec-1]/(*fNDiv)[i];
486       } else {
487         (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
488         (*fDpyD)[i]=fDpy;
489       }
490     }
491   }
492   //
493   // fill the arrays defining the pad segmentation boundaries
494   //
495   //  
496   //  Loop over sectors (isec=0 for secto close to the beam pipe)
497   Float_t totalLength = 0;
498   for (Int_t isec=0; isec<4; isec++) totalLength += fPcbBoards[isec]*fDxPCB;  // !!!!
499
500   fNpy = 0;   // maximum number of pads in y
501   for (Int_t isec=0; isec<4; isec++) {
502     if (isec==0) {
503       fNpxS[0] = 0;
504       fNpyS[0] = 0;
505       fCx[0]   = -totalLength/2;
506     } else {
507       fNpxS[isec] = fNpxS[isec-1] + fPcbBoards[isec]*Int_t(fDxPCB/(*fDpxD)[isec]); 
508       fNpyS[isec] = Int_t(fDyPCB/(*fDpyD)[isec]);
509       if (fNpyS[isec] >= fNpy) fNpy = fNpyS[isec]; 
510       fCx[isec]= fCx[isec-1] + fPcbBoards[isec]*fDxPCB;
511     }
512   } // sectors
513
514   fNpx = fNpxS[3];  // maximum number of pads in x
515   fCy = fDyPCB/2.;
516   //
517   fId = detectionElementId;
518 }
519
520
521
522
523
524
525
526
527
528
529