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.9 2000/10/18 08:41:32 morsch
19 Make NextPad() and MorePads() to iterate until the end.
21 Revision 1.8 2000/10/03 21:48:07 morsch
22 Adopt to const declaration of some of the methods in AliSegmentation.
24 Revision 1.7 2000/10/02 21:28:09 fca
25 Removal of useless dependecies via forward declarations
27 Revision 1.6 2000/10/02 16:58:29 egangler
28 Cleaning of the code :
31 -> some useless includes removed or replaced by "class" statement
33 Revision 1.5 2000/07/13 16:19:44 fca
34 Mainly coding conventions + some small bug fixes
36 Revision 1.4 2000/07/03 11:54:57 morsch
37 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
38 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
40 Revision 1.3 2000/06/29 12:34:09 morsch
41 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
42 it usable with any other geometry class. The link to the object to which it belongs is
43 established via an index. This assumes that there exists a global geometry manager
44 from which the pointer to the parent object can be obtained (in our case gAlice).
46 Revision 1.2 2000/06/15 07:58:48 morsch
47 Code from MUON-dev joined
49 Revision 1.1.2.1 2000/06/09 21:37:30 morsch
50 AliMUONSegmentationV01 code from AliMUONSegResV01.cxx
55 /////////////////////////////////////////////////////
56 // Segmentation and Response classes version 01 //
57 /////////////////////////////////////////////////////
61 #include <TObjArray.h>
64 #include "AliMUONSegmentationV01.h"
66 #include "AliMUONChamber.h"
71 //___________________________________________
72 ClassImp(AliMUONSegmentationV01)
74 AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation)
76 // Dummy copy constructor
78 AliMUONSegmentationV01::AliMUONSegmentationV01()
80 // Default constructor
82 fRSec = new TArrayF(fNsec);
83 fNDiv = new TArrayI(fNsec);
84 fDpxD = new TArrayF(fNsec);
85 (*fRSec)[0]=(*fRSec)[1]=(*fRSec)[2]=(*fRSec)[3]=0;
86 (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
87 (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
88 fCorr = new TObjArray(3);
94 Float_t AliMUONSegmentationV01::Dpx(Int_t isec) const
97 // Returns x-pad size for given sector isec
98 Float_t dpx = (*fDpxD)[isec];
102 Float_t AliMUONSegmentationV01::Dpy(Int_t isec) const
105 // Returns y-pad size for given sector isec
109 void AliMUONSegmentationV01::SetSegRadii(Float_t r[4])
112 // Set the radii of the segmentation zones
113 for (Int_t i=0; i<4; i++) {
119 void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4])
122 // Defines the pad size perp. to the anode wire (y) for different sectors.
123 // Pad sizes are defined as integral fractions ndiv of a basis pad size
126 for (Int_t i=0; i<4; i++) {
133 void AliMUONSegmentationV01::Init(Int_t chamber)
136 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
137 // These arrays help in converting from real to pad co-ordinates and
139 // This version approximates concentric segmentation zones
142 printf("\n Initialise Segmentation V01\n");
143 fNpy=Int_t((*fRSec)[fNsec-1]/fDpy)+1;
145 (*fDpxD)[fNsec-1]=fDpx;
147 for (Int_t i=fNsec-2; i>=0; i--){
148 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
152 // fill the arrays defining the pad segmentation boundaries
157 // loop over sections
158 for(isec=0; isec<fNsec; isec++) {
160 // loop over pads along the aode wires
161 for (Int_t iy=1; iy<=fNpy; iy++) {
163 Float_t x=iy*fDpy-fDpy/2;
164 if (x > (*fRSec)[isec]) {
168 ry=TMath::Sqrt((*fRSec)[isec]*(*fRSec)[isec]-x*x);
170 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
171 if (isec < fNsec-1) {
172 if (TMath::Odd((Long_t)dnx)) dnx++;
174 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
175 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
176 } else if (isec == 1) {
177 dnx= Int_t((ry-fCx[isec-1][iy])/(*fDpxD)[isec]);
178 fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx;
179 add=4 - (fNpxS[isec][iy])%4;
180 if (add < 4) fNpxS[isec][iy]+=add;
181 dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy];
182 fCx[isec][iy]=fCx[isec-1][iy]+dnx*(*fDpxD)[isec];
184 dnx=Int_t(ry/(*fDpxD)[isec]);
186 fCx[isec][iy]=dnx*(*fDpxD)[isec];
191 // reference to chamber
192 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
193 fChamber=&(pMUON->Chamber(chamber));
197 Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy)
199 // Returns sector number for given pad position
201 Int_t absix=TMath::Abs(ix);
202 Int_t absiy=TMath::Abs(iy);
204 for (Int_t i=0; i<fNsec; i++) {
205 if (absix<=fNpxS[i][absiy]){
213 void AliMUONSegmentationV01::
214 GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
216 // Returns pad coordinates (ix,iy) for given real coordinates (x,y)
218 iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1;
219 if (iy > fNpy) iy= fNpy;
220 if (iy < -fNpy) iy=-fNpy;
224 Float_t absx=TMath::Abs(x);
225 Int_t absiy=TMath::Abs(iy);
226 for (Int_t i=0; i < fNsec; i++) {
227 if (absx <= fCx[i][absiy]) {
233 ix= Int_t((absx-fCx[isec-1][absiy])/(*fDpxD)[isec])
234 +fNpxS[isec-1][absiy]+1;
235 } else if (isec == 0) {
236 ix= Int_t(absx/(*fDpxD)[isec])+1;
238 ix=fNpxS[fNsec-1][absiy]+1;
243 void AliMUONSegmentationV01::
244 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
246 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
248 y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.;
251 Int_t isec=AliMUONSegmentationV01::Sector(ix,iy);
253 Int_t absix=TMath::Abs(ix);
254 Int_t absiy=TMath::Abs(iy);
256 x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*(*fDpxD)[isec];
257 x=(ix>0) ? x-(*fDpxD)[isec]/2 : -x+(*fDpxD)[isec]/2;
263 void AliMUONSegmentationV01::
264 SetPad(Int_t ix, Int_t iy)
267 // Sets virtual pad coordinates, needed for evaluating pad response
268 // outside the tracking program
269 GetPadC(ix,iy,fX,fY);
270 fSector=Sector(ix,iy);
274 void AliMUONSegmentationV01::
275 FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
277 // Initialises iteration over pads for charge distribution algorithm
280 // Find the wire position (center of charge distribution)
281 Float_t x0a=GetAnod(xhit);
286 // and take fNsigma*sigma around this center
287 Float_t x01=x0a - dx;
288 Float_t x02=x0a + dx;
289 Float_t y01=yhit - dy;
290 Float_t y02=yhit + dy;
292 // find the pads over which the charge distributes
294 GetPadI(x01,y01,fIxmin,fIymin);
295 GetPadI(x02,y02,fIxmax,fIymax);
302 // Set current pad to lower left corner
303 if (fIxmax < fIxmin) fIxmax=fIxmin;
304 if (fIymax < fIymin) fIymax=fIymin;
307 GetPadC(fIx,fIy,fX,fY);
311 void AliMUONSegmentationV01::NextPad()
313 // Stepper for the iteration over pads
315 // Step to next pad in the integration region
317 // Step to next pad in integration region
321 // step from left to right
323 if (fX < fXmax && fX != 0) {
327 } else if (fIy != fIymax) {
330 // get y-position of next row (yc), xc not used here
331 GetPadC(fIx,fIy,xc,yc);
332 // get x-pad coordiante for first pad in row (fIx)
333 GetPadI(fXmin,yc,fIx,iyc);
338 GetPadC(fIx,fIy,fX,fY);
339 fSector=Sector(fIx,fIy);
341 (fSector ==-1 || fSector==0))
345 Int_t AliMUONSegmentationV01::MorePads()
346 // Stopping condition for the iterator over pads
348 // Are there more pads in the integration region
350 return (fIx != -1 || fIy != -1);
352 if ((fX >= fXmax && fIy >= fIymax) || fY==0) {
360 void AliMUONSegmentationV01::
361 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
363 // Returns integration limits for current pad
365 x1=fXhit-fX-Dpx(fSector)/2.;
367 y1=fYhit-fY-Dpy(fSector)/2.;
371 void AliMUONSegmentationV01::
372 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
374 // Returns list of next neighbours for given Pad (iX, iY)
376 const Float_t kEpsilon=fDpy/1000;
379 Int_t ixx, iyy, isec1;
381 Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY);
386 if (Xlist[i]==0) Xlist[i]++;
391 if (Xlist[i]==0) Xlist[i]--;
395 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
396 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y+fDpy,ixx,iyy);
399 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
402 // no sector boundary crossing
408 } else if (isec1 < isec0) {
409 // finer segmentation
419 // coarser segmenation
421 if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) {
433 AliMUONSegmentationV01::GetPadC(iX,iY,x,y);
434 AliMUONSegmentationV01::GetPadI(x+kEpsilon,y-fDpy,ixx,iyy);
437 isec1=AliMUONSegmentationV01::Sector(ixx,iyy);
440 // no sector boundary crossing
448 } else if (isec1 < isec0) {
449 // finer segmentation
459 // coarser segmentation
461 if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) {
473 void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) const
475 // Returns test point on the pad plane.
476 // Used during determination of the segmoid correction of the COG-method
479 x[0]=((*fRSec)[0]+(*fRSec)[1])/2/TMath::Sqrt(2.);
481 x[1]=((*fRSec)[1]+(*fRSec)[2])/2/TMath::Sqrt(2.);
483 x[2]=((*fRSec)[2]+(*fRSec)[3])/2/TMath::Sqrt(2.);
487 void AliMUONSegmentationV01::Draw(const char *) const
489 // Draws the segmentation zones
493 Float_t dx=0.95/fCx[3][1]/2;
494 Float_t dy=0.95/(Float_t(Npy()))/2;
499 for (Int_t iy=1; iy<Npy(); iy++)
501 for (Int_t isec=0; isec<4; isec++) {
506 x0=fCx[isec-1][iy]*dx;
511 box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
512 box->SetFillColor(isec+1);
515 box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc);
516 box->SetFillColor(isec+1);
519 box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc);
520 box->SetFillColor(isec+1);
523 box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc);
524 box->SetFillColor(isec+1);
529 void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func)
534 TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) const
536 return (TF1*) (*fCorr)[isec];
539 AliMUONSegmentationV01& AliMUONSegmentationV01::operator
540 =(const AliMUONSegmentationV01 & rhs)
542 // Dummy assignment operator