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