3f455e29d866d22821557d5fd345763d96216ace
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerSegmentation.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 classe for trigger chambers.
20 // In the present version the method use global strip coordinates except
21 // HasPad. The conversion is made via GetPadLoc2Glo.
22 // To be improved in the future.
23 //**********************************************************************
24
25 #include "AliMUONTriggerSegmentation.h"
26 #include "AliLog.h"
27 #include "Riostream.h"
28
29 //___________________________________________
30 ClassImp(AliMUONTriggerSegmentation)
31
32 AliMUONTriggerSegmentation::AliMUONTriggerSegmentation() 
33   : AliMUONVGeometryDESegmentation(),
34     fBending(0),
35     fId(0),
36     fNsec(7),
37     fNpx(999999),
38     fNpy(999999),
39     fXhit(0.),
40     fYhit(0.),
41     fIx(0),
42     fIy(0),
43     fX(0.),
44     fY(0.),
45 // add to St345SlatSegmentation
46     fLineNumber(0),
47     fRpcHalfXsize(0),
48     fRpcHalfYsize(0)
49 {
50 // Default constructor
51
52 // add to St345SlatSegmentation
53   for (Int_t i=0; i<7; i++) {
54       fNstrip[i]=0;
55       fStripYsize[i]=0.;   
56       fStripXsize[i]=0.;  
57       fModuleXmin[i]=0.;
58       fModuleXmax[i]=0.;  
59       fModuleYmin[i]=0.;  
60   }
61
62   AliDebug(1, Form("default (empty) ctor this = %p", this));
63 }
64
65
66 //___________________________________________
67 AliMUONTriggerSegmentation::AliMUONTriggerSegmentation(Bool_t bending) 
68   : AliMUONVGeometryDESegmentation(),
69     fBending(bending),
70     fId(0),
71     fNpx(999999),
72     fNpy(999999),
73     fXhit(0.),
74     fYhit(0.),
75     fIx(0),
76     fIy(0),
77     fX(0.),
78     fY(0.),
79 // add to St345SlatSegmentation
80     fLineNumber(0),
81     fRpcHalfXsize(0),
82     fRpcHalfYsize(0)
83 {
84   // Non default constructor
85   fNsec = 7;  
86 // add to St345SlatSegmentation
87   for (Int_t i=0; i<7; i++) {
88       fNstrip[i]=0;
89       fStripYsize[i]=0.;   
90       fStripXsize[i]=0.;  
91       fModuleXmin[i]=0.;
92       fModuleXmax[i]=0.;  
93       fModuleYmin[i]=0.;  
94   }
95
96   AliDebug(1, Form("ctor this = %p", this) ); 
97 }
98
99 //----------------------------------------------------------------------
100 AliMUONTriggerSegmentation::AliMUONTriggerSegmentation(const AliMUONTriggerSegmentation& rhs) : AliMUONVGeometryDESegmentation(rhs)
101 {
102 // Copy constructor
103
104   AliFatal("Not implemented.");
105 }
106 //----------------------------------------------------------------------
107 AliMUONTriggerSegmentation::~AliMUONTriggerSegmentation() 
108 {
109   // Destructor
110
111   AliDebug(1, Form("dtor this = %p", this) ); 
112 }
113 //----------------------------------------------------------------------
114 AliMUONTriggerSegmentation& AliMUONTriggerSegmentation::operator=(const AliMUONTriggerSegmentation& rhs)
115 {
116 // Protected assignement operator
117   if (this == &rhs) return *this;
118   AliFatal("Not implemented.");
119   return *this;  
120 }
121 //----------------------------------------------------------------------
122 Int_t AliMUONTriggerSegmentation::ModuleColNum(Int_t ix)
123 {
124 // returns column number (from 0 to 6) in which the (global) module 
125 // ix is sitting (could return 7 if ix=isec)
126     return TMath::Abs(ix)-Int_t(TMath::Abs(ix)/10)*10-1;
127 }
128 //----------------------------------------------------------------------
129 Bool_t AliMUONTriggerSegmentation::HasPad(Int_t ix, Int_t iy)
130 {
131 // check if steping outside the limits (iy=1,2... iy=0,1...)
132     Bool_t hasPad = true;    
133     Int_t ixGlo = 0;
134     Int_t iyGlo = 0; 
135     GetPadLoc2Glo(ix, iy, ixGlo, iyGlo);
136     if (iyGlo>=fNstrip[ModuleColNum(ixGlo)]) hasPad = false;
137     return hasPad;    
138 }
139 //____________________________________________________________________________
140 Float_t AliMUONTriggerSegmentation::Dpx(Int_t isec) const
141 {
142 // return x-strip width in sector isec
143     Float_t size = (isec<8) ? fStripXsize[isec-1] : fStripXsize[isec-2]/2.;
144     return size;
145 }
146 //____________________________________________________________________________
147 Float_t AliMUONTriggerSegmentation::Dpy(Int_t  isec) const
148 {
149 // return y-strip width in sector isec
150     Float_t size = (isec<8) ? fStripYsize[isec-1] : fStripYsize[isec-2];
151     return size;
152 }
153 //----------------------------------------------------------------------------
154 void AliMUONTriggerSegmentation::GetPadLoc2Glo(Int_t ixLoc, Int_t iyLoc, 
155                                                Int_t &ixGlo, Int_t &iyGlo)
156 {    
157 // converts ixLoc & iyLoc into ixGlo & iyGLo (module,strip number)
158     ixGlo = 0; // see AliMUONTriggerConstants::fgkModuleI
159     iyGlo = 0; // from 0 to (fNtrip-1) in module   
160     if (fBending) { 
161         ixGlo = 10*fLineNumber + ixLoc;
162         iyGlo = iyLoc - 1;
163     } else if (!fBending) {     
164         Int_t iCountStrip = 0;  
165         for (Int_t iModule=0; iModule<fNsec; iModule++) {               
166             for (Int_t iStrip=0; iStrip<fNstrip[iModule]; iStrip++) {
167                 if ((ixLoc-1)==iCountStrip) {
168                     ixGlo = 10*fLineNumber + iModule + 1;
169                     iyGlo = iStrip;
170                 }
171                 iCountStrip++;
172             }
173         }
174     }
175 //    printf(" in GetPadLoc2Glo fbending ixLoc iyLoc ixGlo iyGlo %i %i %i %i \n",fBending,ixLoc,iyLoc,ixGlo,iyGlo);
176 }
177
178 //----------------------------------------------------------------------------
179 void AliMUONTriggerSegmentation::GetPadGlo2Loc(Int_t ixGlo, Int_t iyGlo, 
180                                                Int_t &ixLoc, Int_t &iyLoc)
181 {    
182 // converts ixGlo & iyGlo into ixLoc & iyLoc 
183     ixLoc = 0; 
184     iyLoc = 0; 
185     if (fBending) { 
186         ixLoc = ModuleColNum(ixGlo) + 1;
187         iyLoc = iyGlo + 1;
188     } else if (!fBending) {     
189         Int_t iCountStrip = 1;  
190         for (Int_t iModule=0; iModule<fNsec; iModule++) {               
191             for (Int_t iStrip=0; iStrip<fNstrip[iModule]; iStrip++) {
192                 if ((iModule==ModuleColNum(ixGlo))&&(iStrip==iyGlo)) {
193                     iyLoc = 1;              
194                     ixLoc = iCountStrip;
195                 }               
196                 iCountStrip++;
197             }
198         }
199     }    
200 //    printf(" in GetPadGlo2Loc fBending ixGlo iyGlo ixLoc iyLoc %i %i %i %i %i \n",fBending,ixGlo,iyGlo,ixLoc,iyLoc);
201 }
202
203 //----------------------------------------------------------------------------
204 void AliMUONTriggerSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y) 
205 {
206 // Returns local real coordinates (x,y) for local pad coordinates (ix,iy)
207
208     x = 0.;
209     y = 0.;
210     Int_t iModule = ModuleColNum(ix); // find column number (0-6)
211     if (fBending) {
212         if (iModule==0) {
213             x =  fStripXsize[iModule]/ 2.;
214         } else {        
215         x = fModuleXmax[iModule-1] + fStripXsize[iModule]/2.;
216         }
217         y =  fModuleYmin[iModule] + 
218             iy*fStripYsize[iModule] + fStripYsize[iModule]/2.;
219     } else if (!fBending) {
220         if (ModuleColNum(ix)==6 && iy>7) {
221             x = fModuleXmin[iModule] + 8*fStripXsize[iModule] +
222                 (iy-8)*fStripXsize[iModule]/2. + fStripXsize[iModule]/4.;
223         } else {            
224             x = fModuleXmin[iModule] + 
225                 iy*fStripXsize[iModule] + fStripXsize[iModule]/2.;
226         }
227         y =  fModuleYmin[iModule] + fStripYsize[iModule] / 2.;
228     }    
229     x = x - fRpcHalfXsize;
230     y = y - fRpcHalfYsize;
231
232 //    printf(" in GetPadC fBending ix iy x y %i %i %i %f %f \n",fBending,ix,iy,x,y);
233 }
234
235 //_____________________________________________________________________________
236 void AliMUONTriggerSegmentation::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy) 
237 {
238 //  Returns global pad coordinates (ix,iy) for local real coordinates (x,y)
239     ix = -1;
240     iy = -1;
241
242     x = x + fRpcHalfXsize;
243     y = y + fRpcHalfYsize;
244 // find module number    
245     Int_t modNum=0;    
246     for (Int_t iModule=0; iModule<fNsec; iModule++) { // modules
247         if ( x > fModuleXmin[iModule] && x < fModuleXmax[iModule] ) {
248             ix = 10*fLineNumber + iModule + 1;
249             modNum = iModule;       
250         }
251     }
252
253 // find strip number 
254     Float_t yMin = 0.;    
255     Float_t yMax = fModuleYmin[modNum];
256     Float_t xMin = 0.;
257     Float_t xMax = fModuleXmin[modNum];
258     if (ix!=0) {
259         for (Int_t iStrip=0; iStrip<fNstrip[modNum]; iStrip++) {
260             if (fBending) {
261                 yMin = yMax;
262                 yMax = yMin + fStripYsize[modNum];
263                 if (y > yMin && y < yMax) iy = iStrip;
264             } else if (!fBending) {
265                 xMin = xMax;
266                 if (modNum==6 && iStrip>7) {
267                     xMax = xMin + fStripXsize[modNum]/2.;
268                 } else {                    
269                     xMax = xMin + fStripXsize[modNum];
270                 }               
271                 if (x > xMin && x < xMax) iy = iStrip;
272             } //
273         } // loop on strips
274     } // if ix!=0
275 //    printf("in GetPadI fBending x y ix iy %i %f %f %i %i \n",fBending,x,y,ix,iy);
276 }
277 //-------------------------------------------------------------------------
278 void AliMUONTriggerSegmentation::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
279 {
280 //  Returns global pad coordinates (ix,iy) for local real coordinates (x,y)
281   GetPadI(x, y, ix, iy);
282 }
283
284 //-------------------------------------------------------------------------
285 void AliMUONTriggerSegmentation::SetLineNumber(Int_t iLineNumber){
286 // Set line number
287     fLineNumber = iLineNumber;    
288 }
289 //-------------------------------------------------------------------------
290 void AliMUONTriggerSegmentation::SetPad(Int_t ix, Int_t iy)
291 {
292   // Sets virtual pad coordinates, needed for evaluating pad response 
293   // outside the tracking program 
294   GetPadC(ix,iy,fX,fY);
295   fIx = ix; // used in IntegrationLimits
296   fIy = iy;    
297   fSector=Sector(ix,iy);
298 }
299 //---------------------------------------------------------------------------
300 void AliMUONTriggerSegmentation::SetHit(Float_t x, Float_t y)
301 {
302   // Set current hit 
303   fXhit = x;
304   fYhit = y;
305 }
306 //----------------------------------------------------------------------------
307 void AliMUONTriggerSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
308 {
309   // Set current hit 
310   SetHit(xhit, yhit);
311 }
312
313 //--------------------------------------------------------------------------
314 Int_t AliMUONTriggerSegmentation::Sector(Int_t ix, Int_t iy) 
315 {
316 // determine segmentation zone from pad coordinates (from 1 to 8)
317     if (!fBending && ModuleColNum(ix)==6 && iy>7) {
318         return 8; // sector 8: diff. strip width within same module
319     } else {
320         return ModuleColNum(ix)+1;
321     }
322 }
323
324 //-----------------------------------------------------------------------------
325 void AliMUONTriggerSegmentation::IntegrationLimits(Float_t& x1,Float_t& x2,
326                                                    Float_t& x3, Float_t& x4) 
327 {
328 // need to return (only) x4 = dist. betwwen the hit and the closest border of
329 // the current strip
330
331     Int_t ix,iy;
332     Float_t xstrip,ystrip;
333     GetPadI(fXhit,fYhit,ix,iy);
334     GetPadC(ix,iy,xstrip,ystrip);
335     AliDebug(1,Form("fXhit,Yhit=%e,%e xstrip,ystrip=%e,%e\n",
336                     fXhit,fYhit,xstrip,ystrip));
337     x1= (fBending) ? fYhit : fXhit;  // hit y (bending) / x (!bending) position
338     x2= (fBending) ? ystrip : xstrip; // y or x coord. of the main strip
339     x3= (fBending) ? fY : fX;          // current strip real y or x coord.
340     Int_t modNum = ModuleColNum(fIx);
341
342     // find the position of the 2 borders of the current strip
343     Float_t min = 0.;
344     Float_t max = 0.;    
345     if (fBending) {
346         min = x3 - fStripYsize[modNum]/2.;
347         max = x3 + fStripYsize[modNum]/2.;      
348     } else {
349         if (modNum==6 && fIy>7) { // equivalent to fSector == 8
350             min = x3 - fStripXsize[modNum]/4.;
351             max = x3 + fStripXsize[modNum]/4.;  
352         } else 
353             min = x3 - fStripXsize[modNum]/2.;
354             max = x3 + fStripXsize[modNum]/2.;          
355     }    
356     // dist. between the hit and the closest border of the current strip
357     x4 = (TMath::Abs(max-x1) > TMath::Abs(min-x1)) ? 
358       TMath::Abs(min-x1):TMath::Abs(max-x1);
359   
360     AliDebug(1,Form("Bending %d x1=%e x2=%e x3=%e x4=%e xmin,max=%e,%e\n",
361                     fBending,x1,x2,x3,x4,min,max));
362 }
363
364
365 //-----------------------------------------------------------------------------
366 void AliMUONTriggerSegmentation::
367 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) 
368 {
369 //-----------------BENDING-----------------------------------------
370 // Returns list of 10 next neighbours for given X strip (ix, iy)  
371 // neighbour number 4 in the list -                     
372 // neighbour number 3 in the list  |                    
373 // neighbour number 2 in the list  |_ Upper part             
374 // neighbour number 1 in the list  |            
375 // neighbour number 0 in the list -           
376 //      X strip (ix, iy) 
377 // neighbour number 5 in the list -       
378 // neighbour number 6 in the list  | _ Lower part
379 // neighbour number 7 in the list  |
380 // neighbour number 8 in the list  | 
381 // neighbour number 9 in the list -
382
383 //-----------------NON-BENDING-------------------------------------
384 // Returns list of 10 next neighbours for given Y strip (ix, iy)  
385 // neighbour number 9 8 7 6 5 (Y strip (ix, iy)) 0 1 2 3 4 in the list
386 //                  \_______/                    \_______/
387 //                    left                         right
388
389     Int_t absiX = TMath::Abs(iX); 
390     Int_t modNum = ModuleColNum(absiX); // from 0 to 6
391     Int_t nStrip = fNstrip[modNum];    
392     
393     if (fBending) {
394         Int_t iCandidateUp, iCandidateDo;
395         Int_t j;
396         
397         *Nlist = 10;
398         for (Int_t i=0; i<10; i++) Xlist[i]=Ylist[i]=0;
399         
400         if (iY < nStrip) {          
401             for (Int_t i=0; i<5; i++) {
402                 j = i + 5;
403                 iCandidateUp = iY + (i + 1);
404                 iCandidateDo = iY - (i + 1);
405                 if (iCandidateUp < nStrip) { 
406                     Xlist[i] = iX;
407                     Ylist[i] = iCandidateUp;  
408                 }
409                 if (iCandidateDo >= 0) { 
410                     Xlist[j] = iX;
411                     Ylist[j] = iCandidateDo;  
412                 }
413             }       
414         } // iY < nStrip        
415
416     } else { // non-bending
417          
418       Int_t iCandidateLeft, iCandidateRight;
419       Int_t iNewCandidateRight=0; 
420       Int_t iNewCandidateLeft=0;
421 // first strip number on the right of the left module  
422       if ( modNum!=0 && absiX!=52 ) 
423           iNewCandidateLeft = fNstrip[modNum-1]-1;
424       Int_t j;
425       
426       *Nlist = 10;
427       for (Int_t i=0; i<10; i++) Xlist[i]=Ylist[i]=0;
428       
429       if (iY < nStrip) {
430           
431           for (Int_t i=0; i<5; i++) {
432               j = i + 5;
433               iCandidateRight = iY + (i + 1);
434               iCandidateLeft  = iY - (i + 1);
435               if (iCandidateRight < nStrip) { // strip in same module  
436                   Xlist[i] = absiX;
437                   Ylist[i] = iCandidateRight;  
438               } else if (modNum!=6) {   // need to scan the module on the right
439                   Xlist[i] = absiX+1;
440                   Ylist[i] = iNewCandidateRight;  
441                   iNewCandidateRight++;
442               }
443               
444               if (iCandidateLeft >=0 ) { // strip in same module
445                   Xlist[j] = absiX;
446                   Ylist[j] = iCandidateLeft;  
447               } else if ( iNewCandidateLeft !=0) {
448                   Xlist[j] = absiX-1;
449                   Ylist[j] = iNewCandidateLeft;  
450                   iNewCandidateLeft--;
451               }
452           }
453           
454           if (iX<0) {                                  // left side of chamber 
455               for (Int_t i=0; i<10; i++) { 
456                   if (Xlist[i]!=0) Xlist[i]=-Xlist[i]; 
457               }
458           }
459           
460       } // iY < nStrip
461     } // non-bending
462
463 //    for (Int_t i=0; i<10; i++) {
464 //      printf("AliMUONTriggerSegmentation LOC fBending i ix iy = %i %i %i %i \n",fBending,i,Xlist[i],Ylist[i]);
465 //   }
466 }
467
468 //--------------------------------------------------------------------------
469 void AliMUONTriggerSegmentation::Init(Int_t detectionElementId,
470                                       Int_t nStrip[7],
471                                       Float_t stripYsize[7],
472                                       Float_t stripXsize[7],
473                                       Float_t offset)
474 {
475 //    printf(" fBending: %d \n",fBending);
476     
477     Int_t nStripMax = 0;
478     if (fBending) nStripMax = nStrip[0];
479     
480     for (Int_t i=0; i<7; i++) {
481         fNstrip[i]=nStrip[i];
482         fStripYsize[i]=stripYsize[i];
483         fStripXsize[i]=stripXsize[i];
484         fModuleYmin[0]=0.;
485     }
486 // take care of offset in Y in chamber 5, first module
487     fModuleYmin[0] = offset;
488     
489     Float_t tmp = 0.;  
490     Int_t npad = 0;  // number of pad in x and y
491     for (Int_t iModule=0; iModule<fNsec; iModule++) { // modules        
492         fModuleXmin[iModule] = tmp;      
493         npad = npad + fNstrip[iModule];
494         if (fBending) {
495             fModuleXmax[iModule] = 
496                 fModuleXmin[iModule] + fStripXsize[iModule];
497         } else if (!fBending) {
498             if (iModule<6) {
499                 fModuleXmax[iModule] = 
500                     fModuleXmin[iModule] + 
501                     fStripXsize[iModule]*fNstrip[iModule];
502             } else if (iModule==6) { 
503                 fModuleXmax[iModule] = 
504                     fModuleXmin[iModule] + 
505                     (fStripXsize[iModule]*fNstrip[iModule]/2) +
506                     (fStripXsize[iModule]/2.*fNstrip[iModule]/2);
507             }     
508         }
509         tmp = fModuleXmax[iModule];      
510         
511 // calculate nStripMax in x & y
512         if (fBending) {
513             if (fNstrip[iModule] > nStripMax) nStripMax = fNstrip[iModule];
514         } else if (!fBending) {
515             for (Int_t iStrip=0; iStrip<fNstrip[iModule]; iStrip++) nStripMax++;
516         }
517     } // loop on modules
518
519 // associate nStripMax
520 //   fNpx = (fBending) ? fNsec : nStripMax;
521 //   fNpy = (fBending) ? nStripMax : 1;
522     fNpx = 124; // tot num of modules (like with old segmentation)
523     fNpy = 64; // max number of y strips within one module
524
525 // calculate half size in x & y (to shift local coordinate ref. system)
526   fRpcHalfXsize = 0;
527   fRpcHalfYsize = 0;  
528   if (fBending) {
529       for (Int_t iModule=0; iModule<fNsec; iModule++)  
530           fRpcHalfXsize = fRpcHalfXsize + fStripXsize[iModule];      
531       fRpcHalfYsize = fNstrip[1] * fStripYsize[1];
532   } else if (!fBending) {
533       fRpcHalfXsize = fModuleXmax[6];
534       fRpcHalfYsize = fStripYsize[1];
535   }
536   fRpcHalfXsize = fRpcHalfXsize / 2.;
537   fRpcHalfYsize = fRpcHalfYsize / 2.;  
538
539 /*
540   printf(" fNpx fNpy fRpcHalfXsize fRpcHalfYsize = %i %i %f %f \n",
541          fNpx,fNpy,fRpcHalfXsize,fRpcHalfYsize);
542
543   for (Int_t iModule=0; iModule<fNsec; iModule++) {
544       printf(" iModule fModuleXmin fModuleXmax fModuleYmin fStripXsize fStripYsize %i %f %f %f %f %f\n",
545              iModule,fModuleXmin[iModule],fModuleXmax[iModule],
546              fModuleYmin[iModule],
547              fStripXsize[iModule],fStripYsize[iModule]);
548              }
549
550   for (Int_t iModule=0; iModule<fNsec; iModule++) {
551       printf(" iModule fNstrip fStripXsize fStripYsize %i %i %f %f \n",
552              iModule,fNstrip[iModule],
553              fStripXsize[iModule],fStripYsize[iModule]);
554   }
555 */
556
557   fId = detectionElementId;
558 }
559
560 //_____________________________________________________________________________
561 void
562 AliMUONTriggerSegmentation::Print(Option_t*) const
563 {
564 // Printing
565
566   cout << "fId=" << fId << " fBending=" << fBending << " fNsec=" 
567   << fNsec << " Nx,Ny=" << fNpx << "," << fNpy 
568   << " LineNumber=" << fLineNumber 
569   << " fRpcHalfSize(X,Y)=" << fRpcHalfXsize << "," << fRpcHalfYsize
570   << endl;
571   
572   for (Int_t iModule=0; iModule<fNsec; iModule++) 
573   { 
574     cout << "Module " << iModule 
575     << " xmin,xmax=" << fModuleXmin[iModule] 
576     << "," << fModuleXmax[iModule] 
577     << " ymin=" << fModuleYmin[iModule]
578     << " StripSize(X,Y)=(" << fStripXsize[iModule] << ","
579     << fStripYsize[iModule] << ")"
580     << endl;
581   }                    
582 }
583
584
585
586
587