]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONSegmentationV1.cxx
Obsolete member data deleted.
[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$
18Revision 1.1.2.2 2000/06/12 07:57:43 morsch
19include TMath.cxx
20
21Revision 1.1.2.1 2000/06/09 21:41:29 morsch
22AliMUONSegmentationV1 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//___________________________________________
36ClassImp(AliMUONSegmentationV1)
37
38AliMUONSegmentationV1::AliMUONSegmentationV1(const AliMUONSegmentationV1& segmentation)
39{
40// Dummy copy constructor
41}
42
43
44AliMUONSegmentationV1::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
57void 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
70void 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
88Int_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
95Float_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
103void 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
110void AliMUONSegmentationV1::
111GetPadIxy(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
119void AliMUONSegmentationV1::
120GetPadCxy(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
128void 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
139Int_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
147Int_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
165void AliMUONSegmentationV1::
166SetHit(Float_t xhit, Float_t yhit)
167{
168// Find the wire position (center of charge distribution)
169 fxhit=xhit;
170 fyhit=yhit;
171}
172
173void AliMUONSegmentationV1::
174SetPad(Int_t ix, Int_t iy)
175{
176// Set current pad position
177 GetPadCxy(ix,iy,fx,fy);
178}
179
180
181void AliMUONSegmentationV1::SetPadCoord(Int_t iX, Int_t iY)
182{
183// Set current pad coordinates
184GetPadCxy(iX,iY,fx,fy);
185 Float_t radius2;
186 if ( ( (radius2=fx*fx+fy*fy) > frSensMax2 || radius2 < frSensMin2 )
187 && MorePads() )
188 NextPad();
189}
190
191void 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
225void 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
239Int_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
251Int_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
268Int_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
285Int_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
300Int_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
319Int_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
344Int_t AliMUONSegmentationV1::Ix()
345{
346// returns the X number of pad which has to increment charge
347// due to parallel read-out
348return Ix(fix,fiy);
349}
350
351Int_t AliMUONSegmentationV1::ISector()
352{
353// This function is of no use for this kind of segmentation.
354 return GetZone(fix,fiy);
355}
356
357void 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
368Int_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
385void AliMUONSegmentationV1::
386IntegrationLimits(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
395void 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
423Float_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
446void 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
477void AliMUONSegmentationV1::
478NeighboursNonDiag(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
501void AliMUONSegmentationV1::
502NeighboursDiag(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
525void AliMUONSegmentationV1::Neighbours(Int_t iX, Int_t iY, Int_t* Nlist,
526 Int_t Xlist[24], Int_t Ylist[24])
527{
528// Get neighbours
529NeighboursDiag(iX,iY,Nlist,Xlist,Ylist);
530}
531
532
533void 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
541AliMUONSegmentationV1& AliMUONSegmentationV1::operator =(const AliMUONSegmentationV1 & rhs)
542{
543// Dummy assignment operator
544 return *this;
545}