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