]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSegmentationV1.cxx
AliMUONTriggerConstants added
[u/mrichter/AliRoot.git] / MUON / AliMUONSegmentationV1.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 /*
17 $Log$
18 Revision 1.1.2.2  2000/06/12 07:57:43  morsch
19 include TMath.cxx
20
21 Revision 1.1.2.1  2000/06/09 21:41:29  morsch
22 AliMUONSegmentationV1 code  from  AliMUONSegResV1.cxx
23
24 */
25
26
27 /////////////////////////////////////////////////////////
28 //  Manager and hits classes for set:MUON version LYON //
29 /////////////////////////////////////////////////////////
30
31 #include <TMath.h>
32 #include "AliMUONChamber.h"
33 #include "AliMUONSegmentationV1.h"
34
35 //___________________________________________
36 ClassImp(AliMUONSegmentationV1)
37
38 AliMUONSegmentationV1::AliMUONSegmentationV1(const AliMUONSegmentationV1& segmentation)
39 {
40 // Dummy copy constructor
41 }
42
43
44 AliMUONSegmentationV1::AliMUONSegmentationV1()
45
46 {
47   // initizalize the class with default settings
48     fNzone=1;
49     fDAnod=0.0;
50     fDpx=0.0;
51     fDpx=0.0; // forces crash if not initialized by user
52     fNZoneCut[0]=0;
53     fSensOffset=0;
54 }
55
56
57 void AliMUONSegmentationV1::Init(AliMUONChamber* Chamber)
58 {
59     // valid only for T5/6
60     // beware : frMin is SENSITIVE radius by definition.
61     frSensMin2 = (Chamber->RInner())*(Chamber->RInner());
62     frSensMax2 = (Chamber->ROuter())*(Chamber->ROuter());
63     fNpx=(Int_t) (Chamber->ROuter()/fDpx) + 1;
64     fNpy=(Int_t) (Chamber->ROuter()/fDpy) + 1;
65     //    fNwire=3;
66     DefaultCut();
67     fCorr=0;
68 }
69
70 void AliMUONSegmentationV1::DefaultCut(void)
71 {
72 // Set the default cuts
73     SetNzone(3);
74     AddCut(0,5*6,18*8);
75     AddCut(0,9*6,15*8);
76     AddCut(0,11*6,12*8);
77     AddCut(0,12*6,9*8);
78     AddCut(0,13*6,6*8);
79     AddCut(1,6*6,20*12);
80     AddCut(1,12*6,18*12);
81     AddCut(1,15*6,15*12);
82     AddCut(1,18*6,12*12);
83     AddCut(1,21*6,9*12);
84     SetSensOffset(3.0);
85     SetDAnod(0.325);
86 }
87
88 Int_t AliMUONSegmentationV1::GetiAnod(Float_t xhit)
89 {
90 // Get anode number
91     Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1;
92     return (xhit>0) ? kwire : -kwire ;
93 }
94
95 Float_t AliMUONSegmentationV1::GetAnod(Float_t xhit)
96 {
97 // Get anode position
98     Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1; // to be compatible ...
99     return (xhit>0) ? fDAnod*(kwire-0.5)+fSensOffset : -fDAnod*(kwire-0.5)-fSensOffset ;
100 }
101
102
103 void AliMUONSegmentationV1::SetPadSize(Float_t p1, Float_t p2)
104 {
105 // For chamber T5/6 p1 and p2 should be same for each zone
106     fDpx=p1;
107     fDpy=p2;
108 }
109
110 void AliMUONSegmentationV1::
111 GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
112 {
113 //  returns pad coordinates (ix,iy) for given real coordinates (x,y)
114 //
115     ix = (x>0)? Int_t((x-fSensOffset)/fDpx)+1 : Int_t((x+fSensOffset)/fDpx)-1;
116     iy = (y>0)? Int_t((y-fSensOffset)/fDpy)+1 : Int_t((y+fSensOffset)/fDpy)-1;
117 }
118
119 void AliMUONSegmentationV1::
120 GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
121 {
122 //  returns real coordinates (x,y) for given pad coordinates (ix,iy)
123 //
124     x = (ix>0) ? (Float_t(ix)-0.5)*fDpx+fSensOffset : (Float_t(ix)+0.5)*fDpx-fSensOffset;
125     y = (iy>0) ? (Float_t(iy)-0.5)*fDpy+fSensOffset : (Float_t(iy)+0.5)*fDpy-fSensOffset;
126 }
127
128 void AliMUONSegmentationV1::AddCut(Int_t Zone, Int_t nX, Int_t nY)
129 {
130 // the pad nX,nY is last INSIDE zone Zone. First pad is labelled 1 and not 0
131     if (Zone+1>=fNzone) 
132 // no cut for last Zone : it is the natural boundary of the chamber
133         printf("AliMUONSegmentationV1::AddCut ==> Zone %d not allowed !\n",Zone);
134     fZoneX[Zone][fNZoneCut[Zone]] = nX;
135     fZoneY[Zone][fNZoneCut[Zone]] = nY;
136     fNZoneCut[Zone]++;
137 }
138
139 Int_t AliMUONSegmentationV1::GetZone(Float_t X, Float_t Y)
140 {
141 // Get segmentation zone
142     Int_t iX, iY;
143     GetPadIxy(X,Y,iX,iY);
144     return GetZone( iX , iY );
145 }
146
147 Int_t AliMUONSegmentationV1::GetZone(Int_t nX, Int_t nY)
148 {
149 // Beware : first pad begins at 1 !!
150     Int_t aX =  TMath::Abs(nX);
151     Int_t aY =  TMath::Abs(nY);
152     Int_t zone=fNzone-1;
153     for (Int_t iZone=fNzone-2;iZone>=0;iZone--) 
154     {
155         for (Int_t iCut=0;iCut<fNZoneCut[iZone];iCut++)
156             if ( aY<=fZoneY[iZone][iCut] && aX<=fZoneX[iZone][iCut] )
157             {
158                 zone=iZone;
159                 break;
160             } 
161     }
162     return zone;
163 }
164
165 void AliMUONSegmentationV1::
166 SetHit(Float_t xhit, Float_t yhit)
167 {
168 // Find the wire position (center of charge distribution)
169     fxhit=xhit;
170     fyhit=yhit;
171 }
172
173 void AliMUONSegmentationV1::
174 SetPad(Int_t ix, Int_t iy)
175 {
176 // Set current pad position
177     GetPadCxy(ix,iy,fx,fy);
178 }
179
180
181 void AliMUONSegmentationV1::SetPadCoord(Int_t iX, Int_t iY)
182 {    
183 // Set current pad coordinates
184 GetPadCxy(iX,iY,fx,fy);
185  Float_t radius2;
186  if ( ( (radius2=fx*fx+fy*fy) > frSensMax2 || radius2 < frSensMin2 ) 
187       && MorePads() )
188      NextPad();
189 }
190
191 void AliMUONSegmentationV1::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
192 {
193     //
194     // Find the wire position (center of charge distribution)
195     Float_t x0a=GetAnod(xhit);
196     fxhit=x0a;
197     fyhit=yhit;
198     //
199     // and take fNsigma*sigma around this center
200     Float_t x01=x0a  - dx;
201     Float_t x02=x0a  + dx;
202     Float_t y01=yhit - dy;
203     Float_t y02=yhit + dy;
204
205     // Do not cross over frames...
206     if (x01 * x0a < 0) 
207       x01 = TMath::Sign(fSensOffset, x0a);
208     if (x02 * x0a < 0) 
209       x02 = TMath::Sign(fSensOffset, x0a);
210     if (y01 * yhit < 0) 
211       y01 = TMath::Sign(fSensOffset, yhit);
212     if (y02 * yhit < 0) 
213       y02 = TMath::Sign(fSensOffset, yhit);
214     //
215     // find the pads over which the charge distributes
216     GetPadIxy(x01,y01,fixmin,fiymin);
217     GetPadIxy(x02,y02,fixmax,fiymax);
218     // 
219     // Set current pad to lower left corner
220     fix=fixmin;
221     fiy=fiymin;
222     SetPadCoord(fix,fiy);
223 }
224
225 void AliMUONSegmentationV1::NextPad()
226 {
227   // 
228   // Step to next pad in integration region
229     if (fix != fixmax) {
230         fix++;
231     } else if (fiy != fiymax) {
232         fix=fixmin;
233         fiy++;
234     } else 
235         printf("\n Error: Stepping outside integration region\n ");
236     SetPadCoord(fix,fiy);
237 }
238
239 Int_t AliMUONSegmentationV1::MorePads()
240 {
241 //
242 // Are there more pads in the integration region
243
244     if (fix == fixmax && fiy == fiymax) {
245         return 0;
246     } else {
247         return 1;       
248     }
249 }
250
251 Int_t AliMUONSegmentationV1::IsParallel2(Int_t iX, Int_t iY)
252 {
253 // test if the pad is read in parallel for zone 2
254 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
255 // returns 1 or 2 if read in parallel, 
256 // according to the actual number in the chain, 0 else
257 //
258 // chainage is        result is 
259 // 1  2  3  1  2  3   1 1 1 2 2 2     y
260 // 7  8  9 10 11 12   0 0 0 0 0 0     ^
261 // 4  5  6  4  5  6   1 1 1 2 2 2     +->x
262 //
263
264     if (iY%3==1) return 0;
265     return (iX%6)/3+1;
266 }
267
268 Int_t AliMUONSegmentationV1::IsParallel3(Int_t iX, Int_t iY)
269 {
270 // test if the pad is read in parallel for zone 3
271 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
272 // returns 1,2 or 3 if read in parallel, 
273 // according to the actual number in the chain, 0 else
274 //
275 // chainage is                 result is
276 //16  2  3  1  2  3  1  2  3   0 1 1 1 2 2 2 3 3
277 // 7  8  9 10 11 12 13 14 15   0 0 0 0 0 0 0 0 0
278 // 4  5  6  4  5  6  4  5  6   1 1 1 2 2 2 3 3 3
279 //
280
281     if (iY%3==1) return 0;
282     return (iX%9)/3+1 - (iY%3==2 && iX%3==0);
283 }
284
285 Int_t AliMUONSegmentationV1::NParallel2(Int_t iX, Int_t iY)
286 {
287 // returns the number of pads connected in parallel for zone 2
288 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
289 //
290 // result is
291 // 2 2 2 2 2 2
292 // 1 1 1 1 1 1
293 // 2 2 2 2 2 2
294 //
295
296     if (iY%3==1) return 1;
297     return 2;
298 }
299
300 Int_t AliMUONSegmentationV1::NParallel3(Int_t iX, Int_t iY)
301 {
302 // test if the pad is read in parallel for zone 3
303 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
304 // returns 1,2 or 3 if read in parallel, 
305 // according to the actual number in the chain, 0 else
306 //
307 // result is 
308 // 1 3 3 2 3 3 2 3 3 
309 // 1 1 1 1 1 1 1 1 1
310 // 3 3 3 3 3 3 3 3 3
311 //
312
313     if (iY%3==1) return 1;
314     if (iY%3==2 && iX%9==0) return 1;
315     return 3 - (iY%3==2 && iX%3==0);
316 }
317
318
319 Int_t AliMUONSegmentationV1::Ix(Int_t trueX, Int_t trueY)
320 {
321 // returns the X number of pad which corresponds to the logical 
322 // channel, expressed in x and y.
323
324     Int_t wix = TMath::Abs(trueX)-1;
325     Int_t wiy = TMath::Abs(trueY)-1;
326     Int_t zone = GetZone(trueX,trueY);
327     Int_t par3;
328     switch (zone) {
329     case 0: return trueX;
330     case 1:
331         if (IsParallel2(wix,wiy) == 2)
332             return (trueX>0)? trueX-3 : trueX+3 ;
333         return trueX;
334     case 2:
335         if ( (par3= IsParallel3(wix,wiy)) )
336             return (trueX>0) ? trueX-3*(par3-1) : trueX+3*(par3-1) ;
337         return trueX ;
338     default :
339         printf("Couille dans AliMUONSegmentationV1::ix\n");
340     }
341     return -1;
342 }
343
344 Int_t AliMUONSegmentationV1::Ix()
345 {
346 // returns the X number of pad which has to increment charge
347 // due to parallel read-out
348 return Ix(fix,fiy);
349 }
350
351 Int_t AliMUONSegmentationV1::ISector()
352 {
353 // This function is of no use for this kind of segmentation.
354     return GetZone(fix,fiy);
355 }
356
357 void AliMUONSegmentationV1::SigGenInit(Float_t x,Float_t y,Float_t z)
358 {
359 //
360 //  Initialises pad and wire position during stepping
361     fxt =x;
362     fyt =y;
363     GetPadIxy(x,y,fixt,fiyt);
364     fiwt= GetiAnod(x);
365
366 }
367
368 Int_t AliMUONSegmentationV1::SigGenCond(Float_t x,Float_t y,Float_t z)
369 {
370 //
371 //  Signal will be generated if particle crosses pad boundary or
372 //  boundary between two wires. 
373     Int_t ixt;
374     Int_t iyt;
375     GetPadIxy(x,y,ixt,iyt);
376     Int_t iwt= GetiAnod(x);
377     
378     if ((ixt != fixt) || (iyt !=fiyt) || (iwt != fiwt)) {
379         return 1;
380     } else {
381         return 0;
382     }
383 }
384
385 void AliMUONSegmentationV1::
386 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
387 {
388 // Get integration limits
389     x1=fxhit-fx-fDpx/2.;
390     x2=x1+fDpx;
391     y1=fyhit-fy-fDpy/2.;
392     y2=y1+fDpy;    
393 }
394
395 void AliMUONSegmentationV1::GetNParallelAndOffset(Int_t iX, Int_t iY,Int_t
396 *Nparallel, Int_t* Offset)
397 {
398 // Get parallel pad
399     Int_t wix = TMath::Abs(iX)-1;
400     Int_t wiy = TMath::Abs(iY)-1;
401     Int_t zone = GetZone(iX,iY);
402     switch (zone) {
403     case 0: 
404         *Nparallel=1;
405         *Offset=0;
406         break;
407     case 1:
408         *Nparallel = NParallel2(wix,wiy);
409         (iX>0) ? *Offset =3 : *Offset = -3;
410         if (IsParallel2(wix,wiy)>1)
411             printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n");
412         break;
413     case 2:
414         *Nparallel = NParallel3(wix,wiy);
415         (iX>0) ? *Offset =3 : *Offset = -3;
416         if (IsParallel3(wix,wiy)>1)
417             printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n");
418         break;
419     }
420 }
421
422
423 Float_t AliMUONSegmentationV1::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t *Offset)
424 {
425 //
426 // Computes the offset for which the physical pad has the minimum distance squared
427 // (returned value) to the given coordinates
428
429     Int_t nPara,offset;
430     GetNParallelAndOffset(iX,iY,&nPara,&offset);
431     Float_t d2min=1E10;
432     for (Int_t i=0;i<nPara; i++)
433     {
434         Float_t x,y;
435         GetPadCxy(iX+i*offset,iY,x,y);
436         Float_t d2=(x-X)*(x-X) + (y-Y)*(y-Y);
437         if ( d2min > d2)
438         {
439             d2min = d2;
440             *Offset = i*offset;
441         }
442     }
443     return d2min; 
444 }
445
446 void AliMUONSegmentationV1::CleanNeighbours(Int_t* Nlist, Int_t *Xlist, 
447         Int_t *Ylist)
448 {
449 // In the raw neighbours list, some pads do not exist 
450 // and some others are read in parallel ...
451 // So we prune non-existing neighbours from the list (event if this should be
452 // at last not be a problem due to the clustering algorithm...)
453
454     Int_t nTot=0;
455     for (Int_t nList=0;nList<*Nlist;nList++)
456     {
457         // prune if it does not exist
458         if ( Xlist[nList]==0 || Ylist[nList]==0 )
459             continue;
460         // compute true position
461         Xlist[nTot] = Ix(Xlist[nList],Ylist[nList]) ;
462         Ylist[nTot] = Ylist[nList] ;
463         // and prune if it does already exist
464         Int_t nTest;
465         for (nTest=0;nTest<nTot; nTest++)
466         {
467             if ( Xlist[nTest]==Xlist[nTot] && Ylist[nTest]==Ylist[nTot])
468                 // we found it
469                 break ;
470         }
471         if (nTest==nTot)
472             nTot++;
473     }
474     *Nlist = nTot;
475 }
476
477 void AliMUONSegmentationV1::
478 NeighboursNonDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[12], Int_t Ylist[12])
479 {
480 // returns the X number of pad which has to increment charge
481 // due to parallel read-out
482
483     Int_t nParallel, offset;
484     GetNParallelAndOffset(iX,iY,&nParallel,&offset);
485 //
486 // now fill raw list of neighbours
487     *Nlist=4*nParallel;
488     Xlist[0]=Xlist[1]=iX;Xlist[2]=iX-1;Xlist[3]=iX+1;
489     Ylist[0]=iY-1;Ylist[1]=iY+1;Ylist[2]=Ylist[3]=iY;
490     if (nParallel>1) {
491         Xlist[4]=Xlist[5]=iX+offset;Xlist[6]=iX+offset-1;Xlist[7]=iX+offset+1;
492         Ylist[4]=iY-1;Ylist[5]=iY+1;Ylist[6]=Ylist[7]=iY;
493         if (nParallel>2) {
494             Xlist[8]=Xlist[9]=iX+2*offset;Xlist[10]=iX+2*offset-1;Xlist[11]=iX+2*offset+1;
495             Ylist[8]=iY-1;Ylist[9]=iY+1;Ylist[10]=Ylist[11]=iY;
496         }
497     }
498     CleanNeighbours(Nlist,Xlist,Ylist);
499 }
500
501 void AliMUONSegmentationV1::
502 NeighboursDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[24], Int_t Ylist[24])
503 {
504 // returns the X number of pad which has to increment charge
505 // due to parallel read-out
506
507     Int_t nParallel, offset;
508     GetNParallelAndOffset(iX,iY,&nParallel,&offset);
509 //
510 // now fill raw list of neighbours
511     *Nlist=0;
512     for (Int_t i=0;i<nParallel;i++)
513         for (Int_t dx=-1;dx<2;dx++)
514             for (Int_t dy=-1;dy<2;dy++)
515             {
516                 if (dx==dy && dy==0)
517                     continue; 
518                 Xlist[*Nlist] = iX + dx + i*offset;
519                 Ylist[*Nlist] = iY + dy;
520                 (*Nlist)++;
521             }
522     CleanNeighbours(Nlist,Xlist,Ylist);
523 }
524
525 void AliMUONSegmentationV1::Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, 
526                                        Int_t Xlist[24], Int_t Ylist[24])
527 {
528 // Get neighbours
529 NeighboursDiag(iX,iY,Nlist,Xlist,Ylist);
530 }
531
532
533 void AliMUONSegmentationV1::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
534 {
535 // Return a test point
536     n=1;
537     x[0]=(TMath::Sqrt(frSensMax2)-TMath::Sqrt(frSensMin2))/2/TMath::Sqrt(2.);
538     y[0]=x[0];
539 }
540
541 AliMUONSegmentationV1& AliMUONSegmentationV1::operator =(const AliMUONSegmentationV1 & rhs)
542 {
543 // Dummy assignment operator
544     return *this;
545 }