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.10 2000/10/18 11:42:06 morsch
19 - AliMUONRawCluster contains z-position.
20 - Some clean-up of useless print statements during initialisations.
22 Revision 1.9 2000/10/18 08:41:32 morsch
23 Make NextPad() and MorePads() to iterate until the end.
25 Revision 1.8 2000/10/03 21:48:07 morsch
26 Adopt to const declaration of some of the methods in AliSegmentation.
28 Revision 1.7 2000/10/02 21:28:09 fca
29 Removal of useless dependecies via forward declarations
31 Revision 1.6 2000/10/02 16:58:29 egangler
32 Cleaning of the code :
35 -> some useless includes removed or replaced by "class" statement
37 Revision 1.5 2000/07/13 16:19:44 fca
38 Mainly coding conventions + some small bug fixes
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.
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).
50 Revision 1.2 2000/06/15 07:58:48 morsch
51 Code from MUON-dev joined
53 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
54 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
59 /////////////////////////////////////////////////////
60 // Segmentation and Response classes version 01 //
61 /////////////////////////////////////////////////////
67 #include <TGeometry.h>
69 #include <TObjArray.h>
72 #include "AliMUONSegmentationV01.h"
74 #include "AliMUONChamber.h"
79 //___________________________________________
80 ClassImp(AliMUONSegmentationV01)
82 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
84 // Dummy copy constructor
86 AliMUONSegmentationV01::AliMUONSegmentationV01()
88 // Default constructor
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);
102 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
105 // Returns x-pad size for given sector isec
106 Float_t dpx = (*fDpxD)[isec];
110 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
113 // Returns y-pad size for given sector isec
117 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
120 // Set the radii of the segmentation zones
121 for (Int_t i=0; i<4; i++) {
127 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
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
134 for (Int_t i=0; i<4; i++) {
141 void AliMUONSegmentationV01::Init(Int_t chamber)
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
147 // This version approximates concentric segmentation zones
150 printf("\n Initialise Segmentation V01\n");
151 fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
153 (*fDpxD)[fNsec-1]=fDpx;
155 for (Int_t i=fNsec-2; i>=0; i--){
156 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
160 // fill the arrays defining the pad segmentation boundaries
165 // loop over sections
166 for(isec=0; isec<fNsec; isec++) {
168 // loop over pads along the aode wires
169 for (Int_t iy=1; iy<=fNpy; iy++) {
171 Float_t x=iy*fDpy-fDpy/2;
172 if (x > (*fRSec)[isec]) {
176 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
178 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
179 if (isec < fNsec-1) {
180 if (TMath::Odd((Long_t)dnx)) dnx++;
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];
192 dnx=Int_t(ry/(*fDpxD)[isec]);
194 fCx[isec][iy]=dnx*(*fDpxD)[isec];
199 // reference to chamber
200 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
201 fChamber=&(pMUON->Chamber(chamber));
206 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
208 // Returns sector number for given pad position
210 Int_t absix=TMath::Abs(ix);
211 Int_t absiy=TMath::Abs(iy);
213 for (Int_t i=0; i<fNsec; i++) {
214 if (absix<=fNpxS[i][absiy]){
222 void AliMUONSegmentationV01::
223 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
225 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
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;
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]) {
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;
247 ix=fNpxS[fNsec-1][absiy]+1;
252 void AliMUONSegmentationV01::
253 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
255 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
257 y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
260 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
262 Int_t absix=TMath::Abs(ix);
263 Int_t absiy=TMath::Abs(iy);
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;
272 void AliMUONSegmentationV01::
273 SetPad(Int_t ix, Int_t iy)
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);
283 void AliMUONSegmentationV01::
284 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
286 // Initialises iteration over pads for charge distribution algorithm
289 // Find the wire position (center of charge distribution)
290 Float_t x0a=GetAnod(xhit);
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;
301 // find the pads over which the charge distributes
303 GetPadI(x01,y01,fIxmin,fIymin);
304 GetPadI(x02,y02,fIxmax,fIymax);
311 // Set current pad to lower left corner
312 if (fIxmax < fIxmin) fIxmax=fIxmin;
313 if (fIymax < fIymin) fIymax=fIymin;
316 GetPadC(fIx,fIy,fX,fY);
320 void AliMUONSegmentationV01::NextPad()
322 // Stepper for the iteration over pads
324 // Step to next pad in the integration region
326 // Step to next pad in integration region
330 // step from left to right
332 if (fX < fXmax && fX != 0) {
336 } else if (fIy != fIymax) {
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);
347 GetPadC(fIx,fIy,fX,fY);
348 fSector=Sector(fIx,fIy);
350 (fSector ==-1 || fSector==0))
354 Int_t AliMUONSegmentationV01::MorePads()
355 // Stopping condition for the iterator over pads
357 // Are there more pads in the integration region
359 return (fIx != -1 || fIy != -1);
361 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
369 void AliMUONSegmentationV01::
370 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
372 // Returns integration limits for current pad
374 x1=fXhit-fX-Dpx(fSector)/2.;
376 y1=fYhit-fY-Dpy(fSector)/2.;
380 void AliMUONSegmentationV01::
381 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
383 // Returns list of next neighbours for given Pad (iX, iY)
385 const Float_t kEpsilon=fDpy/1000;
388 Int_t ixx, iyy, isec1;
390 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
395 if (Xlist[i]==0) Xlist[i]++;
400 if (Xlist[i]==0) Xlist[i]--;
404 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
405 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
408 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
411 // no sector boundary crossing
417 } else if (isec1 < isec0) {
418 // finer segmentation
428 // coarser segmenation
430 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
442 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
443 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
446 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
449 // no sector boundary crossing
457 } else if (isec1 < isec0) {
458 // finer segmentation
468 // coarser segmentation
470 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
482 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
484 // Returns test point on the pad plane.
485 // Used during determination of the segmoid correction of the COG-method
488 x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
490 x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
492 x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
496 void AliMUONSegmentationV01::Draw(const char* opt) const
499 // Draws the segmentation zones
501 if (!strcmp(opt,"eventdisplay")) {
502 const int kColorMUON = kBlue;
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);
509 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
510 char nameSense1[9], nameSense2[9];
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);
519 TNode* top=gAlice->GetGeometry()->GetNode("alice");
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.);
526 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
527 Float_t dx=(rmax-rmin)/2;
530 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
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);
538 sprintf(nameNode,"MUON%d",200+fId+1);
539 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
540 node->SetLineColor(kColorMUON);
543 sprintf(nameNode,"MUON%d",300+fId+1);
544 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
545 nodeF->SetLineColor(kColorMUON);
547 sprintf(nameNode,"MUON%d",400+fId+1);
548 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
549 nodeF->SetLineColor(kColorMUON);
551 sprintf(nameNode,"MUON%d",500+fId+1);
552 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
553 nodeF->SetLineColor(kColorMUON);
555 sprintf(nameNode,"MUON%d",600+fId+1);
556 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
557 nodeF->SetLineColor(kColorMUON);
561 Float_t dx=0.95/fCx[3][1]/2;
562 Float_t dy=0.95/(Float_t(Npy()))/2;
567 for (Int_t iy=1; iy<Npy(); iy++) {
568 for (Int_t isec=0; isec<4; isec++) {
573 x0=fCx[isec-1][iy]*dx;
578 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
579 box->SetFillColor(isec+1);
582 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
583 box->SetFillColor(isec+1);
586 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
587 box->SetFillColor(isec+1);
590 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
591 box->SetFillColor(isec+1);
597 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
602 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
604 return (TF1*) (*fCorr)[isec];
607 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
608 =(const AliMUONSegmentationV01 & rhs)
610 // Dummy assignment operator