]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSegmentationV01.cxx
Changed default digitisation to all particles.
[u/mrichter/AliRoot.git] / MUON / AliMUONSegmentationV01.cxx
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$
18 Revision 1.9  2000/10/18 08:41:32  morsch
19 Make NextPad() and MorePads() to iterate until the end.
20
21 Revision 1.8  2000/10/03 21:48:07  morsch
22 Adopt to const declaration of some of the methods in AliSegmentation.
23
24 Revision 1.7  2000/10/02 21:28:09  fca
25 Removal of useless dependecies via forward declarations
26
27 Revision 1.6  2000/10/02 16:58:29  egangler
28 Cleaning of the code :
29 -> coding conventions
30 -> void Streamers
31 -> some useless includes removed or replaced by "class" statement
32
33 Revision 1.5  2000/07/13 16:19:44  fca
34 Mainly coding conventions + some small bug fixes
35
36 Revision 1.4  2000/07/03 11:54:57  morsch
37 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
38 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
39
40 Revision 1.3  2000/06/29 12:34:09  morsch
41 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
42 it usable with any other geometry class. The link to the object to which it belongs is
43 established via an index. This assumes that there exists a global geometry manager
44 from which the pointer to the parent object can be obtained (in our case gAlice).
45
46 Revision 1.2  2000/06/15 07:58:48  morsch
47 Code from MUON-dev joined
48
49 Revision 1.1.2.1  2000/06/09 21:37:30  morsch
50 AliMUONSegmentationV01 code  from  AliMUONSegResV01.cxx
51
52 */
53
54
55 /////////////////////////////////////////////////////
56 //  Segmentation and Response classes version 01   //
57 /////////////////////////////////////////////////////
58
59 #include <TBox.h> 
60 #include <TF1.h> 
61 #include <TObjArray.h>
62 #include <iostream.h>
63
64 #include "AliMUONSegmentationV01.h"
65 #include "AliMUON.h"
66 #include "AliMUONChamber.h"
67 #include "AliRun.h"
68
69
70
71 //___________________________________________
72 ClassImp(AliMUONSegmentationV01)
73
74 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
75 {
76 // Dummy copy constructor
77 }
78 AliMUONSegmentationV01::AliMUONSegmentationV01() 
79 {
80 // Default constructor
81     fNsec=4;
82     fRSec = new TArrayF(fNsec);
83     fNDiv = new TArrayI(fNsec);      
84     fDpxD = new TArrayF(fNsec);      
85     (*fRSec)[0]=(*fRSec)[1]=(*fRSec)[2]=(*fRSec)[3]=0;     
86     (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;     
87     (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;     
88     fCorr = new TObjArray(3);
89     (*fCorr)[0]=0;
90     (*fCorr)[1]=0;
91     (*fCorr)[2]=0;
92
93
94 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
95 {
96 //
97 // Returns x-pad size for given sector isec
98    Float_t dpx = (*fDpxD)[isec];
99    return dpx;
100 }
101
102 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
103 {
104 //
105 // Returns y-pad size for given sector isec
106    return fDpy;
107 }
108     
109 void   AliMUONSegmentationV01::SetSegRadii(Float_t  r[4])
110 {
111 //
112 // Set the radii of the segmentation zones 
113     for (Int_t i=0; i<4; i++) {
114         (*fRSec)[i]=r[i];
115     }
116 }
117
118
119 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
120 {
121 //
122 // Defines the pad size perp. to the anode wire (y) for different sectors. 
123 // Pad sizes are defined as integral fractions ndiv of a basis pad size
124 // fDpx
125 // 
126     for (Int_t i=0; i<4; i++) {
127         (*fNDiv)[i]=ndiv[i];
128     }
129     ndiv[0]=ndiv[1];
130 }
131
132
133 void AliMUONSegmentationV01::Init(Int_t chamber)
134 {
135 //
136 //  Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
137 //  These arrays help in converting from real to pad co-ordinates and
138 //  vice versa.
139 //  This version approximates concentric segmentation zones
140 //
141     Int_t isec;
142     printf("\n Initialise Segmentation V01\n");
143     fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
144
145     (*fDpxD)[fNsec-1]=fDpx;
146     if (fNsec > 1) {
147         for (Int_t i=fNsec-2; i>=0; i--){
148             (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
149         }
150     }
151 //
152 // fill the arrays defining the pad segmentation boundaries
153     Float_t ry;
154     Int_t   dnx;
155     Int_t   add;
156 //
157 //  loop over sections
158     for(isec=0; isec<fNsec; isec++) {
159 //  
160 //  loop over pads along the aode wires
161         for (Int_t iy=1; iy<=fNpy; iy++) {
162 //
163             Float_t x=iy*fDpy-fDpy/2;
164             if (x > (*fRSec)[isec]) {
165                 fNpxS[isec][iy]=0;
166                 fCx[isec][iy]=0;
167             } else {
168                 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
169                 if (isec > 1) {
170                     dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
171                     if (isec < fNsec-1) {
172                         if (TMath::Odd((Long_t)dnx)) dnx++;             
173                     }
174                     fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
175                     fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
176                 } else if (isec == 1) {
177                     dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
178                     fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
179                     add=4 - (fNpxS[isec][iy])%4;
180                     if (add < 4) fNpxS[isec][iy]+=add; 
181                     dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
182                     fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
183                 } else {
184                     dnx=Int_t(ry/(*fDpxD)[isec]);
185                     fNpxS[isec][iy]=dnx;
186                     fCx[isec][iy]=dnx*(*fDpxD)[isec];
187                 }
188             }
189         } // y-pad loop
190     } // sector loop
191 // reference to chamber
192     AliMUON *pMUON  = (AliMUON *) gAlice->GetModule("MUON");
193     fChamber=&(pMUON->Chamber(chamber));
194     fZ = fChamber->Z();
195 }
196
197 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
198 {
199 // Returns sector number for given pad position
200 //
201     Int_t absix=TMath::Abs(ix);
202     Int_t absiy=TMath::Abs(iy);
203     Int_t isec=0;
204     for (Int_t i=0; i<fNsec; i++) {
205         if (absix<=fNpxS[i][absiy]){
206             isec=i;
207             break;
208         }
209     }
210     return isec;
211 }
212
213 void AliMUONSegmentationV01::
214 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
215 {
216 //  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
217 //
218     iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1;
219     if (iy >  fNpy) iy= fNpy;
220     if (iy < -fNpy) iy=-fNpy;
221 //
222 //  Find sector isec
223     Int_t isec=-1;
224     Float_t absx=TMath::Abs(x);
225     Int_t absiy=TMath::Abs(iy);
226     for (Int_t i=0; i < fNsec; i++) {
227         if (absx <= fCx[i][absiy]) {
228             isec=i;
229             break;
230         }
231     }
232     if (isec>0) {
233         ix= Int_t((absx-fCx[isec-1][absiy])/(*fDpxD)[isec])
234             +fNpxS[isec-1][absiy]+1;
235     } else if (isec == 0) {
236         ix= Int_t(absx/(*fDpxD)[isec])+1;
237     } else {
238         ix=fNpxS[fNsec-1][absiy]+1;     
239     }
240     ix = (x>0) ? ix:-ix;
241 }
242
243 void AliMUONSegmentationV01::
244 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
245 {
246 //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
247 //
248     y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
249 //
250 //  Find sector isec
251     Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
252 //
253     Int_t absix=TMath::Abs(ix);
254     Int_t absiy=TMath::Abs(iy);
255     if (isec) {
256         x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*(*fDpxD)[isec];
257         x=(ix>0) ?  x-(*fDpxD)[isec]/2 : -x+(*fDpxD)[isec]/2;
258     } else {
259         x=y=0;
260     }
261 }
262
263 void AliMUONSegmentationV01::
264 SetPad(Int_t ix, Int_t iy)
265 {
266     //
267     // Sets virtual pad coordinates, needed for evaluating pad response 
268     // outside the tracking program 
269     GetPadC(ix,iy,fX,fY);
270     fSector=Sector(ix,iy);
271 }
272
273
274 void AliMUONSegmentationV01::
275 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
276 {
277 // Initialises iteration over pads for charge distribution algorithm
278 //
279     //
280     // Find the wire position (center of charge distribution)
281     Float_t x0a=GetAnod(xhit);
282     fXhit=x0a;
283     fYhit=yhit;
284     
285     //
286     // and take fNsigma*sigma around this center
287     Float_t x01=x0a  - dx;
288     Float_t x02=x0a  + dx;
289     Float_t y01=yhit - dy;
290     Float_t y02=yhit + dy;
291     //
292     // find the pads over which the charge distributes
293
294     GetPadI(x01,y01,fIxmin,fIymin);
295     GetPadI(x02,y02,fIxmax,fIymax);
296     fXmin=x01;
297     fXmax=x02;
298     fYmin=y01;
299     fYmax=y02;
300     
301     // 
302     // Set current pad to lower left corner
303     if (fIxmax < fIxmin) fIxmax=fIxmin;
304     if (fIymax < fIymin) fIymax=fIymin;    
305     fIx=fIxmin;
306     fIy=fIymin;
307     GetPadC(fIx,fIy,fX,fY);
308 }
309
310
311 void AliMUONSegmentationV01::NextPad()
312 {
313 // Stepper for the iteration over pads
314 //
315 // Step to next pad in the integration region
316   // 
317   // Step to next pad in integration region
318     Float_t xc,yc;
319     Int_t   iyc;
320     
321 //  step from left to right    
322
323     if (fX < fXmax && fX != 0) {
324         if (fIx==-1) fIx++;
325         fIx++;
326 //  step up 
327     } else if (fIy != fIymax) {
328         if (fIy==-1) fIy++;
329         fIy++;
330 //      get y-position of next row (yc), xc not used here       
331         GetPadC(fIx,fIy,xc,yc);
332 //      get x-pad coordiante for first pad in row (fIx)
333         GetPadI(fXmin,yc,fIx,iyc);
334     } else {
335         fIx=-1;
336         fIy=-1;
337     }
338     GetPadC(fIx,fIy,fX,fY);
339     fSector=Sector(fIx,fIy);
340     if (MorePads() && 
341         (fSector ==-1 || fSector==0)) 
342         NextPad();
343 }
344
345 Int_t AliMUONSegmentationV01::MorePads()
346 // Stopping condition for the iterator over pads
347 //
348 // Are there more pads in the integration region
349 {
350     return  (fIx != -1  || fIy != -1);
351 /*
352     if ((fX >= fXmax  && fIy >= fIymax) || fY==0) {
353         return 0;
354     } else {
355         return 1;
356     }
357 */
358 }
359
360 void AliMUONSegmentationV01::
361 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
362 {
363 //  Returns integration limits for current pad
364 //
365     x1=fXhit-fX-Dpx(fSector)/2.;
366     x2=x1+Dpx(fSector);
367     y1=fYhit-fY-Dpy(fSector)/2.;
368     y2=y1+Dpy(fSector);    
369 }
370
371 void AliMUONSegmentationV01::
372 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
373 {
374 // Returns list of next neighbours for given Pad (iX, iY)
375 //
376     const Float_t kEpsilon=fDpy/1000;
377     
378     Float_t x,y;
379     Int_t   ixx, iyy, isec1;
380 //
381     Int_t   isec0=AliMUONSegmentationV01::Sector(iX,iY);
382     Int_t i=0;
383 //    
384 //  step right
385     Xlist[i]=iX+1;
386     if (Xlist[i]==0) Xlist[i]++;
387     Ylist[i++]=iY;
388 //
389 //  step left    
390     Xlist[i]=iX-1;
391     if (Xlist[i]==0) Xlist[i]--;
392     Ylist[i++]=iY;
393 //
394 //  step up 
395     AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
396     AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
397     Xlist[i]=ixx;
398     Ylist[i++]=iyy;
399     isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
400     if (isec1==isec0) {
401 //
402 //  no sector boundary crossing
403 //      Xlist[i]=ixx+1;
404 //      Ylist[i++]=iY+1;
405         
406 //      Xlist[i]=ixx-1;
407 //      Ylist[i++]=iY+1;
408     } else if (isec1 < isec0) {
409 // finer segmentation
410 //      Xlist[i]=ixx+1;
411 //      Ylist[i++]=iY+1;
412         
413         Xlist[i]=ixx-1;
414         Ylist[i++]=iyy;
415         
416 //      Xlist[i]=ixx-2;
417 //      Ylist[i++]=iY+1;
418     } else {
419 // coarser segmenation  
420 /*
421         if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
422             Xlist[i]=ixx-1;
423             Ylist[i++]=iY+1;
424         } else {
425             Xlist[i]=ixx+1;
426             Ylist[i++]=iY+1;
427         }
428 */
429     }
430
431 //
432 // step down 
433     AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
434     AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
435     Xlist[i]=ixx;
436     Ylist[i++]=iyy;
437     isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
438     if (isec1==isec0) {
439 //
440 //  no sector boundary crossing
441 /*
442     Xlist[i]=ixx+1;
443     Ylist[i++]=iY-1;
444         
445     Xlist[i]=ixx-1;
446     Ylist[i++]=iY-1;
447 */
448     } else if (isec1 < isec0) {
449 // finer segmentation
450 //      Xlist[i]=ixx+1;
451 //      Ylist[i++]=iY-1;
452         
453         Xlist[i]=ixx-1;
454         Ylist[i++]=iyy;
455         
456 //      Xlist[i]=ixx-2;
457 //      Ylist[i++]=iY-1;
458     } else {
459 // coarser segmentation 
460 /*
461         if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
462             Xlist[i]=ixx-1;
463             Ylist[i++]=iY-1;
464         } else {
465             Xlist[i]=ixx+1;
466             Ylist[i++]=iY-1;
467         }
468 */
469     }
470     *Nlist=i;
471 }
472
473 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
474 {
475 // Returns test point on the pad plane.
476 // Used during determination of the segmoid correction of the COG-method
477
478     n=3;
479     x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
480     y[0]=x[0];
481     x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
482     y[1]=x[1];
483     x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
484     y[2]=x[2];
485 }
486
487 void AliMUONSegmentationV01::Draw(const char *) const
488 {
489 // Draws the segmentation zones
490 //
491     TBox *box;
492     
493     Float_t dx=0.95/fCx[3][1]/2;
494     Float_t dy=0.95/(Float_t(Npy()))/2;
495     Float_t x0,y0,x1,y1;
496     Float_t xc=0.5;
497     Float_t yc=0.5;
498     
499     for (Int_t iy=1; iy<Npy(); iy++)
500     {
501         for (Int_t isec=0; isec<4; isec++) {
502             if (isec==0) {
503                 x0=0;
504                 x1=fCx[isec][iy]*dx;
505             } else {
506                 x0=fCx[isec-1][iy]*dx;
507                 x1=fCx[isec][iy]*dx;
508             }
509             y0=Float_t(iy-1)*dy;
510             y1=y0+dy;
511             box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
512             box->SetFillColor(isec+1);
513             box->Draw();
514
515             box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
516             box->SetFillColor(isec+1);
517             box->Draw();
518
519             box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
520             box->SetFillColor(isec+1);
521             box->Draw();
522
523             box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
524             box->SetFillColor(isec+1);
525             box->Draw();
526         }
527     }
528 }
529 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
530 {
531     (*fCorr)[isec]=func;
532 }
533
534 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
535
536     return (TF1*) (*fCorr)[isec];
537 }
538
539 AliMUONSegmentationV01& AliMUONSegmentationV01::operator 
540 =(const AliMUONSegmentationV01 & rhs)
541 {
542 // Dummy assignment operator
543     return *this;
544 }