1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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.
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.
26 Revision 1.9 2000/10/18 08:41:32 morsch
27 Make NextPad() and MorePads() to iterate until the end.
29 Revision 1.8 2000/10/03 21:48:07 morsch
30 Adopt to const declaration of some of the methods in AliSegmentation.
32 Revision 1.7 2000/10/02 21:28:09 fca
33 Removal of useless dependecies via forward declarations
35 Revision 1.6 2000/10/02 16:58:29 egangler
36 Cleaning of the code :
39 -> some useless includes removed or replaced by "class" statement
41 Revision 1.5 2000/07/13 16:19:44 fca
42 Mainly coding conventions + some small bug fixes
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.
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).
54 Revision 1.2 2000/06/15 07:58:48 morsch
55 Code from MUON-dev joined
57 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
58 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
63 /////////////////////////////////////////////////////
64 // Segmentation and Response classes version 01 //
65 /////////////////////////////////////////////////////
71 #include <TGeometry.h>
73 #include <TObjArray.h>
76 #include "AliMUONSegmentationV01.h"
78 #include "AliMUONChamber.h"
83 //___________________________________________
84 ClassImp(AliMUONSegmentationV01)
86 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
88 // Dummy copy constructor
90 AliMUONSegmentationV01::AliMUONSegmentationV01()
92 // Default constructor
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);
107 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
110 // Returns x-pad size for given sector isec
111 Float_t dpx = (*fDpxD)[isec];
115 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
118 // Returns y-pad size for given sector isec
122 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
125 // Set the radii of the segmentation zones
126 for (Int_t i=0; i<4; i++) {
132 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
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
139 for (Int_t i=0; i<4; i++) {
146 void AliMUONSegmentationV01::Init(Int_t chamber)
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
152 // This version approximates concentric segmentation zones
155 printf("\n Initialise Segmentation V01\n");
156 fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
158 (*fDpxD)[fNsec-1]=fDpx;
160 for (Int_t i=fNsec-2; i>=0; i--){
161 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
165 // fill the arrays defining the pad segmentation boundaries
170 // loop over sections
171 for(isec=0; isec<fNsec; isec++) {
173 // loop over pads along the aode wires
174 for (Int_t iy=1; iy<=fNpy; iy++) {
176 Float_t x=iy*fDpy-fDpy/2;
177 if (x > (*fRSec)[isec]) {
181 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
183 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
184 if (isec < fNsec-1) {
185 if (TMath::Odd((Long_t)dnx)) dnx++;
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];
197 dnx=Int_t(ry/(*fDpxD)[isec]);
199 fCx[isec][iy]=dnx*(*fDpxD)[isec];
204 // reference to chamber
205 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
206 fChamber=&(pMUON->Chamber(chamber));
211 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
213 // Returns sector number for given pad position
215 Int_t absix=TMath::Abs(ix);
216 Int_t absiy=TMath::Abs(iy);
218 for (Int_t i=0; i<fNsec; i++) {
219 if (absix<=fNpxS[i][absiy]){
227 void AliMUONSegmentationV01::
228 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
230 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
232 iy = (y-fOffsetY >0)?
233 Int_t((y-fOffsetY)/fDpy)+1
235 Int_t((y-fOffsetY)/fDpy)-1;
237 if (iy > fNpy) iy= fNpy;
238 if (iy < -fNpy) iy=-fNpy;
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]) {
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;
256 ix=fNpxS[fNsec-1][absiy]+1;
261 void AliMUONSegmentationV01::
262 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
264 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
267 Float_t(iy*fDpy)-fDpy/2.+fOffsetY
269 Float_t(iy*fDpy)+fDpy/2.-fOffsetY;
272 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
274 Int_t absix=TMath::Abs(ix);
275 Int_t absiy=TMath::Abs(iy);
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;
284 void AliMUONSegmentationV01::
285 SetPad(Int_t ix, Int_t iy)
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);
295 void AliMUONSegmentationV01::
296 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
298 // Initialises iteration over pads for charge distribution algorithm
301 // Find the wire position (center of charge distribution)
302 Float_t x0a=GetAnod(xhit);
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;
313 // find the pads over which the charge distributes
315 GetPadI(x01,y01,fIxmin,fIymin);
316 GetPadI(x02,y02,fIxmax,fIymax);
323 // Set current pad to lower left corner
324 if (fIxmax < fIxmin) fIxmax=fIxmin;
325 if (fIymax < fIymin) fIymax=fIymin;
328 GetPadC(fIx,fIy,fX,fY);
332 void AliMUONSegmentationV01::NextPad()
334 // Stepper for the iteration over pads
336 // Step to next pad in the integration region
338 // Step to next pad in integration region
342 // step from left to right
344 if (fX < fXmax && fX != 0) {
348 } else if (fIy != fIymax) {
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);
359 GetPadC(fIx,fIy,fX,fY);
360 fSector=Sector(fIx,fIy);
362 (fSector ==-1 || fSector==0))
366 Int_t AliMUONSegmentationV01::MorePads()
367 // Stopping condition for the iterator over pads
369 // Are there more pads in the integration region
371 return (fIx != -1 || fIy != -1);
373 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
381 void AliMUONSegmentationV01::
382 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
384 // Returns integration limits for current pad
386 x1=fXhit-fX-Dpx(fSector)/2.;
388 y1=fYhit-fY-Dpy(fSector)/2.;
392 void AliMUONSegmentationV01::
393 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
395 // Returns list of next neighbours for given Pad (iX, iY)
397 const Float_t kEpsilon=fDpy/1000;
400 Int_t ixx, iyy, isec1;
402 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
407 if (Xlist[i]==0) Xlist[i]++;
412 if (Xlist[i]==0) Xlist[i]--;
416 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
417 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
420 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
423 // no sector boundary crossing
429 } else if (isec1 < isec0) {
430 // finer segmentation
440 // coarser segmenation
442 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
454 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
455 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
458 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
461 // no sector boundary crossing
469 } else if (isec1 < isec0) {
470 // finer segmentation
480 // coarser segmentation
482 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
494 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
496 // Returns test point on the pad plane.
497 // Used during determination of the segmoid correction of the COG-method
500 x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
502 x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
504 x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
508 void AliMUONSegmentationV01::Draw(const char* opt) const
511 // Draws the segmentation zones
513 if (!strcmp(opt,"eventdisplay")) {
514 const int kColorMUON = kBlue;
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);
521 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
522 char nameSense1[9], nameSense2[9];
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);
531 TNode* top=gAlice->GetGeometry()->GetNode("alice");
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.);
538 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
539 Float_t dx=(rmax-rmin)/2;
542 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
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);
550 sprintf(nameNode,"MUON%d",200+fId+1);
551 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
552 node->SetLineColor(kColorMUON);
555 sprintf(nameNode,"MUON%d",300+fId+1);
556 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
557 nodeF->SetLineColor(kColorMUON);
559 sprintf(nameNode,"MUON%d",400+fId+1);
560 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
561 nodeF->SetLineColor(kColorMUON);
563 sprintf(nameNode,"MUON%d",500+fId+1);
564 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
565 nodeF->SetLineColor(kColorMUON);
567 sprintf(nameNode,"MUON%d",600+fId+1);
568 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
569 nodeF->SetLineColor(kColorMUON);
573 Float_t dx=0.95/fCx[3][1]/2;
574 Float_t dy=0.95/(Float_t(Npy()))/2;
579 for (Int_t iy=1; iy<Npy(); iy++) {
580 for (Int_t isec=0; isec<4; isec++) {
585 x0=fCx[isec-1][iy]*dx;
590 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
591 box->SetFillColor(isec+1);
594 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
595 box->SetFillColor(isec+1);
598 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
599 box->SetFillColor(isec+1);
602 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
603 box->SetFillColor(isec+1);
609 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
614 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
616 return (TF1*) (*fCorr)[isec];
619 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
620 =(const AliMUONSegmentationV01 & rhs)
622 // Dummy assignment operator