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.20 2001/07/20 10:03:14 morsch
19 Changes needed to work with Root 3.01 (substitute lhs [] operator). (Jiri Chudoba)
21 Revision 1.19 2001/05/16 14:57:17 alibrary
22 New files for folders and Stack
24 Revision 1.18 2001/04/11 12:33:56 morsch
25 Bug in GetPadC in case of staggered planes corrected. (Thanks to J.P. Cussonneau)
27 Revision 1.17 2001/01/30 12:17:04 morsch
28 Remove obolete print-statement.
30 Revision 1.16 2001/01/30 09:23:14 hristov
31 Streamers removed (R.Brun)
33 Revision 1.15 2001/01/26 21:25:48 morsch
34 Empty default constructors and.
36 Revision 1.14 2000/12/21 22:12:41 morsch
37 Clean-up of coding rule violations,
39 Revision 1.13 2000/12/07 10:41:51 hristov
40 fCorr replaced by fCorrA
42 Revision 1.12 2000/12/06 11:55:41 morsch
43 Introduce SetOffsetY(Float_t off) method as simplified simulation of pad staggering.
44 fOffset is the staggering offset in y.
46 Revision 1.11 2000/11/06 09:20:43 morsch
47 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
48 Draw() method. This avoids code and parameter replication.
50 Revision 1.10 2000/10/18 11:42:06 morsch
51 - AliMUONRawCluster contains z-position.
52 - Some clean-up of useless print statements during initialisations.
54 Revision 1.9 2000/10/18 08:41:32 morsch
55 Make NextPad() and MorePads() to iterate until the end.
57 Revision 1.8 2000/10/03 21:48:07 morsch
58 Adopt to const declaration of some of the methods in AliSegmentation.
60 Revision 1.7 2000/10/02 21:28:09 fca
61 Removal of useless dependecies via forward declarations
63 Revision 1.6 2000/10/02 16:58:29 egangler
64 Cleaning of the code :
67 -> some useless includes removed or replaced by "class" statement
69 Revision 1.5 2000/07/13 16:19:44 fca
70 Mainly coding conventions + some small bug fixes
72 Revision 1.4 2000/07/03 11:54:57 morsch
73 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
74 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
76 Revision 1.3 2000/06/29 12:34:09 morsch
77 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
78 it usable with any other geometry class. The link to the object to which it belongs is
79 established via an index. This assumes that there exists a global geometry manager
80 from which the pointer to the parent object can be obtained (in our case gAlice).
82 Revision 1.2 2000/06/15 07:58:48 morsch
83 Code from MUON-dev joined
85 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
86 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
91 /////////////////////////////////////////////////////
92 // Segmentation and Response classes version 01 //
93 /////////////////////////////////////////////////////
99 #include <TGeometry.h>
101 #include <TObjArray.h>
102 #include <iostream.h>
104 #include "AliMUONSegmentationV01.h"
106 #include "AliMUONChamber.h"
111 //___________________________________________
112 ClassImp(AliMUONSegmentationV01)
114 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
116 // Dummy copy constructor
119 AliMUONSegmentationV01::AliMUONSegmentationV01()
121 // Default constructor
128 AliMUONSegmentationV01::AliMUONSegmentationV01(Int_t nsec)
130 // Non default constructor
133 fRSec = new TArrayF(fNsec);
134 fNDiv = new TArrayI(fNsec);
135 fDpxD = new TArrayF(fNsec);
138 (*fRSec)[0]=(*fRSec)[1]=(*fRSec)[2]=(*fRSec)[3]=0;
139 (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
140 (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
141 fCorrA = new TObjArray(3);
148 AliMUONSegmentationV01::~AliMUONSegmentationV01()
151 if (fRSec) delete fRSec;
152 if (fNDiv) delete fNDiv;
153 if (fDpxD) delete fDpxD;
161 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
164 // Returns x-pad size for given sector isec
165 Float_t dpx = (*fDpxD)[isec];
169 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
172 // Returns y-pad size for given sector isec
176 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
179 // Set the radii of the segmentation zones
180 for (Int_t i=0; i<4; i++) {
186 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
189 // Defines the pad size perp. to the anode wire (y) for different sectors.
190 // Pad sizes are defined as integral fractions ndiv of a basis pad size
193 for (Int_t i=0; i<4; i++) {
200 void AliMUONSegmentationV01::Init(Int_t chamber)
203 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
204 // These arrays help in converting from real to pad co-ordinates and
206 // This version approximates concentric segmentation zones
209 //printf("\n Initialise Segmentation V01\n");
212 fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
214 (*fDpxD)[fNsec-1]=fDpx;
216 for (Int_t i=fNsec-2; i>=0; i--){
217 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
221 // fill the arrays defining the pad segmentation boundaries
226 // loop over sections
227 for(isec=0; isec<fNsec; isec++) {
229 // loop over pads along the aode wires
230 for (Int_t iy=1; iy<=fNpy; iy++) {
232 Float_t x=iy*fDpy-fDpy/2;
233 if (x > (*fRSec)[isec]) {
237 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
239 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
240 if (isec < fNsec-1) {
241 if (TMath::Odd((Long_t)dnx)) dnx++;
243 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
244 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
245 } else if (isec == 1) {
246 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
247 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
248 add=4 - (fNpxS[isec][iy])%4;
249 if (add < 4) fNpxS[isec][iy]+=add;
250 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
251 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
253 dnx=Int_t(ry/(*fDpxD)[isec]);
255 fCx[isec][iy]=dnx*(*fDpxD)[isec];
260 // reference to chamber
261 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
262 fChamber=&(pMUON->Chamber(chamber));
267 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
269 // Returns sector number for given pad position
271 Int_t absix=TMath::Abs(ix);
272 Int_t absiy=TMath::Abs(iy);
274 for (Int_t i=0; i<fNsec; i++) {
275 if (absix<=fNpxS[i][absiy]){
283 void AliMUONSegmentationV01::
284 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
286 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
288 iy = (y-fOffsetY >0)?
289 Int_t((y-fOffsetY)/fDpy)+1
291 Int_t((y-fOffsetY)/fDpy)-1;
293 if (iy > fNpy) iy= fNpy;
294 if (iy < -fNpy) iy=-fNpy;
298 Float_t absx=TMath::Abs(x);
299 Int_t absiy=TMath::Abs(iy);
300 for (Int_t i=0; i < fNsec; i++) {
301 if (absx <= fCx[i][absiy]) {
307 ix= Int_t((absx-fCx[isec-1][absiy])/(*fDpxD)[isec])
308 +fNpxS[isec-1][absiy]+1;
309 } else if (isec == 0) {
310 ix= Int_t(absx/(*fDpxD)[isec])+1;
312 ix=fNpxS[fNsec-1][absiy]+1;
317 void AliMUONSegmentationV01::
318 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
320 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
323 Float_t(iy*fDpy)-fDpy/2.+fOffsetY
325 Float_t(iy*fDpy)+fDpy/2.+fOffsetY;
329 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
331 Int_t absix=TMath::Abs(ix);
332 Int_t absiy=TMath::Abs(iy);
334 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*(*fDpxD)[isec];
335 x=(ix>0) ? x-(*fDpxD)[isec]/2 : -x+(*fDpxD)[isec]/2;
341 void AliMUONSegmentationV01::
342 SetPad(Int_t ix, Int_t iy)
345 // Sets virtual pad coordinates, needed for evaluating pad response
346 // outside the tracking program
347 GetPadC(ix,iy,fX,fY);
348 fSector=Sector(ix,iy);
352 void AliMUONSegmentationV01::
353 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
355 // Initialises iteration over pads for charge distribution algorithm
358 // Find the wire position (center of charge distribution)
359 Float_t x0a=GetAnod(xhit);
364 // and take fNsigma*sigma around this center
365 Float_t x01=x0a - dx;
366 Float_t x02=x0a + dx;
367 Float_t y01=yhit - dy;
368 Float_t y02=yhit + dy;
370 // find the pads over which the charge distributes
372 GetPadI(x01,y01,fIxmin,fIymin);
373 GetPadI(x02,y02,fIxmax,fIymax);
380 // Set current pad to lower left corner
381 if (fIxmax < fIxmin) fIxmax=fIxmin;
382 if (fIymax < fIymin) fIymax=fIymin;
385 GetPadC(fIx,fIy,fX,fY);
389 void AliMUONSegmentationV01::NextPad()
391 // Stepper for the iteration over pads
393 // Step to next pad in the integration region
395 // Step to next pad in integration region
399 // step from left to right
401 if (fX < fXmax && fX != 0) {
405 } else if (fIy != fIymax) {
408 // get y-position of next row (yc), xc not used here
409 GetPadC(fIx,fIy,xc,yc);
410 // get x-pad coordiante for first pad in row (fIx)
411 GetPadI(fXmin,yc,fIx,iyc);
416 GetPadC(fIx,fIy,fX,fY);
417 fSector=Sector(fIx,fIy);
419 (fSector ==-1 || fSector==0))
423 Int_t AliMUONSegmentationV01::MorePads()
426 // Stopping condition for the iterator over pads
428 // Are there more pads in the integration region
429 return (fIx != -1 || fIy != -1);
431 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
439 void AliMUONSegmentationV01::
440 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
442 // Returns integration limits for current pad
444 x1=fXhit-fX-Dpx(fSector)/2.;
446 y1=fYhit-fY-Dpy(fSector)/2.;
450 void AliMUONSegmentationV01::
451 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
453 // Returns list of next neighbours for given Pad (iX, iY)
455 const Float_t kEpsilon=fDpy/1000;
458 Int_t ixx, iyy, isec1;
460 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
465 if (Xlist[i]==0) Xlist[i]++;
470 if (Xlist[i]==0) Xlist[i]--;
474 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
475 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
478 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
481 // no sector boundary crossing
487 } else if (isec1 < isec0) {
488 // finer segmentation
498 // coarser segmenation
500 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
512 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
513 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
516 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
519 // no sector boundary crossing
527 } else if (isec1 < isec0) {
528 // finer segmentation
538 // coarser segmentation
540 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
552 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
554 // Returns test point on the pad plane.
555 // Used during determination of the segmoid correction of the COG-method
558 x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
560 x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
562 x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
566 void AliMUONSegmentationV01::Draw(const char* opt) const
569 // Draws the segmentation zones
571 if (!strcmp(opt,"eventdisplay")) {
572 const int kColorMUON = kBlue;
574 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
575 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
576 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
577 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
579 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
580 char nameSense1[9], nameSense2[9];
583 sprintf(nameChamber,"C_MUON%d",fId+1);
584 sprintf(nameSense,"S_MUON%d",fId+1);
585 sprintf(nameSense1,"S1_MUON%d",fId+1);
586 sprintf(nameSense2,"S2_MUON%d",fId+1);
587 sprintf(nameFrame,"F_MUON%d",fId+1);
589 TNode* top=gAlice->GetGeometry()->GetNode("alice");
591 Float_t rmin = (*fRSec)[0]-3;
592 Float_t rmax = (*fRSec)[3]+3;
593 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
596 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
597 Float_t dx=(rmax-rmin)/2;
600 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
602 sprintf(nameNode,"MUON%d",100+fId+1);
603 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,fChamber->Z(),"");
604 node->SetLineColor(kColorMUON);
605 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
606 (pMUON->Nodes())->Add(node);
608 sprintf(nameNode,"MUON%d",200+fId+1);
609 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
610 node->SetLineColor(kColorMUON);
613 sprintf(nameNode,"MUON%d",300+fId+1);
614 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
615 nodeF->SetLineColor(kColorMUON);
617 sprintf(nameNode,"MUON%d",400+fId+1);
618 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
619 nodeF->SetLineColor(kColorMUON);
621 sprintf(nameNode,"MUON%d",500+fId+1);
622 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
623 nodeF->SetLineColor(kColorMUON);
625 sprintf(nameNode,"MUON%d",600+fId+1);
626 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
627 nodeF->SetLineColor(kColorMUON);
631 Float_t dx=0.95/fCx[3][1]/2;
632 Float_t dy=0.95/(Float_t(Npy()))/2;
637 for (Int_t iy=1; iy<Npy(); iy++) {
638 for (Int_t isec=0; isec<4; isec++) {
643 x0=fCx[isec-1][iy]*dx;
648 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
649 box->SetFillColor(isec+1);
652 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
653 box->SetFillColor(isec+1);
656 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
657 box->SetFillColor(isec+1);
660 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
661 box->SetFillColor(isec+1);
667 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
669 // Set the correction function
670 fCorrA->AddAt(func,isec);
673 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
675 // Get correction function
676 //PH return (TF1*) (*fCorrA)[isec];
677 return (TF1*) fCorrA->At(isec);
680 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
681 =(const AliMUONSegmentationV01 & rhs)
683 // Dummy assignment operator