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