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.7 2000/10/18 11:42:06 morsch
19 - AliMUONRawCluster contains z-position.
20 - Some clean-up of useless print statements during initialisations.
22 Revision 1.6 2000/10/03 21:48:07 morsch
23 Adopt to const declaration of some of the methods in AliSegmentation.
25 Revision 1.5 2000/10/02 16:58:29 egangler
26 Cleaning of the code :
29 -> some useless includes removed or replaced by "class" statement
31 Revision 1.4 2000/07/03 11:54:57 morsch
32 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
33 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
35 Revision 1.3 2000/06/29 12:34:09 morsch
36 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
37 it usable with any other geometry class. The link to the object to which it belongs is
38 established via an index. This assumes that there exists a global geometry manager
39 from which the pointer to the parent object can be obtained (in our case gAlice).
41 Revision 1.2 2000/06/15 07:58:48 morsch
42 Code from MUON-dev joined
44 Revision 1.1.2.2 2000/06/12 07:57:43 morsch
47 Revision 1.1.2.1 2000/06/09 21:41:29 morsch
48 AliMUONSegmentationV1 code from AliMUONSegResV1.cxx
53 /////////////////////////////////////////////////////////
54 // Manager and hits classes for set:MUON version LYON //
55 /////////////////////////////////////////////////////////
58 #include "AliMUONChamber.h"
59 #include "AliMUONSegmentationV1.h"
62 #include "AliMUONChamber.h"
64 //___________________________________________
65 ClassImp(AliMUONSegmentationV1)
67 AliMUONSegmentationV1::AliMUONSegmentationV1(const AliMUONSegmentationV1& segmentation)
69 // Dummy copy constructor
73 AliMUONSegmentationV1::AliMUONSegmentationV1()
76 // initizalize the class with default settings
80 fDpx=0.0; // forces crash if not initialized by user
87 void AliMUONSegmentationV1::Init(Int_t chamber)
89 // valid only for T5/6
90 // beware : frMin is SENSITIVE radius by definition.
91 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
92 AliMUONChamber* iChamber=&(pMUON->Chamber(chamber));
94 frSensMin2 = (iChamber->RInner())*(iChamber->RInner());
95 frSensMax2 = (iChamber->ROuter())*(iChamber->ROuter());
96 fNpx=(Int_t) (iChamber->ROuter()/fDpx) + 1;
97 fNpy=(Int_t) (iChamber->ROuter()/fDpy) + 1;
106 void AliMUONSegmentationV1::DefaultCut(void)
108 // Set the default cuts
116 AddCut(1,12*6,18*12);
117 AddCut(1,15*6,15*12);
118 AddCut(1,18*6,12*12);
124 Int_t AliMUONSegmentationV1::GetiAnod(Float_t xhit)
127 Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1;
128 return (xhit>0) ? kwire : -kwire ;
131 Float_t AliMUONSegmentationV1::GetAnod(Float_t xhit) const
133 // Get anode position
134 Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1; // to be compatible ...
135 return (xhit>0) ? fDAnod*(kwire-0.5)+fSensOffset : -fDAnod*(kwire-0.5)-fSensOffset ;
139 void AliMUONSegmentationV1::SetPadSize(Float_t p1, Float_t p2)
141 // For chamber T5/6 p1 and p2 should be same for each zone
146 void AliMUONSegmentationV1::
147 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
149 // returns pad coordinates (ix,iy) for given real coordinates (x,y)
151 ix = (x>0)? Int_t((x-fSensOffset)/fDpx)+1 : Int_t((x+fSensOffset)/fDpx)-1;
152 iy = (y>0)? Int_t((y-fSensOffset)/fDpy)+1 : Int_t((y+fSensOffset)/fDpy)-1;
155 void AliMUONSegmentationV1::
156 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
158 // returns real coordinates (x,y) for given pad coordinates (ix,iy)
160 x = (ix>0) ? (Float_t(ix)-0.5)*fDpx+fSensOffset : (Float_t(ix)+0.5)*fDpx-fSensOffset;
161 y = (iy>0) ? (Float_t(iy)-0.5)*fDpy+fSensOffset : (Float_t(iy)+0.5)*fDpy-fSensOffset;
164 void AliMUONSegmentationV1::AddCut(Int_t Zone, Int_t nX, Int_t nY)
166 // the pad nX,nY is last INSIDE zone Zone. First pad is labelled 1 and not 0
168 // no cut for last Zone : it is the natural boundary of the chamber
169 printf("AliMUONSegmentationV1::AddCut ==> Zone %d not allowed !\n",Zone);
170 fZoneX[Zone][fNZoneCut[Zone]] = nX;
171 fZoneY[Zone][fNZoneCut[Zone]] = nY;
175 Int_t AliMUONSegmentationV1::GetZone(Float_t X, Float_t Y)
177 // Get segmentation zone
180 return GetZone( iX , iY );
183 Int_t AliMUONSegmentationV1::GetZone(Int_t nX, Int_t nY)
185 // Beware : first pad begins at 1 !!
186 Int_t aX = TMath::Abs(nX);
187 Int_t aY = TMath::Abs(nY);
189 for (Int_t iZone=fNzone-2;iZone>=0;iZone--)
191 for (Int_t iCut=0;iCut<fNZoneCut[iZone];iCut++)
192 if ( aY<=fZoneY[iZone][iCut] && aX<=fZoneX[iZone][iCut] )
201 void AliMUONSegmentationV1::
202 SetHit(Float_t xhit, Float_t yhit)
204 // Find the wire position (center of charge distribution)
209 void AliMUONSegmentationV1::
210 SetPad(Int_t ix, Int_t iy)
212 // Set current pad position
213 GetPadC(ix,iy,fX,fY);
217 void AliMUONSegmentationV1::SetPadCoord(Int_t iX, Int_t iY)
219 // Set current pad coordinates
220 GetPadC(iX,iY,fX,fY);
222 if ( ( (radius2=fX*fX+fY*fY) > frSensMax2 || radius2 < frSensMin2 )
227 void AliMUONSegmentationV1::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
230 // Find the wire position (center of charge distribution)
231 Float_t x0a=GetAnod(xhit);
235 // and take fNsigma*sigma around this center
236 Float_t x01=x0a - dx;
237 Float_t x02=x0a + dx;
238 Float_t y01=yhit - dy;
239 Float_t y02=yhit + dy;
241 // Do not cross over frames...
243 x01 = TMath::Sign(fSensOffset, x0a);
245 x02 = TMath::Sign(fSensOffset, x0a);
247 y01 = TMath::Sign(fSensOffset, yhit);
249 y02 = TMath::Sign(fSensOffset, yhit);
251 // find the pads over which the charge distributes
252 GetPadI(x01,y01,fIxmin,fIymin);
253 GetPadI(x02,y02,fIxmax,fIymax);
255 // Set current pad to lower left corner
258 SetPadCoord(fIx,fIy);
261 void AliMUONSegmentationV1::NextPad()
264 // Step to next pad in integration region
267 } else if (fIy != fIymax) {
271 printf("\n Error: Stepping outside integration region\n ");
272 SetPadCoord(fIx,fIy);
275 Int_t AliMUONSegmentationV1::MorePads()
278 // Are there more pads in the integration region
280 if (fIx == fIxmax && fIy == fIymax) {
287 Int_t AliMUONSegmentationV1::IsParallel2(Int_t iX, Int_t iY)
289 // test if the pad is read in parallel for zone 2
290 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
291 // returns 1 or 2 if read in parallel,
292 // according to the actual number in the chain, 0 else
294 // chainage is result is
295 // 1 2 3 1 2 3 1 1 1 2 2 2 y
296 // 7 8 9 10 11 12 0 0 0 0 0 0 ^
297 // 4 5 6 4 5 6 1 1 1 2 2 2 +->x
300 if (iY%3==1) return 0;
304 Int_t AliMUONSegmentationV1::IsParallel3(Int_t iX, Int_t iY)
306 // test if the pad is read in parallel for zone 3
307 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
308 // returns 1,2 or 3 if read in parallel,
309 // according to the actual number in the chain, 0 else
311 // chainage is result is
312 //16 2 3 1 2 3 1 2 3 0 1 1 1 2 2 2 3 3
313 // 7 8 9 10 11 12 13 14 15 0 0 0 0 0 0 0 0 0
314 // 4 5 6 4 5 6 4 5 6 1 1 1 2 2 2 3 3 3
317 if (iY%3==1) return 0;
318 return (iX%9)/3+1 - (iY%3==2 && iX%3==0);
321 Int_t AliMUONSegmentationV1::NParallel2(Int_t iX, Int_t iY)
323 // returns the number of pads connected in parallel for zone 2
324 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
332 if (iY%3==1) return 1;
336 Int_t AliMUONSegmentationV1::NParallel3(Int_t iX, Int_t iY)
338 // test if the pad is read in parallel for zone 3
339 // iX and iY are assumed to be positive and starting at 0 numbering (cF. iX)
340 // returns 1,2 or 3 if read in parallel,
341 // according to the actual number in the chain, 0 else
349 if (iY%3==1) return 1;
350 if (iY%3==2 && iX%9==0) return 1;
351 return 3 - (iY%3==2 && iX%3==0);
355 Int_t AliMUONSegmentationV1::Ix(Int_t trueX, Int_t trueY)
357 // returns the X number of pad which corresponds to the logical
358 // channel, expressed in x and y.
360 Int_t wix = TMath::Abs(trueX)-1;
361 Int_t wiy = TMath::Abs(trueY)-1;
362 Int_t zone = GetZone(trueX,trueY);
365 case 0: return trueX;
367 if (IsParallel2(wix,wiy) == 2)
368 return (trueX>0)? trueX-3 : trueX+3 ;
371 if ( (par3= IsParallel3(wix,wiy)) )
372 return (trueX>0) ? trueX-3*(par3-1) : trueX+3*(par3-1) ;
375 printf("Couille dans AliMUONSegmentationV1::ix\n");
380 Int_t AliMUONSegmentationV1::Ix()
382 // returns the X number of pad which has to increment charge
383 // due to parallel read-out
387 Int_t AliMUONSegmentationV1::ISector()
389 // This function is of no use for this kind of segmentation.
390 return GetZone(fIx,fIy);
393 void AliMUONSegmentationV1::SigGenInit(Float_t x,Float_t y,Float_t z)
396 // Initialises pad and wire position during stepping
399 GetPadI(x,y,fIxt,fIyt);
404 Int_t AliMUONSegmentationV1::SigGenCond(Float_t x,Float_t y,Float_t z)
407 // Signal will be generated if particle crosses pad boundary or
408 // boundary between two wires.
411 GetPadI(x,y,ixt,iyt);
412 Int_t iwt= GetiAnod(x);
414 if ((ixt != fIxt) || (iyt !=fIyt) || (iwt != fIwt)) {
421 void AliMUONSegmentationV1::
422 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
424 // Get integration limits
431 void AliMUONSegmentationV1::GetNParallelAndOffset(Int_t iX, Int_t iY,Int_t
432 *Nparallel, Int_t* Offset)
435 Int_t wix = TMath::Abs(iX)-1;
436 Int_t wiy = TMath::Abs(iY)-1;
437 Int_t zone = GetZone(iX,iY);
444 *Nparallel = NParallel2(wix,wiy);
445 (iX>0) ? *Offset =3 : *Offset = -3;
446 if (IsParallel2(wix,wiy)>1)
447 printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n");
450 *Nparallel = NParallel3(wix,wiy);
451 (iX>0) ? *Offset =3 : *Offset = -3;
452 if (IsParallel3(wix,wiy)>1)
453 printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n");
459 Float_t AliMUONSegmentationV1::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t *Offset)
462 // Computes the offset for which the physical pad has the minimum distance squared
463 // (returned value) to the given coordinates
466 GetNParallelAndOffset(iX,iY,&nPara,&offset);
468 for (Int_t i=0;i<nPara; i++)
471 GetPadC(iX+i*offset,iY,x,y);
472 Float_t d2=(x-X)*(x-X) + (y-Y)*(y-Y);
482 void AliMUONSegmentationV1::CleanNeighbours(Int_t* Nlist, Int_t *Xlist,
485 // In the raw neighbours list, some pads do not exist
486 // and some others are read in parallel ...
487 // So we prune non-existing neighbours from the list (event if this should be
488 // at last not be a problem due to the clustering algorithm...)
491 for (Int_t nList=0;nList<*Nlist;nList++)
493 // prune if it does not exist
494 if ( Xlist[nList]==0 || Ylist[nList]==0 )
496 // compute true position
497 Xlist[nTot] = Ix(Xlist[nList],Ylist[nList]) ;
498 Ylist[nTot] = Ylist[nList] ;
499 // and prune if it does already exist
501 for (nTest=0;nTest<nTot; nTest++)
503 if ( Xlist[nTest]==Xlist[nTot] && Ylist[nTest]==Ylist[nTot])
513 void AliMUONSegmentationV1::
514 NeighboursNonDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[12], Int_t Ylist[12])
516 // returns the X number of pad which has to increment charge
517 // due to parallel read-out
519 Int_t nParallel, offset;
520 GetNParallelAndOffset(iX,iY,&nParallel,&offset);
522 // now fill raw list of neighbours
524 Xlist[0]=Xlist[1]=iX;Xlist[2]=iX-1;Xlist[3]=iX+1;
525 Ylist[0]=iY-1;Ylist[1]=iY+1;Ylist[2]=Ylist[3]=iY;
527 Xlist[4]=Xlist[5]=iX+offset;Xlist[6]=iX+offset-1;Xlist[7]=iX+offset+1;
528 Ylist[4]=iY-1;Ylist[5]=iY+1;Ylist[6]=Ylist[7]=iY;
530 Xlist[8]=Xlist[9]=iX+2*offset;Xlist[10]=iX+2*offset-1;Xlist[11]=iX+2*offset+1;
531 Ylist[8]=iY-1;Ylist[9]=iY+1;Ylist[10]=Ylist[11]=iY;
534 CleanNeighbours(Nlist,Xlist,Ylist);
537 void AliMUONSegmentationV1::
538 NeighboursDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[24], Int_t Ylist[24])
540 // returns the X number of pad which has to increment charge
541 // due to parallel read-out
543 Int_t nParallel, offset;
544 GetNParallelAndOffset(iX,iY,&nParallel,&offset);
546 // now fill raw list of neighbours
548 for (Int_t i=0;i<nParallel;i++)
549 for (Int_t dx=-1;dx<2;dx++)
550 for (Int_t dy=-1;dy<2;dy++)
554 Xlist[*Nlist] = iX + dx + i*offset;
555 Ylist[*Nlist] = iY + dy;
558 CleanNeighbours(Nlist,Xlist,Ylist);
561 void AliMUONSegmentationV1::Neighbours(Int_t iX, Int_t iY, Int_t* Nlist,
562 Int_t Xlist[24], Int_t Ylist[24])
565 NeighboursDiag(iX,iY,Nlist,Xlist,Ylist);
569 void AliMUONSegmentationV1::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
571 // Return a test point
573 x[0]=(TMath::Sqrt(frSensMax2)-TMath::Sqrt(frSensMin2))/2/TMath::Sqrt(2.);
577 AliMUONSegmentationV1& AliMUONSegmentationV1::operator =(const AliMUONSegmentationV1 & rhs)
579 // Dummy assignment operator