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