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