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 /////////////////////////////////////////////////////
19 // Segmentation and Response classes version 01 //
20 /////////////////////////////////////////////////////
26 #include <TGeometry.h>
29 #include <TObjArray.h>
31 #include "AliMUONSegmentationV01.h"
33 #include "AliMUONChamber.h"
39 //___________________________________________
40 ClassImp(AliMUONSegmentationV01)
42 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
43 : AliMUONSegmentationV0(segmentation)
45 // Protected copy constructor
47 AliFatal("Not implemented.");
50 AliMUONSegmentationV01::AliMUONSegmentationV01()
51 : AliMUONSegmentationV0()
53 // Default constructor
61 AliMUONSegmentationV01::AliMUONSegmentationV01(Int_t nsec)
62 : AliMUONSegmentationV0()
64 // Non default constructor
67 fRSec = new TArrayF(fNsec);
68 fNDiv = new TArrayI(fNsec);
69 fDpxD = new TArrayF(fNsec);
72 (*fRSec)[0]=(*fRSec)[1]=(*fRSec)[2]=(*fRSec)[3]=0;
73 (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
74 (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
75 fCorrA = new TObjArray(3);
83 AliMUONSegmentationV01::~AliMUONSegmentationV01()
86 if (fRSec) delete fRSec;
87 if (fNDiv) delete fNDiv;
88 if (fDpxD) delete fDpxD;
96 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
99 // Returns x-pad size for given sector isec
100 Float_t dpx = (*fDpxD)[isec];
104 Float_t AliMUONSegmentationV01::Dpy(Int_t /*isec*/) const
107 // Returns y-pad size for given sector isec
111 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
114 // Set the radii of the segmentation zones
115 for (Int_t i=0; i<4; i++) {
121 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
124 // Defines the pad size perp. to the anode wire (y) for different sectors.
125 // Pad sizes are defined as integral fractions ndiv of a basis pad size
128 for (Int_t i=0; i<4; i++) {
135 void AliMUONSegmentationV01::Init(Int_t chamber)
138 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
139 // These arrays help in converting from real to pad co-ordinates and
141 // This version approximates concentric segmentation zones
145 //printf("\n Initialise Segmentation V01\n");
148 fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
150 (*fDpxD)[fNsec-1]=fDpx;
152 for (Int_t i=fNsec-2; i>=0; i--){
153 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
157 // fill the arrays defining the pad segmentation boundaries
162 // loop over sections
163 for(isec=0; isec<fNsec; isec++) {
165 // loop over pads along the aode wires
166 for (Int_t iy=1; iy<=fNpy; iy++) {
168 Float_t x=iy*fDpy-fDpy/2;
169 if (x > (*fRSec)[isec]) {
173 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
175 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
176 if (isec < fNsec-1) {
177 if (TMath::Odd((Long_t)dnx)) dnx++;
179 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
180 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
181 } else if (isec == 1) {
182 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
183 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
184 add=4 - (fNpxS[isec][iy])%4;
185 if (add < 4) fNpxS[isec][iy]+=add;
186 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
187 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
189 dnx=Int_t(ry/(*fDpxD)[isec]);
191 fCx[isec][iy]=dnx*(*fDpxD)[isec];
197 // reference to chamber
198 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
199 fChamber=&(pMUON->Chamber(chamber));
200 fRmin=fChamber->RInner();
201 fRmax=fChamber->ROuter();
207 //______________________________________________________________________
208 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
210 // Returns sector number for given pad position
212 Int_t absix=TMath::Abs(ix);
213 Int_t absiy=TMath::Abs(iy);
215 for (Int_t i=0; i<fNsec; i++) {
216 if (absix<=fNpxS[i][absiy]){
224 //______________________________________________________________________
225 void AliMUONSegmentationV01::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
227 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
229 iy = (y-fOffsetY >0)?
230 Int_t((y-fOffsetY)/fDpy)+1
232 Int_t((y-fOffsetY)/fDpy)-1;
234 if (iy > fNpy) iy= fNpy;
235 if (iy < -fNpy) iy=-fNpy;
239 Float_t absx=TMath::Abs(x);
240 Int_t absiy=TMath::Abs(iy);
241 for (Int_t i=0; i < fNsec; i++) {
242 if (absx <= fCx[i][absiy]) {
248 ix= Int_t((absx-fCx[isec-1][absiy])/(*fDpxD)[isec])
249 +fNpxS[isec-1][absiy]+1;
250 } else if (isec == 0) {
251 ix= Int_t(absx/(*fDpxD)[isec])+1;
253 ix=fNpxS[fNsec-1][absiy]+1;
257 //________________________________________________________________
258 void AliMUONSegmentationV01::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
260 GetPadI(x, y, ix, iy);
262 //________________________________________________________________
264 void AliMUONSegmentationV01::
265 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
267 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
270 Float_t(iy*fDpy)-fDpy/2.+fOffsetY
272 Float_t(iy*fDpy)+fDpy/2.+fOffsetY;
276 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
278 Int_t absix=TMath::Abs(ix);
279 Int_t absiy=TMath::Abs(iy);
281 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*(*fDpxD)[isec];
282 x=(ix>0) ? x-(*fDpxD)[isec]/2 : -x+(*fDpxD)[isec]/2;
288 //________________________________________________________________
290 void AliMUONSegmentationV01::
291 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y, Float_t &z)
293 // Returns real coordinates (x,y,z) for given pad coordinates (ix,iy)
297 // To be properly interfaced with chamber geometry (AliMUONSt1GeometryBuilderV2) ???
299 scale[0] = TVector3( 1, 1, 1); // quadrant I
300 scale[1] = TVector3(-1, 1, -1); // quadrant II
301 scale[2] = TVector3(-1, -1, 1); // quadrant III
302 scale[3] = TVector3( 1, -1, -1); // quadrant IV
319 if (TMath::Abs(fZ) < 600) {
320 z = fZ + scale[iQuadrant].Z()*6.5/2.; // Station 1
326 void AliMUONSegmentationV01::
327 SetPad(Int_t ix, Int_t iy)
330 // Sets virtual pad coordinates, needed for evaluating pad response
331 // outside the tracking program
332 GetPadC(ix,iy,fX,fY);
333 fSector=Sector(ix,iy);
336 //______________________________________________________________________
337 void AliMUONSegmentationV01::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
339 // Initialises iteration over pads for charge distribution algorithm
342 // Find the wire position (center of charge distribution)
343 Float_t x0a=GetAnod(xhit);
348 // and take fNsigma*sigma around this center
349 Float_t x01=x0a - dx;
350 Float_t x02=x0a + dx;
351 Float_t y01=yhit - dy;
352 Float_t y02=yhit + dy;
354 // find the pads over which the charge distributes
356 GetPadI(x01,y01,fIxmin,fIymin);
357 GetPadI(x02,y02,fIxmax,fIymax);
364 // Set current pad to lower left corner
365 if (fIxmax < fIxmin) fIxmax=fIxmin;
366 if (fIymax < fIymin) fIymax=fIymin;
369 GetPadC(fIx,fIy,fX,fY);
373 fSector=Sector(fIx,fIy);
378 void AliMUONSegmentationV01::NextPad()
380 // Stepper for the iteration over pads
382 // Step to next pad in the integration region
384 // Step to next pad in integration region
388 // step from left to right
390 if (fX < fXmax && fX != 0) {
394 } else if (fIy != fIymax) {
397 // get y-position of next row (yc), xc not used here
398 GetPadC(fIx,fIy,xc,yc);
399 // get x-pad coordiante for first pad in row (fIx)
400 GetPadI(fXmin,yc,fIx,iyc);
405 GetPadC(fIx,fIy,fX,fY);
406 fSector=Sector(fIx,fIy);
408 (fSector ==-1 || fSector==0))
412 Int_t AliMUONSegmentationV01::MorePads()
415 // Stopping condition for the iterator over pads
417 // Are there more pads in the integration region
418 return (fIx != -1 || fIy != -1);
420 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
427 //______________________________________________________________________
428 void AliMUONSegmentationV01::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
430 FirstPad(xhit, yhit, dx, dy);
434 void AliMUONSegmentationV01::
435 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
437 // Returns integration limits for current pad
439 x1=fXhit-fX-Dpx(fSector)/2.;
441 y1=fYhit-fY-Dpy(fSector)/2.;
445 void AliMUONSegmentationV01::
446 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
448 // Returns list of next neighbours for given Pad (iX, iY)
450 const Float_t kEpsilon=fDpy/1000;
453 Int_t ixx, iyy, isec1;
455 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
460 if (Xlist[i]==0) Xlist[i]++;
465 if (Xlist[i]==0) Xlist[i]--;
469 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
470 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
473 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
476 // no sector boundary crossing
482 } else if (isec1 < isec0) {
483 // finer segmentation
493 // coarser segmenation
495 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
507 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
508 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
511 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
514 // no sector boundary crossing
522 } else if (isec1 < isec0) {
523 // finer segmentation
533 // coarser segmentation
535 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
547 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
549 // Returns test point on the pad plane.
550 // Used during determination of the segmoid correction of the COG-method
553 x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
555 x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
557 x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
561 void AliMUONSegmentationV01::Draw(const char* opt)
564 // Draws the segmentation zones
566 if (!strcmp(opt,"eventdisplay")) {
567 const int kColorMUON = kBlue;
569 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
570 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
571 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
572 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
574 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
575 char nameSense1[9], nameSense2[9];
578 sprintf(nameChamber,"C_MUON%d",fId+1);
579 sprintf(nameSense,"S_MUON%d",fId+1);
580 sprintf(nameSense1,"S1_MUON%d",fId+1);
581 sprintf(nameSense2,"S2_MUON%d",fId+1);
582 sprintf(nameFrame,"F_MUON%d",fId+1);
584 TNode* top=gAlice->GetGeometry()->GetNode("alice");
586 Float_t rmin = (*fRSec)[0]-3;
587 Float_t rmax = (*fRSec)[3]+3;
588 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
591 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
592 Float_t dx=(rmax-rmin)/2;
595 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
597 sprintf(nameNode,"MUON%d",100+fId+1);
598 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,fChamber->Z(),"");
599 node->SetLineColor(kColorMUON);
600 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
601 (pMUON->Nodes())->Add(node);
603 sprintf(nameNode,"MUON%d",200+fId+1);
604 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
605 node->SetLineColor(kColorMUON);
608 sprintf(nameNode,"MUON%d",300+fId+1);
609 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
610 nodeF->SetLineColor(kColorMUON);
612 sprintf(nameNode,"MUON%d",400+fId+1);
613 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
614 nodeF->SetLineColor(kColorMUON);
616 sprintf(nameNode,"MUON%d",500+fId+1);
617 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
618 nodeF->SetLineColor(kColorMUON);
620 sprintf(nameNode,"MUON%d",600+fId+1);
621 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
622 nodeF->SetLineColor(kColorMUON);
626 Float_t dx=0.95/fCx[3][1]/2;
627 Float_t dy=0.95/(Float_t(Npy()))/2;
632 for (Int_t iy=1; iy<Npy(); iy++) {
633 for (Int_t isec=0; isec<4; isec++) {
638 x0=fCx[isec-1][iy]*dx;
643 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
644 box->SetFillColor(isec+1);
647 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
648 box->SetFillColor(isec+1);
651 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
652 box->SetFillColor(isec+1);
655 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
656 box->SetFillColor(isec+1);
662 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
664 // Set the correction function
665 fCorrA->AddAt(func,isec);
668 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
670 // Get correction function
671 //PH return (TF1*) (*fCorrA)[isec];
672 return (TF1*) fCorrA->At(isec);
675 AliMUONSegmentationV01&
676 AliMUONSegmentationV01::operator =(const AliMUONSegmentationV01 & rhs)
678 // Protected assignement operator
680 if (this == &rhs) return *this;
682 AliFatal("Not implemented.");