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.21 2001/08/30 09:52:12 hristov
19 The operator[] is replaced by At() or AddAt() in case of TObjArray.
21 Revision 1.20 2001/07/20 10:03:14 morsch
22 Changes needed to work with Root 3.01 (substitute lhs [] operator). (Jiri Chudoba)
24 Revision 1.19 2001/05/16 14:57:17 alibrary
25 New files for folders and Stack
27 Revision 1.18 2001/04/11 12:33:56 morsch
28 Bug in GetPadC in case of staggered planes corrected. (Thanks to J.P. Cussonneau)
30 Revision 1.17 2001/01/30 12:17:04 morsch
31 Remove obolete print-statement.
33 Revision 1.16 2001/01/30 09:23:14 hristov
34 Streamers removed (R.Brun)
36 Revision 1.15 2001/01/26 21:25:48 morsch
37 Empty default constructors and.
39 Revision 1.14 2000/12/21 22:12:41 morsch
40 Clean-up of coding rule violations,
42 Revision 1.13 2000/12/07 10:41:51 hristov
43 fCorr replaced by fCorrA
45 Revision 1.12 2000/12/06 11:55:41 morsch
46 Introduce SetOffsetY(Float_t off) method as simplified simulation of pad staggering.
47 fOffset is the staggering offset in y.
49 Revision 1.11 2000/11/06 09:20:43 morsch
50 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
51 Draw() method. This avoids code and parameter replication.
53 Revision 1.10 2000/10/18 11:42:06 morsch
54 - AliMUONRawCluster contains z-position.
55 - Some clean-up of useless print statements during initialisations.
57 Revision 1.9 2000/10/18 08:41:32 morsch
58 Make NextPad() and MorePads() to iterate until the end.
60 Revision 1.8 2000/10/03 21:48:07 morsch
61 Adopt to const declaration of some of the methods in AliSegmentation.
63 Revision 1.7 2000/10/02 21:28:09 fca
64 Removal of useless dependecies via forward declarations
66 Revision 1.6 2000/10/02 16:58:29 egangler
67 Cleaning of the code :
70 -> some useless includes removed or replaced by "class" statement
72 Revision 1.5 2000/07/13 16:19:44 fca
73 Mainly coding conventions + some small bug fixes
75 Revision 1.4 2000/07/03 11:54:57 morsch
76 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
77 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
79 Revision 1.3 2000/06/29 12:34:09 morsch
80 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
81 it usable with any other geometry class. The link to the object to which it belongs is
82 established via an index. This assumes that there exists a global geometry manager
83 from which the pointer to the parent object can be obtained (in our case gAlice).
85 Revision 1.2 2000/06/15 07:58:48 morsch
86 Code from MUON-dev joined
88 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
89 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
94 /////////////////////////////////////////////////////
95 // Segmentation and Response classes version 01 //
96 /////////////////////////////////////////////////////
102 #include <TGeometry.h>
104 #include <TObjArray.h>
105 #include <Riostream.h>
107 #include "AliMUONSegmentationV01.h"
109 #include "AliMUONChamber.h"
114 //___________________________________________
115 ClassImp(AliMUONSegmentationV01)
117 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
119 // Dummy copy constructor
122 AliMUONSegmentationV01::AliMUONSegmentationV01()
124 // Default constructor
131 AliMUONSegmentationV01::AliMUONSegmentationV01(Int_t nsec)
133 // Non default constructor
136 fRSec = new TArrayF(fNsec);
137 fNDiv = new TArrayI(fNsec);
138 fDpxD = new TArrayF(fNsec);
141 (*fRSec)[0]=(*fRSec)[1]=(*fRSec)[2]=(*fRSec)[3]=0;
142 (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
143 (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
144 fCorrA = new TObjArray(3);
151 AliMUONSegmentationV01::~AliMUONSegmentationV01()
154 if (fRSec) delete fRSec;
155 if (fNDiv) delete fNDiv;
156 if (fDpxD) delete fDpxD;
164 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
167 // Returns x-pad size for given sector isec
168 Float_t dpx = (*fDpxD)[isec];
172 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
175 // Returns y-pad size for given sector isec
179 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
182 // Set the radii of the segmentation zones
183 for (Int_t i=0; i<4; i++) {
189 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
192 // Defines the pad size perp. to the anode wire (y) for different sectors.
193 // Pad sizes are defined as integral fractions ndiv of a basis pad size
196 for (Int_t i=0; i<4; i++) {
203 void AliMUONSegmentationV01::Init(Int_t chamber)
206 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
207 // These arrays help in converting from real to pad co-ordinates and
209 // This version approximates concentric segmentation zones
212 //printf("\n Initialise Segmentation V01\n");
215 fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
217 (*fDpxD)[fNsec-1]=fDpx;
219 for (Int_t i=fNsec-2; i>=0; i--){
220 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
224 // fill the arrays defining the pad segmentation boundaries
229 // loop over sections
230 for(isec=0; isec<fNsec; isec++) {
232 // loop over pads along the aode wires
233 for (Int_t iy=1; iy<=fNpy; iy++) {
235 Float_t x=iy*fDpy-fDpy/2;
236 if (x > (*fRSec)[isec]) {
240 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
242 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
243 if (isec < fNsec-1) {
244 if (TMath::Odd((Long_t)dnx)) dnx++;
246 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
247 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
248 } else if (isec == 1) {
249 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
250 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
251 add=4 - (fNpxS[isec][iy])%4;
252 if (add < 4) fNpxS[isec][iy]+=add;
253 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
254 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
256 dnx=Int_t(ry/(*fDpxD)[isec]);
258 fCx[isec][iy]=dnx*(*fDpxD)[isec];
263 // reference to chamber
264 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
265 fChamber=&(pMUON->Chamber(chamber));
270 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
272 // Returns sector number for given pad position
274 Int_t absix=TMath::Abs(ix);
275 Int_t absiy=TMath::Abs(iy);
277 for (Int_t i=0; i<fNsec; i++) {
278 if (absix<=fNpxS[i][absiy]){
286 void AliMUONSegmentationV01::
287 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
289 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
291 iy = (y-fOffsetY >0)?
292 Int_t((y-fOffsetY)/fDpy)+1
294 Int_t((y-fOffsetY)/fDpy)-1;
296 if (iy > fNpy) iy= fNpy;
297 if (iy < -fNpy) iy=-fNpy;
301 Float_t absx=TMath::Abs(x);
302 Int_t absiy=TMath::Abs(iy);
303 for (Int_t i=0; i < fNsec; i++) {
304 if (absx <= fCx[i][absiy]) {
310 ix= Int_t((absx-fCx[isec-1][absiy])/(*fDpxD)[isec])
311 +fNpxS[isec-1][absiy]+1;
312 } else if (isec == 0) {
313 ix= Int_t(absx/(*fDpxD)[isec])+1;
315 ix=fNpxS[fNsec-1][absiy]+1;
320 void AliMUONSegmentationV01::
321 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
323 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
326 Float_t(iy*fDpy)-fDpy/2.+fOffsetY
328 Float_t(iy*fDpy)+fDpy/2.+fOffsetY;
332 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
334 Int_t absix=TMath::Abs(ix);
335 Int_t absiy=TMath::Abs(iy);
337 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*(*fDpxD)[isec];
338 x=(ix>0) ? x-(*fDpxD)[isec]/2 : -x+(*fDpxD)[isec]/2;
344 void AliMUONSegmentationV01::
345 SetPad(Int_t ix, Int_t iy)
348 // Sets virtual pad coordinates, needed for evaluating pad response
349 // outside the tracking program
350 GetPadC(ix,iy,fX,fY);
351 fSector=Sector(ix,iy);
355 void AliMUONSegmentationV01::
356 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
358 // Initialises iteration over pads for charge distribution algorithm
361 // Find the wire position (center of charge distribution)
362 Float_t x0a=GetAnod(xhit);
367 // and take fNsigma*sigma around this center
368 Float_t x01=x0a - dx;
369 Float_t x02=x0a + dx;
370 Float_t y01=yhit - dy;
371 Float_t y02=yhit + dy;
373 // find the pads over which the charge distributes
375 GetPadI(x01,y01,fIxmin,fIymin);
376 GetPadI(x02,y02,fIxmax,fIymax);
383 // Set current pad to lower left corner
384 if (fIxmax < fIxmin) fIxmax=fIxmin;
385 if (fIymax < fIymin) fIymax=fIymin;
388 GetPadC(fIx,fIy,fX,fY);
392 void AliMUONSegmentationV01::NextPad()
394 // Stepper for the iteration over pads
396 // Step to next pad in the integration region
398 // Step to next pad in integration region
402 // step from left to right
404 if (fX < fXmax && fX != 0) {
408 } else if (fIy != fIymax) {
411 // get y-position of next row (yc), xc not used here
412 GetPadC(fIx,fIy,xc,yc);
413 // get x-pad coordiante for first pad in row (fIx)
414 GetPadI(fXmin,yc,fIx,iyc);
419 GetPadC(fIx,fIy,fX,fY);
420 fSector=Sector(fIx,fIy);
422 (fSector ==-1 || fSector==0))
426 Int_t AliMUONSegmentationV01::MorePads()
429 // Stopping condition for the iterator over pads
431 // Are there more pads in the integration region
432 return (fIx != -1 || fIy != -1);
434 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
442 void AliMUONSegmentationV01::
443 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
445 // Returns integration limits for current pad
447 x1=fXhit-fX-Dpx(fSector)/2.;
449 y1=fYhit-fY-Dpy(fSector)/2.;
453 void AliMUONSegmentationV01::
454 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
456 // Returns list of next neighbours for given Pad (iX, iY)
458 const Float_t kEpsilon=fDpy/1000;
461 Int_t ixx, iyy, isec1;
463 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
468 if (Xlist[i]==0) Xlist[i]++;
473 if (Xlist[i]==0) Xlist[i]--;
477 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
478 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
481 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
484 // no sector boundary crossing
490 } else if (isec1 < isec0) {
491 // finer segmentation
501 // coarser segmenation
503 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
515 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
516 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
519 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
522 // no sector boundary crossing
530 } else if (isec1 < isec0) {
531 // finer segmentation
541 // coarser segmentation
543 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
555 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
557 // Returns test point on the pad plane.
558 // Used during determination of the segmoid correction of the COG-method
561 x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
563 x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
565 x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
569 void AliMUONSegmentationV01::Draw(const char* opt) const
572 // Draws the segmentation zones
574 if (!strcmp(opt,"eventdisplay")) {
575 const int kColorMUON = kBlue;
577 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
578 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
579 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
580 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
582 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
583 char nameSense1[9], nameSense2[9];
586 sprintf(nameChamber,"C_MUON%d",fId+1);
587 sprintf(nameSense,"S_MUON%d",fId+1);
588 sprintf(nameSense1,"S1_MUON%d",fId+1);
589 sprintf(nameSense2,"S2_MUON%d",fId+1);
590 sprintf(nameFrame,"F_MUON%d",fId+1);
592 TNode* top=gAlice->GetGeometry()->GetNode("alice");
594 Float_t rmin = (*fRSec)[0]-3;
595 Float_t rmax = (*fRSec)[3]+3;
596 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
599 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
600 Float_t dx=(rmax-rmin)/2;
603 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
605 sprintf(nameNode,"MUON%d",100+fId+1);
606 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,fChamber->Z(),"");
607 node->SetLineColor(kColorMUON);
608 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
609 (pMUON->Nodes())->Add(node);
611 sprintf(nameNode,"MUON%d",200+fId+1);
612 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
613 node->SetLineColor(kColorMUON);
616 sprintf(nameNode,"MUON%d",300+fId+1);
617 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
618 nodeF->SetLineColor(kColorMUON);
620 sprintf(nameNode,"MUON%d",400+fId+1);
621 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
622 nodeF->SetLineColor(kColorMUON);
624 sprintf(nameNode,"MUON%d",500+fId+1);
625 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
626 nodeF->SetLineColor(kColorMUON);
628 sprintf(nameNode,"MUON%d",600+fId+1);
629 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
630 nodeF->SetLineColor(kColorMUON);
634 Float_t dx=0.95/fCx[3][1]/2;
635 Float_t dy=0.95/(Float_t(Npy()))/2;
640 for (Int_t iy=1; iy<Npy(); iy++) {
641 for (Int_t isec=0; isec<4; isec++) {
646 x0=fCx[isec-1][iy]*dx;
651 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
652 box->SetFillColor(isec+1);
655 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
656 box->SetFillColor(isec+1);
659 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
660 box->SetFillColor(isec+1);
663 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
664 box->SetFillColor(isec+1);
670 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
672 // Set the correction function
673 fCorrA->AddAt(func,isec);
676 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
678 // Get correction function
679 //PH return (TF1*) (*fCorrA)[isec];
680 return (TF1*) fCorrA->At(isec);
683 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
684 =(const AliMUONSegmentationV01 & rhs)
686 // Dummy assignment operator