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