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.19 2001/05/16 14:57:17 alibrary
19 New files for folders and Stack
21 Revision 1.18 2001/04/11 12:33:56 morsch
22 Bug in GetPadC in case of staggered planes corrected. (Thanks to J.P. Cussonneau)
24 Revision 1.17 2001/01/30 12:17:04 morsch
25 Remove obolete print-statement.
27 Revision 1.16 2001/01/30 09:23:14 hristov
28 Streamers removed (R.Brun)
30 Revision 1.15 2001/01/26 21:25:48 morsch
31 Empty default constructors and.
33 Revision 1.14 2000/12/21 22:12:41 morsch
34 Clean-up of coding rule violations,
36 Revision 1.13 2000/12/07 10:41:51 hristov
37 fCorr replaced by fCorrA
39 Revision 1.12 2000/12/06 11:55:41 morsch
40 Introduce SetOffsetY(Float_t off) method as simplified simulation of pad staggering.
41 fOffset is the staggering offset in y.
43 Revision 1.11 2000/11/06 09:20:43 morsch
44 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
45 Draw() method. This avoids code and parameter replication.
47 Revision 1.10 2000/10/18 11:42:06 morsch
48 - AliMUONRawCluster contains z-position.
49 - Some clean-up of useless print statements during initialisations.
51 Revision 1.9 2000/10/18 08:41:32 morsch
52 Make NextPad() and MorePads() to iterate until the end.
54 Revision 1.8 2000/10/03 21:48:07 morsch
55 Adopt to const declaration of some of the methods in AliSegmentation.
57 Revision 1.7 2000/10/02 21:28:09 fca
58 Removal of useless dependecies via forward declarations
60 Revision 1.6 2000/10/02 16:58:29 egangler
61 Cleaning of the code :
64 -> some useless includes removed or replaced by "class" statement
66 Revision 1.5 2000/07/13 16:19:44 fca
67 Mainly coding conventions + some small bug fixes
69 Revision 1.4 2000/07/03 11:54:57 morsch
70 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
71 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
73 Revision 1.3 2000/06/29 12:34:09 morsch
74 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
75 it usable with any other geometry class. The link to the object to which it belongs is
76 established via an index. This assumes that there exists a global geometry manager
77 from which the pointer to the parent object can be obtained (in our case gAlice).
79 Revision 1.2 2000/06/15 07:58:48 morsch
80 Code from MUON-dev joined
82 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
83 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
88 /////////////////////////////////////////////////////
89 // Segmentation and Response classes version 01 //
90 /////////////////////////////////////////////////////
96 #include <TGeometry.h>
98 #include <TObjArray.h>
101 #include "AliMUONSegmentationV01.h"
103 #include "AliMUONChamber.h"
108 //___________________________________________
109 ClassImp(AliMUONSegmentationV01)
111 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
113 // Dummy copy constructor
116 AliMUONSegmentationV01::AliMUONSegmentationV01()
118 // Default constructor
125 AliMUONSegmentationV01::AliMUONSegmentationV01(Int_t nsec)
127 // Non default constructor
130 fRSec = new TArrayF(fNsec);
131 fNDiv = new TArrayI(fNsec);
132 fDpxD = new TArrayF(fNsec);
135 (*fRSec)[0]=(*fRSec)[1]=(*fRSec)[2]=(*fRSec)[3]=0;
136 (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
137 (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
138 fCorrA = new TObjArray(3);
145 AliMUONSegmentationV01::~AliMUONSegmentationV01()
148 if (fRSec) delete fRSec;
149 if (fNDiv) delete fNDiv;
150 if (fDpxD) delete fDpxD;
158 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
161 // Returns x-pad size for given sector isec
162 Float_t dpx = (*fDpxD)[isec];
166 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
169 // Returns y-pad size for given sector isec
173 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
176 // Set the radii of the segmentation zones
177 for (Int_t i=0; i<4; i++) {
183 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
186 // Defines the pad size perp. to the anode wire (y) for different sectors.
187 // Pad sizes are defined as integral fractions ndiv of a basis pad size
190 for (Int_t i=0; i<4; i++) {
197 void AliMUONSegmentationV01::Init(Int_t chamber)
200 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
201 // These arrays help in converting from real to pad co-ordinates and
203 // This version approximates concentric segmentation zones
206 //printf("\n Initialise Segmentation V01\n");
209 fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
211 (*fDpxD)[fNsec-1]=fDpx;
213 for (Int_t i=fNsec-2; i>=0; i--){
214 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
218 // fill the arrays defining the pad segmentation boundaries
223 // loop over sections
224 for(isec=0; isec<fNsec; isec++) {
226 // loop over pads along the aode wires
227 for (Int_t iy=1; iy<=fNpy; iy++) {
229 Float_t x=iy*fDpy-fDpy/2;
230 if (x > (*fRSec)[isec]) {
234 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
236 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
237 if (isec < fNsec-1) {
238 if (TMath::Odd((Long_t)dnx)) dnx++;
240 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
241 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
242 } else if (isec == 1) {
243 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
244 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
245 add=4 - (fNpxS[isec][iy])%4;
246 if (add < 4) fNpxS[isec][iy]+=add;
247 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
248 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
250 dnx=Int_t(ry/(*fDpxD)[isec]);
252 fCx[isec][iy]=dnx*(*fDpxD)[isec];
257 // reference to chamber
258 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
259 fChamber=&(pMUON->Chamber(chamber));
264 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
266 // Returns sector number for given pad position
268 Int_t absix=TMath::Abs(ix);
269 Int_t absiy=TMath::Abs(iy);
271 for (Int_t i=0; i<fNsec; i++) {
272 if (absix<=fNpxS[i][absiy]){
280 void AliMUONSegmentationV01::
281 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
283 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
285 iy = (y-fOffsetY >0)?
286 Int_t((y-fOffsetY)/fDpy)+1
288 Int_t((y-fOffsetY)/fDpy)-1;
290 if (iy > fNpy) iy= fNpy;
291 if (iy < -fNpy) iy=-fNpy;
295 Float_t absx=TMath::Abs(x);
296 Int_t absiy=TMath::Abs(iy);
297 for (Int_t i=0; i < fNsec; i++) {
298 if (absx <= fCx[i][absiy]) {
304 ix= Int_t((absx-fCx[isec-1][absiy])/(*fDpxD)[isec])
305 +fNpxS[isec-1][absiy]+1;
306 } else if (isec == 0) {
307 ix= Int_t(absx/(*fDpxD)[isec])+1;
309 ix=fNpxS[fNsec-1][absiy]+1;
314 void AliMUONSegmentationV01::
315 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
317 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
320 Float_t(iy*fDpy)-fDpy/2.+fOffsetY
322 Float_t(iy*fDpy)+fDpy/2.+fOffsetY;
326 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
328 Int_t absix=TMath::Abs(ix);
329 Int_t absiy=TMath::Abs(iy);
331 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*(*fDpxD)[isec];
332 x=(ix>0) ? x-(*fDpxD)[isec]/2 : -x+(*fDpxD)[isec]/2;
338 void AliMUONSegmentationV01::
339 SetPad(Int_t ix, Int_t iy)
342 // Sets virtual pad coordinates, needed for evaluating pad response
343 // outside the tracking program
344 GetPadC(ix,iy,fX,fY);
345 fSector=Sector(ix,iy);
349 void AliMUONSegmentationV01::
350 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
352 // Initialises iteration over pads for charge distribution algorithm
355 // Find the wire position (center of charge distribution)
356 Float_t x0a=GetAnod(xhit);
361 // and take fNsigma*sigma around this center
362 Float_t x01=x0a - dx;
363 Float_t x02=x0a + dx;
364 Float_t y01=yhit - dy;
365 Float_t y02=yhit + dy;
367 // find the pads over which the charge distributes
369 GetPadI(x01,y01,fIxmin,fIymin);
370 GetPadI(x02,y02,fIxmax,fIymax);
377 // Set current pad to lower left corner
378 if (fIxmax < fIxmin) fIxmax=fIxmin;
379 if (fIymax < fIymin) fIymax=fIymin;
382 GetPadC(fIx,fIy,fX,fY);
386 void AliMUONSegmentationV01::NextPad()
388 // Stepper for the iteration over pads
390 // Step to next pad in the integration region
392 // Step to next pad in integration region
396 // step from left to right
398 if (fX < fXmax && fX != 0) {
402 } else if (fIy != fIymax) {
405 // get y-position of next row (yc), xc not used here
406 GetPadC(fIx,fIy,xc,yc);
407 // get x-pad coordiante for first pad in row (fIx)
408 GetPadI(fXmin,yc,fIx,iyc);
413 GetPadC(fIx,fIy,fX,fY);
414 fSector=Sector(fIx,fIy);
416 (fSector ==-1 || fSector==0))
420 Int_t AliMUONSegmentationV01::MorePads()
423 // Stopping condition for the iterator over pads
425 // Are there more pads in the integration region
426 return (fIx != -1 || fIy != -1);
428 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
436 void AliMUONSegmentationV01::
437 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
439 // Returns integration limits for current pad
441 x1=fXhit-fX-Dpx(fSector)/2.;
443 y1=fYhit-fY-Dpy(fSector)/2.;
447 void AliMUONSegmentationV01::
448 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
450 // Returns list of next neighbours for given Pad (iX, iY)
452 const Float_t kEpsilon=fDpy/1000;
455 Int_t ixx, iyy, isec1;
457 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
462 if (Xlist[i]==0) Xlist[i]++;
467 if (Xlist[i]==0) Xlist[i]--;
471 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
472 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
475 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
478 // no sector boundary crossing
484 } else if (isec1 < isec0) {
485 // finer segmentation
495 // coarser segmenation
497 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
509 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
510 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
513 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
516 // no sector boundary crossing
524 } else if (isec1 < isec0) {
525 // finer segmentation
535 // coarser segmentation
537 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
549 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
551 // Returns test point on the pad plane.
552 // Used during determination of the segmoid correction of the COG-method
555 x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
557 x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
559 x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
563 void AliMUONSegmentationV01::Draw(const char* opt) const
566 // Draws the segmentation zones
568 if (!strcmp(opt,"eventdisplay")) {
569 const int kColorMUON = kBlue;
571 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
572 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
573 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
574 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
576 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
577 char nameSense1[9], nameSense2[9];
580 sprintf(nameChamber,"C_MUON%d",fId+1);
581 sprintf(nameSense,"S_MUON%d",fId+1);
582 sprintf(nameSense1,"S1_MUON%d",fId+1);
583 sprintf(nameSense2,"S2_MUON%d",fId+1);
584 sprintf(nameFrame,"F_MUON%d",fId+1);
586 TNode* top=gAlice->GetGeometry()->GetNode("alice");
588 Float_t rmin = (*fRSec)[0]-3;
589 Float_t rmax = (*fRSec)[3]+3;
590 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
593 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
594 Float_t dx=(rmax-rmin)/2;
597 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
599 sprintf(nameNode,"MUON%d",100+fId+1);
600 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,fChamber->Z(),"");
601 node->SetLineColor(kColorMUON);
602 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
603 (pMUON->Nodes())->Add(node);
605 sprintf(nameNode,"MUON%d",200+fId+1);
606 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
607 node->SetLineColor(kColorMUON);
610 sprintf(nameNode,"MUON%d",300+fId+1);
611 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
612 nodeF->SetLineColor(kColorMUON);
614 sprintf(nameNode,"MUON%d",400+fId+1);
615 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
616 nodeF->SetLineColor(kColorMUON);
618 sprintf(nameNode,"MUON%d",500+fId+1);
619 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
620 nodeF->SetLineColor(kColorMUON);
622 sprintf(nameNode,"MUON%d",600+fId+1);
623 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
624 nodeF->SetLineColor(kColorMUON);
628 Float_t dx=0.95/fCx[3][1]/2;
629 Float_t dy=0.95/(Float_t(Npy()))/2;
634 for (Int_t iy=1; iy<Npy(); iy++) {
635 for (Int_t isec=0; isec<4; isec++) {
640 x0=fCx[isec-1][iy]*dx;
645 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
646 box->SetFillColor(isec+1);
649 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
650 box->SetFillColor(isec+1);
653 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
654 box->SetFillColor(isec+1);
657 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
658 box->SetFillColor(isec+1);
664 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
666 // Set the correction function
667 fCorrA->AddAt(func,isec);
670 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
672 // Get correction function
673 return (TF1*) (*fCorrA)[isec];
676 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
677 =(const AliMUONSegmentationV01 & rhs)
679 // Dummy assignment operator