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