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.13 2000/12/07 10:41:51 hristov
19 fCorr replaced by fCorrA
21 Revision 1.12 2000/12/06 11:55:41 morsch
22 Introduce SetOffsetY(Float_t off) method as simplified simulation of pad staggering.
23 fOffset is the staggering offset in y.
25 Revision 1.11 2000/11/06 09:20:43 morsch
26 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
27 Draw() method. This avoids code and parameter replication.
29 Revision 1.10 2000/10/18 11:42:06 morsch
30 - AliMUONRawCluster contains z-position.
31 - Some clean-up of useless print statements during initialisations.
33 Revision 1.9 2000/10/18 08:41:32 morsch
34 Make NextPad() and MorePads() to iterate until the end.
36 Revision 1.8 2000/10/03 21:48:07 morsch
37 Adopt to const declaration of some of the methods in AliSegmentation.
39 Revision 1.7 2000/10/02 21:28:09 fca
40 Removal of useless dependecies via forward declarations
42 Revision 1.6 2000/10/02 16:58:29 egangler
43 Cleaning of the code :
46 -> some useless includes removed or replaced by "class" statement
48 Revision 1.5 2000/07/13 16:19:44 fca
49 Mainly coding conventions + some small bug fixes
51 Revision 1.4 2000/07/03 11:54:57 morsch
52 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
53 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
55 Revision 1.3 2000/06/29 12:34:09 morsch
56 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
57 it usable with any other geometry class. The link to the object to which it belongs is
58 established via an index. This assumes that there exists a global geometry manager
59 from which the pointer to the parent object can be obtained (in our case gAlice).
61 Revision 1.2 2000/06/15 07:58:48 morsch
62 Code from MUON-dev joined
64 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
65 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
70 /////////////////////////////////////////////////////
71 // Segmentation and Response classes version 01 //
72 /////////////////////////////////////////////////////
78 #include <TGeometry.h>
80 #include <TObjArray.h>
83 #include "AliMUONSegmentationV01.h"
85 #include "AliMUONChamber.h"
90 //___________________________________________
91 ClassImp(AliMUONSegmentationV01)
93 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
95 // Dummy copy constructor
97 AliMUONSegmentationV01::AliMUONSegmentationV01()
99 // Default constructor
101 fRSec = new TArrayF(fNsec);
102 fNDiv = new TArrayI(fNsec);
103 fDpxD = new TArrayF(fNsec);
104 (*fRSec)[0]=(*fRSec)[1]=(*fRSec)[2]=(*fRSec)[3]=0;
105 (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
106 (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
107 fCorrA = new TObjArray(3);
114 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
117 // Returns x-pad size for given sector isec
118 Float_t dpx = (*fDpxD)[isec];
122 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
125 // Returns y-pad size for given sector isec
129 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
132 // Set the radii of the segmentation zones
133 for (Int_t i=0; i<4; i++) {
139 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
142 // Defines the pad size perp. to the anode wire (y) for different sectors.
143 // Pad sizes are defined as integral fractions ndiv of a basis pad size
146 for (Int_t i=0; i<4; i++) {
153 void AliMUONSegmentationV01::Init(Int_t chamber)
156 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
157 // These arrays help in converting from real to pad co-ordinates and
159 // This version approximates concentric segmentation zones
162 printf("\n Initialise Segmentation V01\n");
163 fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
165 (*fDpxD)[fNsec-1]=fDpx;
167 for (Int_t i=fNsec-2; i>=0; i--){
168 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
172 // fill the arrays defining the pad segmentation boundaries
177 // loop over sections
178 for(isec=0; isec<fNsec; isec++) {
180 // loop over pads along the aode wires
181 for (Int_t iy=1; iy<=fNpy; iy++) {
183 Float_t x=iy*fDpy-fDpy/2;
184 if (x > (*fRSec)[isec]) {
188 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
190 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
191 if (isec < fNsec-1) {
192 if (TMath::Odd((Long_t)dnx)) dnx++;
194 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
195 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
196 } else if (isec == 1) {
197 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
198 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
199 add=4 - (fNpxS[isec][iy])%4;
200 if (add < 4) fNpxS[isec][iy]+=add;
201 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
202 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
204 dnx=Int_t(ry/(*fDpxD)[isec]);
206 fCx[isec][iy]=dnx*(*fDpxD)[isec];
211 // reference to chamber
212 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
213 fChamber=&(pMUON->Chamber(chamber));
218 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
220 // Returns sector number for given pad position
222 Int_t absix=TMath::Abs(ix);
223 Int_t absiy=TMath::Abs(iy);
225 for (Int_t i=0; i<fNsec; i++) {
226 if (absix<=fNpxS[i][absiy]){
234 void AliMUONSegmentationV01::
235 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
237 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
239 iy = (y-fOffsetY >0)?
240 Int_t((y-fOffsetY)/fDpy)+1
242 Int_t((y-fOffsetY)/fDpy)-1;
244 if (iy > fNpy) iy= fNpy;
245 if (iy < -fNpy) iy=-fNpy;
249 Float_t absx=TMath::Abs(x);
250 Int_t absiy=TMath::Abs(iy);
251 for (Int_t i=0; i < fNsec; i++) {
252 if (absx <= fCx[i][absiy]) {
258 ix= Int_t((absx-fCx[isec-1][absiy])/(*fDpxD)[isec])
259 +fNpxS[isec-1][absiy]+1;
260 } else if (isec == 0) {
261 ix= Int_t(absx/(*fDpxD)[isec])+1;
263 ix=fNpxS[fNsec-1][absiy]+1;
268 void AliMUONSegmentationV01::
269 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
271 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
274 Float_t(iy*fDpy)-fDpy/2.+fOffsetY
276 Float_t(iy*fDpy)+fDpy/2.-fOffsetY;
279 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
281 Int_t absix=TMath::Abs(ix);
282 Int_t absiy=TMath::Abs(iy);
284 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*(*fDpxD)[isec];
285 x=(ix>0) ? x-(*fDpxD)[isec]/2 : -x+(*fDpxD)[isec]/2;
291 void AliMUONSegmentationV01::
292 SetPad(Int_t ix, Int_t iy)
295 // Sets virtual pad coordinates, needed for evaluating pad response
296 // outside the tracking program
297 GetPadC(ix,iy,fX,fY);
298 fSector=Sector(ix,iy);
302 void AliMUONSegmentationV01::
303 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
305 // Initialises iteration over pads for charge distribution algorithm
308 // Find the wire position (center of charge distribution)
309 Float_t x0a=GetAnod(xhit);
314 // and take fNsigma*sigma around this center
315 Float_t x01=x0a - dx;
316 Float_t x02=x0a + dx;
317 Float_t y01=yhit - dy;
318 Float_t y02=yhit + dy;
320 // find the pads over which the charge distributes
322 GetPadI(x01,y01,fIxmin,fIymin);
323 GetPadI(x02,y02,fIxmax,fIymax);
330 // Set current pad to lower left corner
331 if (fIxmax < fIxmin) fIxmax=fIxmin;
332 if (fIymax < fIymin) fIymax=fIymin;
335 GetPadC(fIx,fIy,fX,fY);
339 void AliMUONSegmentationV01::NextPad()
341 // Stepper for the iteration over pads
343 // Step to next pad in the integration region
345 // Step to next pad in integration region
349 // step from left to right
351 if (fX < fXmax && fX != 0) {
355 } else if (fIy != fIymax) {
358 // get y-position of next row (yc), xc not used here
359 GetPadC(fIx,fIy,xc,yc);
360 // get x-pad coordiante for first pad in row (fIx)
361 GetPadI(fXmin,yc,fIx,iyc);
366 GetPadC(fIx,fIy,fX,fY);
367 fSector=Sector(fIx,fIy);
369 (fSector ==-1 || fSector==0))
373 Int_t AliMUONSegmentationV01::MorePads()
376 // Stopping condition for the iterator over pads
378 // Are there more pads in the integration region
379 return (fIx != -1 || fIy != -1);
381 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
389 void AliMUONSegmentationV01::
390 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
392 // Returns integration limits for current pad
394 x1=fXhit-fX-Dpx(fSector)/2.;
396 y1=fYhit-fY-Dpy(fSector)/2.;
400 void AliMUONSegmentationV01::
401 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
403 // Returns list of next neighbours for given Pad (iX, iY)
405 const Float_t kEpsilon=fDpy/1000;
408 Int_t ixx, iyy, isec1;
410 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
415 if (Xlist[i]==0) Xlist[i]++;
420 if (Xlist[i]==0) Xlist[i]--;
424 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
425 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
428 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
431 // no sector boundary crossing
437 } else if (isec1 < isec0) {
438 // finer segmentation
448 // coarser segmenation
450 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
462 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
463 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
466 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
469 // no sector boundary crossing
477 } else if (isec1 < isec0) {
478 // finer segmentation
488 // coarser segmentation
490 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
502 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
504 // Returns test point on the pad plane.
505 // Used during determination of the segmoid correction of the COG-method
508 x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
510 x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
512 x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
516 void AliMUONSegmentationV01::Draw(const char* opt) const
519 // Draws the segmentation zones
521 if (!strcmp(opt,"eventdisplay")) {
522 const int kColorMUON = kBlue;
524 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
525 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
526 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
527 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
529 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
530 char nameSense1[9], nameSense2[9];
533 sprintf(nameChamber,"C_MUON%d",fId+1);
534 sprintf(nameSense,"S_MUON%d",fId+1);
535 sprintf(nameSense1,"S1_MUON%d",fId+1);
536 sprintf(nameSense2,"S2_MUON%d",fId+1);
537 sprintf(nameFrame,"F_MUON%d",fId+1);
539 TNode* top=gAlice->GetGeometry()->GetNode("alice");
541 Float_t rmin = (*fRSec)[0]-3;
542 Float_t rmax = (*fRSec)[3]+3;
543 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
546 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
547 Float_t dx=(rmax-rmin)/2;
550 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
552 sprintf(nameNode,"MUON%d",100+fId+1);
553 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,fChamber->Z(),"");
554 node->SetLineColor(kColorMUON);
555 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
556 (pMUON->Nodes())->Add(node);
558 sprintf(nameNode,"MUON%d",200+fId+1);
559 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
560 node->SetLineColor(kColorMUON);
563 sprintf(nameNode,"MUON%d",300+fId+1);
564 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
565 nodeF->SetLineColor(kColorMUON);
567 sprintf(nameNode,"MUON%d",400+fId+1);
568 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
569 nodeF->SetLineColor(kColorMUON);
571 sprintf(nameNode,"MUON%d",500+fId+1);
572 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
573 nodeF->SetLineColor(kColorMUON);
575 sprintf(nameNode,"MUON%d",600+fId+1);
576 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
577 nodeF->SetLineColor(kColorMUON);
581 Float_t dx=0.95/fCx[3][1]/2;
582 Float_t dy=0.95/(Float_t(Npy()))/2;
587 for (Int_t iy=1; iy<Npy(); iy++) {
588 for (Int_t isec=0; isec<4; isec++) {
593 x0=fCx[isec-1][iy]*dx;
598 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
599 box->SetFillColor(isec+1);
602 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
603 box->SetFillColor(isec+1);
606 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
607 box->SetFillColor(isec+1);
610 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
611 box->SetFillColor(isec+1);
617 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
619 // Set the correction function
620 (*fCorrA)[isec]=func;
623 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
625 // Get correction function
626 return (TF1*) (*fCorrA)[isec];
629 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
630 =(const AliMUONSegmentationV01 & rhs)
632 // Dummy assignment operator