]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONSt345SlatSegmentation.cxx
New segmentation with switch between old and new (Ch. Finck)
[u/mrichter/AliRoot.git] / MUON / AliMUONSt345SlatSegmentation.cxx
CommitLineData
cc4dcfb0 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
18//*********************************************************
19// Segmentation classes for slat modules
20// This class works with local coordinates
21// of the slats via the class AliMUONGeometrySegmentation
22// This class contains the size of the slats and the
23// and the differents PCB densities.
24// (from old AliMUONSegmentationSlatModule)
25// Gines, Subatech, Nov04
26//*********************************************************
27
28#include <TArrayI.h>
29#include <TArrayF.h>
30#include "AliMUONSt345SlatSegmentation.h"
31#include "AliLog.h"
32
cc4dcfb0 33ClassImp(AliMUONSt345SlatSegmentation)
34
35
a713db22 36AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation()
37 : AliMUONVGeometryDESegmentation(),
38 fBending(0),
39 fId(0),
40 fDpx(0),
41 fDpy(0),
42 fNpx(999999),
43 fNpy(999999),
44 fWireD(0.0),
45 fXhit(0.),
46 fYhit(0.),
47 fIx(0),
48 fIy(0),
49 fX(0.),
50 fY(0.),
51 fIxmin(0),
52 fIxmax(0),
53 fIymin(0),
54 fIymax(0)
55{
56 // default constructor
57
58}
59
60//___________________________________________
f48459ab 61AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(Bool_t bending)
e0a49962 62 : AliMUONVGeometryDESegmentation(),
f48459ab 63 fBending(bending),
64 fId(0),
65 fDpx(0),
66 fDpy(0),
67 fNpx(999999),
68 fNpy(999999),
69 fWireD(0.25),
70 fXhit(0.),
71 fYhit(0.),
72 fIx(0),
73 fIy(0),
74 fX(0.),
75 fY(0.),
76 fIxmin(0),
77 fIxmax(0),
78 fIymin(0),
79 fIymax(0)
cc4dcfb0 80{
f48459ab 81 // Non default constructor
cc4dcfb0 82 fNsec = 4; // 4 sector densities at most per slat
83 fNDiv = new TArrayI(fNsec);
84 fDpxD = new TArrayF(fNsec);
f48459ab 85 fDpyD = new TArrayF(fNsec);
cc4dcfb0 86 (*fNDiv)[0]=(*fNDiv)[1]=(*fNDiv)[2]=(*fNDiv)[3]=0;
87 (*fDpxD)[0]=(*fDpxD)[1]=(*fDpxD)[2]=(*fDpxD)[3]=0;
f48459ab 88 (*fDpyD)[0]=(*fDpyD)[1]=(*fDpyD)[2]=(*fDpyD)[3]=0;
cc4dcfb0 89}
90//----------------------------------------------------------------------
e0a49962 91AliMUONSt345SlatSegmentation::AliMUONSt345SlatSegmentation(const AliMUONSt345SlatSegmentation& rhs) : AliMUONVGeometryDESegmentation(rhs)
cc4dcfb0 92{
93 AliFatal("Not implemented.");
94}
95//----------------------------------------------------------------------
96AliMUONSt345SlatSegmentation::~AliMUONSt345SlatSegmentation()
97{
f48459ab 98 // Destructor
99 if (fNDiv) delete fNDiv;
100 if (fDpxD) delete fDpxD;
101 if (fDpyD) delete fDpyD;
cc4dcfb0 102}
103//----------------------------------------------------------------------
104AliMUONSt345SlatSegmentation& AliMUONSt345SlatSegmentation::operator=(const AliMUONSt345SlatSegmentation& rhs)
105{
f48459ab 106 // Protected assignement operator
cc4dcfb0 107 if (this == &rhs) return *this;
108 AliFatal("Not implemented.");
109 return *this;
110}
111
112
113//------------------------------------------------------------------------
114Float_t AliMUONSt345SlatSegmentation::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t * /*dummy*/)
115{
f48459ab 116 // Returns the square of the distance between 1 pad
117 // labelled by its Channel numbers and a coordinate
cc4dcfb0 118 Float_t x,y;
119 GetPadC(iX,iY,x,y);
120 return (x-X)*(x-X) + (y-Y)*(y-Y);
121}
122//____________________________________________________________________________
123Float_t AliMUONSt345SlatSegmentation::Dpx(Int_t isec) const
124{
f48459ab 125 // Return x-strip width
126 return (*fDpxD)[isec];
cc4dcfb0 127}
128
129//____________________________________________________________________________
f48459ab 130Float_t AliMUONSt345SlatSegmentation::Dpy(Int_t isec) const
cc4dcfb0 131{
132 // Return y-strip width
f48459ab 133 return (*fDpyD)[isec];
cc4dcfb0 134}
135//_____________________________________________________________________________
136Float_t AliMUONSt345SlatSegmentation::GetAnod(Float_t xhit) const
137{
f48459ab 138 // Returns for a hit position xhit the position of the nearest anode wire
139 Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5;
140 return fWireD*wire;
cc4dcfb0 141}
cc4dcfb0 142
cc4dcfb0 143
f48459ab 144
cc4dcfb0 145//--------------------------------------------------------------------------------
146void AliMUONSt345SlatSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y)
147{
148 if (ix<1 || ix>Npx() || iy<1 || iy>Npy() ){
149 AliWarning(Form("ix or iy out of boundaries: Npx=%d and Npy=%d",Npx(),Npy()));
150 x=-99999.; y=-99999.;
151 }
152 else {
153 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
cc4dcfb0 154 // Find sector isec
155 Int_t isec = Sector(ix,iy);
156 if (isec == -1) printf("\n PadC %d %d %d %d \n ", isec, fId, ix, iy);
f48459ab 157 if (iy > fNpyS[isec]) {
158 x=-99999.; y=-99999.;
159 return;
160 }
cc4dcfb0 161 if (isec>0) {
162 x = fCx[isec-1]+(ix-fNpxS[isec-1])*(*fDpxD)[isec];
163 x = x-(*fDpxD)[isec]/2;
f48459ab 164 y = Float_t(iy*(*fDpyD)[isec])-(*fDpyD)[isec]/2.- fCy; // !!!
cc4dcfb0 165 } else {
166 x=y=0;
167 }
168 }
169}
f48459ab 170
171
172//_____________________________________________________________________________
173void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
174{
175// Returns pad coordinates (ix,iy) for given real coordinates (x,y)
176
177 // Find sector isec
178 Int_t isec=-1;
179 for (Int_t i=fNsec-1; i > 0; i--) {
180 if (x >= fCx[i-1]) {
181 isec=i;
182 if (fCx[isec] == fCx[isec-1] && isec > 1) isec--;
183 break;
184 }
185 }
186
187 if (isec>0) {
188 ix= Int_t((x-fCx[isec-1])/(*fDpxD)[isec])
189 +fNpxS[isec-1]+1;
190 iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
191 } else if (isec == 0) {
192 ix= Int_t(x/(*fDpxD)[isec])+1;
193 iy= Int_t((y+fCy)/(*fDpyD)[isec])+1;
194 } else {
195 ix=0;
196 iy=0;
197 }
198}
cc4dcfb0 199//-------------------------------------------------------------------------
200void AliMUONSt345SlatSegmentation::GetPadI(Float_t x, Float_t y , Float_t /*z*/, Int_t &ix, Int_t &iy)
201{
202 GetPadI(x, y, ix, iy);
203}
204//_______________________________________________________________
205void AliMUONSt345SlatSegmentation::SetPadDivision(Int_t ndiv[4])
206{
f48459ab 207 // Defines the pad size perp. to the anode wire (y) for different sectors.
208 // Pad sizes are defined as integral fractions ndiv of a basis pad size
209 // fDpx
210 //
211 for (Int_t i=0; i<4; i++) {
212 (*fNDiv)[i]=ndiv[i];
213 }
214 ndiv[0]=ndiv[1];
cc4dcfb0 215}
216//____________________________________________________________________________
217void AliMUONSt345SlatSegmentation::SetPadSize(Float_t p1, Float_t p2)
218{
f48459ab 219 // Sets the padsize
220 fDpx=p1;
221 fDpy=p2;
cc4dcfb0 222}
223//_______________________________________________________________
224void AliMUONSt345SlatSegmentation::SetPcbBoards(Int_t n[4])
225{
f48459ab 226 //
227 // Set PcbBoard segmentation zones for each density
228 // n[0] PcbBoards for maximum density sector fNDiv[0]
229 // n[1] PcbBoards for next density sector fNDiv[1] etc ...
230 for (Int_t i=0; i<4; i++) fPcbBoards[i]=n[i];
cc4dcfb0 231}
232//-------------------------------------------------------------------------
233void AliMUONSt345SlatSegmentation::SetPad(Int_t ix, Int_t iy)
234{
f48459ab 235 //
236 // Sets virtual pad coordinates, needed for evaluating pad response
237 // outside the tracking program
238 GetPadC(ix,iy,fX,fY);
239 fSector=Sector(ix,iy);
cc4dcfb0 240}
241//---------------------------------------------------------------------------
242void AliMUONSt345SlatSegmentation::SetHit(Float_t x, Float_t y)
243{
f48459ab 244 // Set current hit
245 //
246 fXhit = x;
247 fYhit = y;
cc4dcfb0 248
f48459ab 249 if (x < 0) fXhit = 0;
250 if (y < 0) fYhit = 0;
cc4dcfb0 251
f48459ab 252 if (x >= fCx[fNsec-1]) fXhit = fCx[fNsec-1];
253 if (y >= fDyPCB) fYhit = fDyPCB;
cc4dcfb0 254
255}
256//----------------------------------------------------------------------------
257void AliMUONSt345SlatSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/)
258{
259 SetHit(xhit, yhit);
260}
f48459ab 261
cc4dcfb0 262//----------------------------------------------------------
263void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy)
264{
265// Initialises iteration over pads for charge distribution algorithm
266//
267 //
268 // Find the wire position (center of charge distribution)
269 Float_t x0a=GetAnod(xhit);
270 fXhit=x0a;
271 fYhit=yhit;
272 //
273 // and take fNsigma*sigma around this center
274 Float_t x01=x0a - dx;
275 Float_t x02=x0a + dx;
276 Float_t y01=yhit - dy;
277 Float_t y02=yhit + dy;
278 if (x01 < 0) x01 = 0;
279 if (y01 < 0) y01 = 0;
280
281 if (x02 >= fCx[fNsec-1]) x02 = fCx[fNsec-1];
282
283
284 Int_t isec=-1;
285 for (Int_t i=fNsec-1; i > 0; i--) {
286 if (x02 >= fCx[i-1]) {
287 isec=i;
288 if (fCx[isec] == fCx[isec-1] && isec > 1) isec--;
289 break;
290 }
291 }
292 y02 += Dpy(isec);
293 if (y02 >= fDyPCB) y02 = fDyPCB;
294
295 //
296 // find the pads over which the charge distributes
297 GetPadI(x01,y01,fIxmin,fIymin);
298 GetPadI(x02,y02,fIxmax,fIymax);
299
300 if (fIxmax > fNpx) fIxmax=fNpx;
301 if (fIymax > fNpyS[isec]) fIymax = fNpyS[isec];
302
303 fXmin=x01;
304 fXmax=x02;
305 fYmin=y01;
306 fYmax=y02;
307
308 //
309 // Set current pad to lower left corner
310 if (fIxmax < fIxmin) fIxmax=fIxmin;
311 if (fIymax < fIymin) fIymax=fIymin;
312 fIx=fIxmin;
313 fIy=fIymin;
314
315 GetPadC(fIx,fIy,fX,fY);
316 fSector=Sector(fIx,fIy);
317/*
318 printf("\n \n First Pad: %d %d %f %f %d %d %d %f" ,
319 fIxmin, fIxmax, fXmin, fXmax, fNpx, fId, isec, Dpy(isec));
320 printf("\n \n First Pad: %d %d %f %f %d %d %d %f",
321 fIymin, fIymax, fYmin, fYmax, fNpyS[isec], fId, isec, Dpy(isec));
322*/
323}
f48459ab 324
325
326
cc4dcfb0 327//----------------------------------------------------------------------
328void AliMUONSt345SlatSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy)
329{
330 FirstPad(xhit, yhit, dx, dy);
331}
332//----------------------------------------------------------------------
333void AliMUONSt345SlatSegmentation::NextPad()
334{
f48459ab 335 // Stepper for the iteration over pads
336 //
337 // Step to next pad in the integration region
338 // step from left to right
339 if (fIx != fIxmax) {
340 fIx++;
341 GetPadC(fIx,fIy,fX,fY);
342 fSector=Sector(fIx,fIy);
343 // step up
344 } else if (fIy != fIymax) {
345 fIx=fIxmin;
346 fIy++;
347 GetPadC(fIx,fIy,fX,fY);
348 fSector=Sector(fIx,fIy);
cc4dcfb0 349
f48459ab 350 } else {
351 fIx=-1;
352 fIy=-1;
353 }
354 // printf("\n Next Pad %d %d %f %f %d %d %d %d %d ",
cc4dcfb0 355}
356//-------------------------------------------------------------------------
357Int_t AliMUONSt345SlatSegmentation::MorePads()
358{
f48459ab 359 // Stopping condition for the iterator over pads
360 //
361 // Are there more pads in the integration region
cc4dcfb0 362
f48459ab 363 return (fIx != -1 || fIy != -1);
cc4dcfb0 364}
365//--------------------------------------------------------------------------
366Int_t AliMUONSt345SlatSegmentation::Sector(Int_t ix, Int_t iy)
367{
f48459ab 368 //
369 // Determine segmentation zone from pad coordinates
370 //
371 Int_t isec=-1;
372 for (Int_t i=0; i < fNsec; i++) {
373 if (ix <= fNpxS[i]) {
374 isec=i;
375 break;
cc4dcfb0 376 }
f48459ab 377 }
378 if (isec == -1) printf("\n Sector: Attention isec ! %d %d %d %d \n",
379 fId, ix, iy,fNpxS[3]);
cc4dcfb0 380
f48459ab 381 return isec;
cc4dcfb0 382
383}
384//-----------------------------------------------------------------------------
385void AliMUONSt345SlatSegmentation::
386IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
387{
f48459ab 388 // Returns integration limits for current pad
389 //
390 x1=fXhit-fX-Dpx(fSector)/2.;
391 x2=x1+Dpx(fSector);
392 y1=fYhit-fY-Dpy(fSector)/2.;
393 y2=y1+Dpy(fSector);
394 // printf("\n Integration Limits %f %f %f %f %d %f", x1, x2, y1, y2, fSector, Dpx(fSector));
cc4dcfb0 395
396}
397//-----------------------------------------------------------------------------
398void AliMUONSt345SlatSegmentation::
399Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
400{
f48459ab 401 // Returns list of next neighbours for given Pad (iX, iY)
402 Int_t i=0;
403 // step right
404 if (iX+1 <= fNpx) {
405 Xlist[i]=iX+1;
406 Ylist[i++]=iY;
407 }
408 // step left
409 if (iX-1 > 0) {
410 Xlist[i]=iX-1;
411 Ylist[i++]=iY;
412 }
413 Int_t sector = Sector(iX,iY);
414 // step up
415 if (iY+1 <= fNpyS[sector]) {
416 Xlist[i]=iX;
417 Ylist[i++]=iY+1;
418 }
419 // step down
420 if (iY-1 > 0) {
421 Xlist[i]=iX;
422 Ylist[i++]=iY-1;
423 }
424 *Nlist=i;
cc4dcfb0 425}
f48459ab 426
cc4dcfb0 427//--------------------------------------------------------------------------
428void AliMUONSt345SlatSegmentation::Init(Int_t detectionElementId)
429{
f48459ab 430 //
431 // Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector
432 // These arrays help in converting from real to pad co-ordinates and
433 // vice versa
434 //
435 // Segmentation is defined by rectangular modules approximating
436 // concentric circles as shown below
437 //
438 // PCB module size in cm
439 // printf("\n Initialise Segmentation SlatModule \n");
cc4dcfb0 440
f48459ab 441
a713db22 442 // printf(" fBending: %d \n",fBending);
f48459ab 443
444 fDxPCB=40;
445 fDyPCB=40;
446
447 // Calculate padsize along x
448 (*fDpxD)[fNsec-1]=fDpx;
449 (*fDpyD)[fNsec-1]=fDpy;
450 if (fNsec > 1) {
451 for (Int_t i=fNsec-1; i>=0; i--){ // fNsec-2
452 if (!fBending) {
453 (*fDpxD)[i]=fDpx;
454 (*fDpyD)[i]=(*fDpyD)[fNsec-1]/(*fNDiv)[i];
455 } else {
cc4dcfb0 456 (*fDpxD)[i]=(*fDpxD)[fNsec-1]/(*fNDiv)[i];
f48459ab 457 (*fDpyD)[i]=fDpy;
cc4dcfb0 458 }
459 }
f48459ab 460 }
461 //
462 // fill the arrays defining the pad segmentation boundaries
463 //
464 //
465 // Loop over sectors (isec=0 for secto close to the beam pipe)
466 Float_t totalLength = 0;
467 for (Int_t isec=0; isec<4; isec++) totalLength += fPcbBoards[isec]*fDxPCB; // !!!!
468
469 fNpy = 0; // maximum number of pads in y
470 for (Int_t isec=0; isec<4; isec++) {
471 if (isec==0) {
472 fNpxS[0] = 0;
473 fNpyS[0] = 0;
474 fCx[0] = -totalLength/2;
475 } else {
476 fNpxS[isec] = fNpxS[isec-1] + fPcbBoards[isec]*Int_t(fDxPCB/(*fDpxD)[isec]);
477 fNpyS[isec] = Int_t(fDyPCB/(*fDpyD)[isec]);
478 if (fNpyS[isec] >= fNpy) fNpy = fNpyS[isec];
479 fCx[isec]= fCx[isec-1] + fPcbBoards[isec]*fDxPCB;
480 }
481 } // sectors
cc4dcfb0 482
f48459ab 483 fNpx = fNpxS[3]; // maximum number of pads in x
484 fCy = fDyPCB/2.;
485 //
486 fId = detectionElementId;
487}
cc4dcfb0 488
489
490
491
492
493
494
495
496
497
498