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.1.2.1 2000/06/09 21:37:30 morsch
19 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
24 /////////////////////////////////////////////////////
25 // Segmentation and Response classes version 01 //
26 /////////////////////////////////////////////////////
30 #include <TObjArray.h>
33 #include "AliMUONSegmentationV01.h"
38 //___________________________________________
39 ClassImp(AliMUONSegmentationV01)
41 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
43 // Dummy copy constructor
45 AliMUONSegmentationV01::AliMUONSegmentationV01()
47 // Default constructor
52 fRSec[0]=fRSec[1]=fRSec[2]=fRSec[3]=0;
53 fNDiv[0]=fNDiv[1]=fNDiv[2]=fNDiv[3]=0;
54 fDpxD[0]=fDpxD[1]=fDpxD[2]=fDpxD[3]=0;
55 fCorr = new TObjArray(3);
61 Float_t AliMUONSegmentationV01::Dpx(Int_t isec)
64 // Returns x-pad size for given sector isec
68 Float_t AliMUONSegmentationV01::Dpy(Int_t isec)
71 // Returns y-pad size for given sector isec
75 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
78 // Set the radii of the segmentation zones
79 for (Int_t i=0; i<4; i++) {
81 printf("\n R %d %f \n",i,fRSec[i]);
87 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
90 // Defines the pad size perp. to the anode wire (y) for different sectors.
91 // Pad sizes are defined as integral fractions ndiv of a basis pad size
94 for (Int_t i=0; i<4; i++) {
96 printf("\n Ndiv %d %d \n",i,fNDiv[i]);
102 void AliMUONSegmentationV01::Init(AliMUONChamber* Chamber)
105 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
106 // These arrays help in converting from real to pad co-ordinates and
108 // This version approximates concentric segmentation zones
111 printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n");
112 fNpy=Int_t(fRSec[fNsec-1]/fDpy)+1;
116 for (Int_t i=fNsec-2; i>=0; i--){
117 fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i];
118 printf("\n test ---dx %d %f \n",i,fDpxD[i]);
122 // fill the arrays defining the pad segmentation boundaries
127 // loop over sections
128 for(isec=0; isec<fNsec; isec++) {
130 // loop over pads along the aode wires
131 for (Int_t iy=1; iy<=fNpy; iy++) {
133 Float_t x=iy*fDpy-fDpy/2;
134 if (x > fRSec[isec]) {
138 ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x);
140 dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
141 if (isec < fNsec-1) {
142 if (TMath::Odd((Long_t)dnx)) dnx++;
144 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
145 fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
146 } else if (isec == 1) {
147 dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]);
148 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
149 add=4 - (fNpxS[isec][iy])%4;
150 if (add < 4) fNpxS[isec][iy]+=add;
151 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
152 fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec];
154 dnx=Int_t(ry/fDpxD[isec]);
156 fCx[isec][iy]=dnx*fDpxD[isec];
163 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
165 // Returns sector number for given pad position
167 Int_t absix=TMath::Abs(ix);
168 Int_t absiy=TMath::Abs(iy);
170 for (Int_t i=0; i<fNsec; i++) {
171 if (absix<=fNpxS[i][absiy]){
179 void AliMUONSegmentationV01::
180 GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
182 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
184 iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1;
185 if (iy > fNpy) iy= fNpy;
186 if (iy < -fNpy) iy=-fNpy;
190 Float_t absx=TMath::Abs(x);
191 Int_t absiy=TMath::Abs(iy);
192 for (Int_t i=0; i < fNsec; i++) {
193 if (absx <= fCx[i][absiy]) {
199 ix= Int_t((absx-fCx[isec-1][absiy])/fDpxD[isec])
200 +fNpxS[isec-1][absiy]+1;
201 } else if (isec == 0) {
202 ix= Int_t(absx/fDpxD[isec])+1;
204 ix=fNpxS[fNsec-1][absiy]+1;
209 void AliMUONSegmentationV01::
210 GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
212 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
214 y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
217 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
219 Int_t absix=TMath::Abs(ix);
220 Int_t absiy=TMath::Abs(iy);
222 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*fDpxD[isec];
223 x=(ix>0) ? x-fDpxD[isec]/2 : -x+fDpxD[isec]/2;
229 void AliMUONSegmentationV01::
230 SetPad(Int_t ix, Int_t iy)
233 // Sets virtual pad coordinates, needed for evaluating pad response
234 // outside the tracking program
235 GetPadCxy(ix,iy,fx,fy);
236 fSector=Sector(ix,iy);
240 void AliMUONSegmentationV01::
241 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
243 // Initialises iteration over pads for charge distribution algorithm
246 // Find the wire position (center of charge distribution)
247 Float_t x0a=GetAnod(xhit);
252 // and take fNsigma*sigma around this center
253 Float_t x01=x0a - dx;
254 Float_t x02=x0a + dx;
255 Float_t y01=yhit - dy;
256 Float_t y02=yhit + dy;
258 // find the pads over which the charge distributes
259 GetPadIxy(x01,y01,fixmin,fiymin);
260 GetPadIxy(x02,y02,fixmax,fiymax);
267 // Set current pad to lower left corner
268 if (fixmax < fixmin) fixmax=fixmin;
269 if (fiymax < fiymin) fiymax=fiymin;
272 GetPadCxy(fix,fiy,fx,fy);
276 void AliMUONSegmentationV01::NextPad()
278 // Stepper for the iteration over pads
280 // Step to next pad in the integration region
282 // Step to next pad in integration region
286 // step from left to right
287 if (fx < fxmax && fx != 0) {
291 } else if (fiy != fiymax) {
294 // get y-position of next row (yc), xc not used here
295 GetPadCxy(fix,fiy,xc,yc);
296 // get x-pad coordiante for first pad in row (fix)
297 GetPadIxy(fxmin,yc,fix,iyc);
299 printf("\n Error: Stepping outside integration region\n ");
301 GetPadCxy(fix,fiy,fx,fy);
302 fSector=Sector(fix,fiy);
304 (fSector ==-1 || fSector==0))
308 Int_t AliMUONSegmentationV01::MorePads()
309 // Stopping condition for the iterator over pads
311 // Are there more pads in the integration region
313 if ((fx >= fxmax && fiy >= fiymax) || fy==0) {
320 void AliMUONSegmentationV01::
321 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
323 // Returns integration limits for current pad
325 x1=fxhit-fx-Dpx(fSector)/2.;
327 y1=fyhit-fy-Dpy(fSector)/2.;
331 void AliMUONSegmentationV01::
332 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
334 // Returns list of next neighbours for given Pad (iX, iY)
336 const Float_t kEpsilon=fDpy/1000;
339 Int_t ixx, iyy, isec1;
341 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
346 if (Xlist[i]==0) Xlist[i]++;
351 if (Xlist[i]==0) Xlist[i]--;
355 AliMUONSegmentationV01::GetPadCxy(iX,iY,x,y);
356 AliMUONSegmentationV01::GetPadIxy(x+kEpsilon,y+fDpy,ixx,iyy);
359 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
362 // no sector boundary crossing
368 } else if (isec1 < isec0) {
369 // finer segmentation
379 // coarser segmenation
381 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
393 AliMUONSegmentationV01::GetPadCxy(iX,iY,x,y);
394 AliMUONSegmentationV01::GetPadIxy(x+kEpsilon,y-fDpy,ixx,iyy);
397 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
400 // no sector boundary crossing
408 } else if (isec1 < isec0) {
409 // finer segmentation
419 // coarser segmentation
421 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
433 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
435 // Returns test point on the pad plane.
436 // Used during determination of the segmoid correction of the COG-method
439 x[0]=(fRSec[0]+fRSec[1])/2/TMath::Sqrt(2.);
441 x[1]=(fRSec[1]+fRSec[2])/2/TMath::Sqrt(2.);
443 x[2]=(fRSec[2]+fRSec[3])/2/TMath::Sqrt(2.);
447 void AliMUONSegmentationV01::Draw()
449 // Draws the segmentation zones
453 Float_t dx=0.95/fCx[3][1]/2;
454 Float_t dy=0.95/(Float_t(Npy()))/2;
459 for (Int_t iy=1; iy<Npy(); iy++)
461 for (Int_t isec=0; isec<4; isec++) {
466 x0=fCx[isec-1][iy]*dx;
471 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
472 box->SetFillColor(isec+1);
475 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
476 box->SetFillColor(isec+1);
479 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
480 box->SetFillColor(isec+1);
483 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
484 box->SetFillColor(isec+1);
489 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
494 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec)
496 return (TF1*) (*fCorr)[isec];
499 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
500 =(const AliMUONSegmentationV01 & rhs)
502 // Dummy assignment operator