1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.3 2000/06/29 12:34:09 morsch
19 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
20 it usable with any other geometry class. The link to the object to which it belongs is
21 established via an index. This assumes that there exists a global geometry manager
22 from which the pointer to the parent object can be obtained (in our case gAlice).
24 Revision 1.2 2000/06/15 07:58:48 morsch
25 Code from MUON-dev joined
27 Revision 1.1.2.2 2000/06/12 07:57:43 morsch
30 Revision 1.1.2.1 2000/06/09 21:41:29 morsch
31 AliMUONSegmentationV1 code from AliMUONSegResV1.cxx
36 /////////////////////////////////////////////////////////
37 // Manager and hits classes for set:MUON version LYON //
38 /////////////////////////////////////////////////////////
41 #include "AliMUONChamber.h"
42 #include "AliMUONSegmentationV1.h"
46 //___________________________________________
47 ClassImp(AliMUONSegmentationV1)
49 AliMUONSegmentationV1::AliMUONSegmentationV1(const AliMUONSegmentationV1& segmentation)
51 // Dummy copy constructor
55 AliMUONSegmentationV1::AliMUONSegmentationV1()
58 // initizalize the class with default settings
62 fDpx=0.0; // forces crash if not initialized by user
68 void AliMUONSegmentationV1::Init(Int_t chamber)
70 // valid only for T5/6
71 // beware : frMin is SENSITIVE radius by definition.
72 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
73 AliMUONChamber* iChamber=&(pMUON->Chamber(chamber));
75 frSensMin2 = (iChamber->RInner())*(iChamber->RInner());
76 frSensMax2 = (iChamber->ROuter())*(iChamber->ROuter());
77 fNpx=(Int_t) (iChamber->ROuter()/fDpx) + 1;
78 fNpy=(Int_t) (iChamber->ROuter()/fDpy) + 1;
84 void AliMUONSegmentationV1::DefaultCut(void)
86 // Set the default cuts
102 Int_t AliMUONSegmentationV1::GetiAnod(Float_t xhit)
105 Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1;
106 return (xhit>0) ? kwire : -kwire ;
109 Float_t AliMUONSegmentationV1::GetAnod(Float_t xhit)
111 // Get anode position
112 Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1; // to be compatible ...
113 return (xhit>0) ? fDAnod*(kwire-0.5)+fSensOffset : -fDAnod*(kwire-0.5)-fSensOffset ;
117 void AliMUONSegmentationV1::SetPadSize(Float_t p1, Float_t p2)
119 // For chamber T5/6 p1 and p2 should be same for each zone
124 void AliMUONSegmentationV1::
125 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
127 // returns pad coordinates (ix,iy) for given real coordinates (x,y)
129 ix = (x>0)? Int_t((x-fSensOffset)/fDpx)+1 : Int_t((x+fSensOffset)/fDpx)-1;
130 iy = (y>0)? Int_t((y-fSensOffset)/fDpy)+1 : Int_t((y+fSensOffset)/fDpy)-1;
133 void AliMUONSegmentationV1::
134 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
136 // returns real coordinates (x,y) for given pad coordinates (ix,iy)
138 x = (ix>0) ? (Float_t(ix)-0.5)*fDpx+fSensOffset : (Float_t(ix)+0.5)*fDpx-fSensOffset;
139 y = (iy>0) ? (Float_t(iy)-0.5)*fDpy+fSensOffset : (Float_t(iy)+0.5)*fDpy-fSensOffset;
142 void AliMUONSegmentationV1::AddCut(Int_t Zone, Int_t nX, Int_t nY)
144 // the pad nX,nY is last INSIDE zone Zone. First pad is labelled 1 and not 0
146 // no cut for last Zone : it is the natural boundary of the chamber
147 printf("AliMUONSegmentationV1::AddCut ==> Zone %d not allowed !\n",Zone);
148 fZoneX[Zone][fNZoneCut[Zone]] = nX;
149 fZoneY[Zone][fNZoneCut[Zone]] = nY;
153 Int_t AliMUONSegmentationV1::GetZone(Float_t X, Float_t Y)
155 // Get segmentation zone
158 return GetZone( iX , iY );
161 Int_t AliMUONSegmentationV1::GetZone(Int_t nX, Int_t nY)
163 // Beware : first pad begins at 1 !!
164 Int_t aX = TMath::Abs(nX);
165 Int_t aY = TMath::Abs(nY);
167 for (Int_t iZone=fNzone-2;iZone>=0;iZone--)
169 for (Int_t iCut=0;iCut<fNZoneCut[iZone];iCut++)
170 if ( aY<=fZoneY[iZone][iCut] && aX<=fZoneX[iZone][iCut] )
179 void AliMUONSegmentationV1::
180 SetHit(Float_t xhit, Float_t yhit)
182 // Find the wire position (center of charge distribution)
187 void AliMUONSegmentationV1::
188 SetPad(Int_t ix, Int_t iy)
190 // Set current pad position
191 GetPadC(ix,iy,fx,fy);
195 void AliMUONSegmentationV1::SetPadCoord(Int_t iX, Int_t iY)
197 // Set current pad coordinates
198 GetPadC(iX,iY,fx,fy);
200 if ( ( (radius2=fx*fx+fy*fy) > frSensMax2 || radius2 < frSensMin2 )
205 void AliMUONSegmentationV1::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
208 // Find the wire position (center of charge distribution)
209 Float_t x0a=GetAnod(xhit);
213 // and take fNsigma*sigma around this center
214 Float_t x01=x0a - dx;
215 Float_t x02=x0a + dx;
216 Float_t y01=yhit - dy;
217 Float_t y02=yhit + dy;
219 // Do not cross over frames...
221 x01 = TMath::Sign(fSensOffset, x0a);
223 x02 = TMath::Sign(fSensOffset, x0a);
225 y01 = TMath::Sign(fSensOffset, yhit);
227 y02 = TMath::Sign(fSensOffset, yhit);
229 // find the pads over which the charge distributes
230 GetPadI(x01,y01,fixmin,fiymin);
231 GetPadI(x02,y02,fixmax,fiymax);
233 // Set current pad to lower left corner
236 SetPadCoord(fix,fiy);
239 void AliMUONSegmentationV1::NextPad()
242 // Step to next pad in integration region
245 } else if (fiy != fiymax) {
249 printf("\n Error: Stepping outside integration region\n ");
250 SetPadCoord(fix,fiy);
253 Int_t AliMUONSegmentationV1::MorePads()
256 // Are there more pads in the integration region
258 if (fix == fixmax && fiy == fiymax) {
265 Int_t AliMUONSegmentationV1::IsParallel2(Int_t iX, Int_t iY)
267 // test if the pad is read in parallel for zone 2
268 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
269 // returns 1 or 2 if read in parallel,
270 // according to the actual number in the chain, 0 else
272 // chainage is result is
273 // 1 2 3 1 2 3 1 1 1 2 2 2 y
274 // 7 8 9 10 11 12 0 0 0 0 0 0 ^
275 // 4 5 6 4 5 6 1 1 1 2 2 2 +->x
278 if (iY%3==1) return 0;
282 Int_t AliMUONSegmentationV1::IsParallel3(Int_t iX, Int_t iY)
284 // test if the pad is read in parallel for zone 3
285 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
286 // returns 1,2 or 3 if read in parallel,
287 // according to the actual number in the chain, 0 else
289 // chainage is result is
290 //16 2 3 1 2 3 1 2 3 0 1 1 1 2 2 2 3 3
291 // 7 8 9 10 11 12 13 14 15 0 0 0 0 0 0 0 0 0
292 // 4 5 6 4 5 6 4 5 6 1 1 1 2 2 2 3 3 3
295 if (iY%3==1) return 0;
296 return (iX%9)/3+1 - (iY%3==2 && iX%3==0);
299 Int_t AliMUONSegmentationV1::NParallel2(Int_t iX, Int_t iY)
301 // returns the number of pads connected in parallel for zone 2
302 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
310 if (iY%3==1) return 1;
314 Int_t AliMUONSegmentationV1::NParallel3(Int_t iX, Int_t iY)
316 // test if the pad is read in parallel for zone 3
317 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
318 // returns 1,2 or 3 if read in parallel,
319 // according to the actual number in the chain, 0 else
327 if (iY%3==1) return 1;
328 if (iY%3==2 && iX%9==0) return 1;
329 return 3 - (iY%3==2 && iX%3==0);
333 Int_t AliMUONSegmentationV1::Ix(Int_t trueX, Int_t trueY)
335 // returns the X number of pad which corresponds to the logical
336 // channel, expressed in x and y.
338 Int_t wix = TMath::Abs(trueX)-1;
339 Int_t wiy = TMath::Abs(trueY)-1;
340 Int_t zone = GetZone(trueX,trueY);
343 case 0: return trueX;
345 if (IsParallel2(wix,wiy) == 2)
346 return (trueX>0)? trueX-3 : trueX+3 ;
349 if ( (par3= IsParallel3(wix,wiy)) )
350 return (trueX>0) ? trueX-3*(par3-1) : trueX+3*(par3-1) ;
353 printf("Couille dans AliMUONSegmentationV1::ix\n");
358 Int_t AliMUONSegmentationV1::Ix()
360 // returns the X number of pad which has to increment charge
361 // due to parallel read-out
365 Int_t AliMUONSegmentationV1::ISector()
367 // This function is of no use for this kind of segmentation.
368 return GetZone(fix,fiy);
371 void AliMUONSegmentationV1::SigGenInit(Float_t x,Float_t y,Float_t z)
374 // Initialises pad and wire position during stepping
377 GetPadI(x,y,fixt,fiyt);
382 Int_t AliMUONSegmentationV1::SigGenCond(Float_t x,Float_t y,Float_t z)
385 // Signal will be generated if particle crosses pad boundary or
386 // boundary between two wires.
389 GetPadI(x,y,ixt,iyt);
390 Int_t iwt= GetiAnod(x);
392 if ((ixt != fixt) || (iyt !=fiyt) || (iwt != fiwt)) {
399 void AliMUONSegmentationV1::
400 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
402 // Get integration limits
409 void AliMUONSegmentationV1::GetNParallelAndOffset(Int_t iX, Int_t iY,Int_t
410 *Nparallel, Int_t* Offset)
413 Int_t wix = TMath::Abs(iX)-1;
414 Int_t wiy = TMath::Abs(iY)-1;
415 Int_t zone = GetZone(iX,iY);
422 *Nparallel = NParallel2(wix,wiy);
423 (iX>0) ? *Offset =3 : *Offset = -3;
424 if (IsParallel2(wix,wiy)>1)
425 printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n");
428 *Nparallel = NParallel3(wix,wiy);
429 (iX>0) ? *Offset =3 : *Offset = -3;
430 if (IsParallel3(wix,wiy)>1)
431 printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n");
437 Float_t AliMUONSegmentationV1::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t *Offset)
440 // Computes the offset for which the physical pad has the minimum distance squared
441 // (returned value) to the given coordinates
444 GetNParallelAndOffset(iX,iY,&nPara,&offset);
446 for (Int_t i=0;i<nPara; i++)
449 GetPadC(iX+i*offset,iY,x,y);
450 Float_t d2=(x-X)*(x-X) + (y-Y)*(y-Y);
460 void AliMUONSegmentationV1::CleanNeighbours(Int_t* Nlist, Int_t *Xlist,
463 // In the raw neighbours list, some pads do not exist
464 // and some others are read in parallel ...
465 // So we prune non-existing neighbours from the list (event if this should be
466 // at last not be a problem due to the clustering algorithm...)
469 for (Int_t nList=0;nList<*Nlist;nList++)
471 // prune if it does not exist
472 if ( Xlist[nList]==0 || Ylist[nList]==0 )
474 // compute true position
475 Xlist[nTot] = Ix(Xlist[nList],Ylist[nList]) ;
476 Ylist[nTot] = Ylist[nList] ;
477 // and prune if it does already exist
479 for (nTest=0;nTest<nTot; nTest++)
481 if ( Xlist[nTest]==Xlist[nTot] && Ylist[nTest]==Ylist[nTot])
491 void AliMUONSegmentationV1::
492 NeighboursNonDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[12], Int_t Ylist[12])
494 // returns the X number of pad which has to increment charge
495 // due to parallel read-out
497 Int_t nParallel, offset;
498 GetNParallelAndOffset(iX,iY,&nParallel,&offset);
500 // now fill raw list of neighbours
502 Xlist[0]=Xlist[1]=iX;Xlist[2]=iX-1;Xlist[3]=iX+1;
503 Ylist[0]=iY-1;Ylist[1]=iY+1;Ylist[2]=Ylist[3]=iY;
505 Xlist[4]=Xlist[5]=iX+offset;Xlist[6]=iX+offset-1;Xlist[7]=iX+offset+1;
506 Ylist[4]=iY-1;Ylist[5]=iY+1;Ylist[6]=Ylist[7]=iY;
508 Xlist[8]=Xlist[9]=iX+2*offset;Xlist[10]=iX+2*offset-1;Xlist[11]=iX+2*offset+1;
509 Ylist[8]=iY-1;Ylist[9]=iY+1;Ylist[10]=Ylist[11]=iY;
512 CleanNeighbours(Nlist,Xlist,Ylist);
515 void AliMUONSegmentationV1::
516 NeighboursDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[24], Int_t Ylist[24])
518 // returns the X number of pad which has to increment charge
519 // due to parallel read-out
521 Int_t nParallel, offset;
522 GetNParallelAndOffset(iX,iY,&nParallel,&offset);
524 // now fill raw list of neighbours
526 for (Int_t i=0;i<nParallel;i++)
527 for (Int_t dx=-1;dx<2;dx++)
528 for (Int_t dy=-1;dy<2;dy++)
532 Xlist[*Nlist] = iX + dx + i*offset;
533 Ylist[*Nlist] = iY + dy;
536 CleanNeighbours(Nlist,Xlist,Ylist);
539 void AliMUONSegmentationV1::Neighbours(Int_t iX, Int_t iY, Int_t* Nlist,
540 Int_t Xlist[24], Int_t Ylist[24])
543 NeighboursDiag(iX,iY,Nlist,Xlist,Ylist);
547 void AliMUONSegmentationV1::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
549 // Return a test point
551 x[0]=(TMath::Sqrt(frSensMax2)-TMath::Sqrt(frSensMin2))/2/TMath::Sqrt(2.);
555 AliMUONSegmentationV1& AliMUONSegmentationV1::operator =(const AliMUONSegmentationV1 & rhs)
557 // Dummy assignment operator