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