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 /////////////////////////////////////////////////////////
19 // Manager and hits classes for set:MUON version LYON //
20 /////////////////////////////////////////////////////////
24 #include "AliMUONChamber.h"
25 #include "AliMUONSegmentationV1.h"
28 #include "AliMUONChamber.h"
30 //___________________________________________
31 ClassImp(AliMUONSegmentationV1)
33 AliMUONSegmentationV1::AliMUONSegmentationV1(const AliMUONSegmentationV1& segmentation)
34 : AliSegmentation(segmentation)
36 // Protected copy constructor
38 Fatal("AliMUONSegmentationV1", "Not implemented.");
42 AliMUONSegmentationV1::AliMUONSegmentationV1()
45 // initizalize the class with default settings
49 fDpx=0.0; // forces crash if not initialized by user
56 void AliMUONSegmentationV1::Init(Int_t chamber)
58 // valid only for T5/6
59 // beware : frMin is SENSITIVE radius by definition.
60 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
61 AliMUONChamber* iChamber=&(pMUON->Chamber(chamber));
63 frSensMin2 = (iChamber->RInner())*(iChamber->RInner());
64 frSensMax2 = (iChamber->ROuter())*(iChamber->ROuter());
65 fNpx=(Int_t) (iChamber->ROuter()/fDpx) + 1;
66 fNpy=(Int_t) (iChamber->ROuter()/fDpy) + 1;
75 void AliMUONSegmentationV1::DefaultCut(void)
77 // Set the default cuts
93 Int_t AliMUONSegmentationV1::GetiAnod(Float_t xhit)
96 Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1;
97 return (xhit>0) ? kwire : -kwire ;
100 Float_t AliMUONSegmentationV1::GetAnod(Float_t xhit) const
102 // Get anode position
103 Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1; // to be compatible ...
104 return (xhit>0) ? fDAnod*(kwire-0.5)+fSensOffset : -fDAnod*(kwire-0.5)-fSensOffset ;
108 void AliMUONSegmentationV1::SetPadSize(Float_t p1, Float_t p2)
110 // For chamber T5/6 p1 and p2 should be same for each zone
115 void AliMUONSegmentationV1::
116 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
118 // returns pad coordinates (ix,iy) for given real coordinates (x,y)
120 ix = (x>0)? Int_t((x-fSensOffset)/fDpx)+1 : Int_t((x+fSensOffset)/fDpx)-1;
121 iy = (y>0)? Int_t((y-fSensOffset)/fDpy)+1 : Int_t((y+fSensOffset)/fDpy)-1;
124 void AliMUONSegmentationV1::
125 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
127 // returns real coordinates (x,y) for given pad coordinates (ix,iy)
129 x = (ix>0) ? (Float_t(ix)-0.5)*fDpx+fSensOffset : (Float_t(ix)+0.5)*fDpx-fSensOffset;
130 y = (iy>0) ? (Float_t(iy)-0.5)*fDpy+fSensOffset : (Float_t(iy)+0.5)*fDpy-fSensOffset;
133 void AliMUONSegmentationV1::AddCut(Int_t Zone, Int_t nX, Int_t nY)
135 // the pad nX,nY is last INSIDE zone Zone. First pad is labelled 1 and not 0
137 // no cut for last Zone : it is the natural boundary of the chamber
138 printf("AliMUONSegmentationV1::AddCut ==> Zone %d not allowed !\n",Zone);
139 fZoneX[Zone][fNZoneCut[Zone]] = nX;
140 fZoneY[Zone][fNZoneCut[Zone]] = nY;
144 Int_t AliMUONSegmentationV1::GetZone(Float_t X, Float_t Y)
146 // Get segmentation zone
149 return GetZone( iX , iY );
152 Int_t AliMUONSegmentationV1::GetZone(Int_t nX, Int_t nY)
154 // Beware : first pad begins at 1 !!
155 Int_t aX = TMath::Abs(nX);
156 Int_t aY = TMath::Abs(nY);
158 for (Int_t iZone=fNzone-2;iZone>=0;iZone--)
160 for (Int_t iCut=0;iCut<fNZoneCut[iZone];iCut++)
161 if ( aY<=fZoneY[iZone][iCut] && aX<=fZoneX[iZone][iCut] )
170 void AliMUONSegmentationV1::
171 SetHit(Float_t xhit, Float_t yhit)
173 // Find the wire position (center of charge distribution)
178 void AliMUONSegmentationV1::
179 SetPad(Int_t ix, Int_t iy)
181 // Set current pad position
182 GetPadC(ix,iy,fX,fY);
186 void AliMUONSegmentationV1::SetPadCoord(Int_t iX, Int_t iY)
188 // Set current pad coordinates
189 GetPadC(iX,iY,fX,fY);
191 if ( ( (radius2=fX*fX+fY*fY) > frSensMax2 || radius2 < frSensMin2 )
196 void AliMUONSegmentationV1::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
199 // Find the wire position (center of charge distribution)
200 Float_t x0a=GetAnod(xhit);
204 // and take fNsigma*sigma around this center
205 Float_t x01=x0a - dx;
206 Float_t x02=x0a + dx;
207 Float_t y01=yhit - dy;
208 Float_t y02=yhit + dy;
210 // Do not cross over frames...
212 x01 = TMath::Sign(fSensOffset, x0a);
214 x02 = TMath::Sign(fSensOffset, x0a);
216 y01 = TMath::Sign(fSensOffset, yhit);
218 y02 = TMath::Sign(fSensOffset, yhit);
220 // find the pads over which the charge distributes
221 GetPadI(x01,y01,fIxmin,fIymin);
222 GetPadI(x02,y02,fIxmax,fIymax);
224 // Set current pad to lower left corner
227 SetPadCoord(fIx,fIy);
230 void AliMUONSegmentationV1::NextPad()
233 // Step to next pad in integration region
236 } else if (fIy != fIymax) {
240 printf("\n Error: Stepping outside integration region\n ");
241 SetPadCoord(fIx,fIy);
244 Int_t AliMUONSegmentationV1::MorePads()
247 // Are there more pads in the integration region
249 if (fIx == fIxmax && fIy == fIymax) {
256 Int_t AliMUONSegmentationV1::IsParallel2(Int_t iX, Int_t iY) const
258 // test if the pad is read in parallel for zone 2
259 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
260 // returns 1 or 2 if read in parallel,
261 // according to the actual number in the chain, 0 else
263 // chainage is result is
264 // 1 2 3 1 2 3 1 1 1 2 2 2 y
265 // 7 8 9 10 11 12 0 0 0 0 0 0 ^
266 // 4 5 6 4 5 6 1 1 1 2 2 2 +->x
269 if (iY%3==1) return 0;
273 Int_t AliMUONSegmentationV1::IsParallel3(Int_t iX, Int_t iY) const
275 // test if the pad is read in parallel for zone 3
276 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
277 // returns 1,2 or 3 if read in parallel,
278 // according to the actual number in the chain, 0 else
280 // chainage is result is
281 //16 2 3 1 2 3 1 2 3 0 1 1 1 2 2 2 3 3
282 // 7 8 9 10 11 12 13 14 15 0 0 0 0 0 0 0 0 0
283 // 4 5 6 4 5 6 4 5 6 1 1 1 2 2 2 3 3 3
286 if (iY%3==1) return 0;
287 return (iX%9)/3+1 - (iY%3==2 && iX%3==0);
290 Int_t AliMUONSegmentationV1::NParallel2(Int_t /*iX*/, Int_t iY) const
292 // returns the number of pads connected in parallel for zone 2
293 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
301 if (iY%3==1) return 1;
305 Int_t AliMUONSegmentationV1::NParallel3(Int_t iX, Int_t iY) const
307 // test if the pad is read in parallel for zone 3
308 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
309 // returns 1,2 or 3 if read in parallel,
310 // according to the actual number in the chain, 0 else
318 if (iY%3==1) return 1;
319 if (iY%3==2 && iX%9==0) return 1;
320 return 3 - (iY%3==2 && iX%3==0);
324 Int_t AliMUONSegmentationV1::Ix(Int_t trueX, Int_t trueY)
326 // returns the X number of pad which corresponds to the logical
327 // channel, expressed in x and y.
329 Int_t wix = TMath::Abs(trueX)-1;
330 Int_t wiy = TMath::Abs(trueY)-1;
331 Int_t zone = GetZone(trueX,trueY);
334 case 0: return trueX;
336 if (IsParallel2(wix,wiy) == 2)
337 return (trueX>0)? trueX-3 : trueX+3 ;
340 if ( (par3= IsParallel3(wix,wiy)) )
341 return (trueX>0) ? trueX-3*(par3-1) : trueX+3*(par3-1) ;
344 printf("Couille dans AliMUONSegmentationV1::ix\n");
349 Int_t AliMUONSegmentationV1::Ix()
351 // returns the X number of pad which has to increment charge
352 // due to parallel read-out
356 Int_t AliMUONSegmentationV1::ISector()
358 // This function is of no use for this kind of segmentation.
359 return GetZone(fIx,fIy);
362 void AliMUONSegmentationV1::SigGenInit(Float_t x,Float_t y,Float_t /*z*/)
365 // Initialises pad and wire position during stepping
368 GetPadI(x,y,fIxt,fIyt);
373 Int_t AliMUONSegmentationV1::SigGenCond(Float_t x,Float_t y,Float_t /*z*/)
376 // Signal will be generated if particle crosses pad boundary or
377 // boundary between two wires.
380 GetPadI(x,y,ixt,iyt);
381 Int_t iwt= GetiAnod(x);
383 if ((ixt != fIxt) || (iyt !=fIyt) || (iwt != fIwt)) {
390 void AliMUONSegmentationV1::
391 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
393 // Get integration limits
400 void AliMUONSegmentationV1::GetNParallelAndOffset(Int_t iX, Int_t iY,Int_t
401 *Nparallel, Int_t* Offset)
404 Int_t wix = TMath::Abs(iX)-1;
405 Int_t wiy = TMath::Abs(iY)-1;
406 Int_t zone = GetZone(iX,iY);
413 *Nparallel = NParallel2(wix,wiy);
414 (iX>0) ? *Offset =3 : *Offset = -3;
415 if (IsParallel2(wix,wiy)>1)
416 printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n");
419 *Nparallel = NParallel3(wix,wiy);
420 (iX>0) ? *Offset =3 : *Offset = -3;
421 if (IsParallel3(wix,wiy)>1)
422 printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n");
428 Float_t AliMUONSegmentationV1::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t *Offset)
431 // Computes the offset for which the physical pad has the minimum distance squared
432 // (returned value) to the given coordinates
435 GetNParallelAndOffset(iX,iY,&nPara,&offset);
437 for (Int_t i=0;i<nPara; i++)
440 GetPadC(iX+i*offset,iY,x,y);
441 Float_t d2=(x-X)*(x-X) + (y-Y)*(y-Y);
451 void AliMUONSegmentationV1::CleanNeighbours(Int_t* Nlist, Int_t *Xlist,
454 // In the raw neighbours list, some pads do not exist
455 // and some others are read in parallel ...
456 // So we prune non-existing neighbours from the list (event if this should be
457 // at last not be a problem due to the clustering algorithm...)
460 for (Int_t nList=0;nList<*Nlist;nList++)
462 // prune if it does not exist
463 if ( Xlist[nList]==0 || Ylist[nList]==0 )
465 // compute true position
466 Xlist[nTot] = Ix(Xlist[nList],Ylist[nList]) ;
467 Ylist[nTot] = Ylist[nList] ;
468 // and prune if it does already exist
470 for (nTest=0;nTest<nTot; nTest++)
472 if ( Xlist[nTest]==Xlist[nTot] && Ylist[nTest]==Ylist[nTot])
482 void AliMUONSegmentationV1::
483 NeighboursNonDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[12], Int_t Ylist[12])
485 // returns the X number of pad which has to increment charge
486 // due to parallel read-out
488 Int_t nParallel, offset;
489 GetNParallelAndOffset(iX,iY,&nParallel,&offset);
491 // now fill raw list of neighbours
493 Xlist[0]=Xlist[1]=iX;Xlist[2]=iX-1;Xlist[3]=iX+1;
494 Ylist[0]=iY-1;Ylist[1]=iY+1;Ylist[2]=Ylist[3]=iY;
496 Xlist[4]=Xlist[5]=iX+offset;Xlist[6]=iX+offset-1;Xlist[7]=iX+offset+1;
497 Ylist[4]=iY-1;Ylist[5]=iY+1;Ylist[6]=Ylist[7]=iY;
499 Xlist[8]=Xlist[9]=iX+2*offset;Xlist[10]=iX+2*offset-1;Xlist[11]=iX+2*offset+1;
500 Ylist[8]=iY-1;Ylist[9]=iY+1;Ylist[10]=Ylist[11]=iY;
503 CleanNeighbours(Nlist,Xlist,Ylist);
506 void AliMUONSegmentationV1::
507 NeighboursDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[24], Int_t Ylist[24])
509 // returns the X number of pad which has to increment charge
510 // due to parallel read-out
512 Int_t nParallel, offset;
513 GetNParallelAndOffset(iX,iY,&nParallel,&offset);
515 // now fill raw list of neighbours
517 for (Int_t i=0;i<nParallel;i++)
518 for (Int_t dx=-1;dx<2;dx++)
519 for (Int_t dy=-1;dy<2;dy++)
523 Xlist[*Nlist] = iX + dx + i*offset;
524 Ylist[*Nlist] = iY + dy;
527 CleanNeighbours(Nlist,Xlist,Ylist);
530 void AliMUONSegmentationV1::Neighbours(Int_t iX, Int_t iY, Int_t* Nlist,
531 Int_t Xlist[24], Int_t Ylist[24])
534 NeighboursDiag(iX,iY,Nlist,Xlist,Ylist);
538 void AliMUONSegmentationV1::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
540 // Return a test point
542 x[0]=(TMath::Sqrt(frSensMax2)-TMath::Sqrt(frSensMin2))/2/TMath::Sqrt(2.);
546 AliMUONSegmentationV1&
547 AliMUONSegmentationV1::operator =(const AliMUONSegmentationV1 & rhs)
549 // Protected assignement operator
551 if (this == &rhs) return *this;
553 Fatal("operator=", "Not implemented.");