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