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.2 2000/10/09 14:06:18 morsch
19 Some type cast problems of type (TMath::Sign((Float_t)1.,x)) corrected (P.H.)
21 Revision 1.1 2000/10/06 09:00:47 morsch
22 Segmentation class for chambers built out of slats.
26 #include "AliMUONSegmentationSlat.h"
27 #include "AliMUONSegmentationSlatModule.h"
29 #include "AliMUONChamber.h"
31 #include "TObjArray.h"
36 //___________________________________________
37 ClassImp(AliMUONSegmentationSlat)
39 AliMUONSegmentationSlat::AliMUONSegmentationSlat()
41 // Default constructor
43 fNDiv = new TArrayI(4);
46 void AliMUONSegmentationSlat::SetPadSize(Float_t p1, Float_t p2)
48 // Sets the pad (strip) size
54 Float_t AliMUONSegmentationSlat::GetAnod(Float_t xhit) const
56 // Returns for a hit position xhit the position of the nearest anode wire
57 Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5;
61 Float_t AliMUONSegmentationSlat::Dpx(Int_t isec) const
64 // Returns x-pad size for given sector isec
65 // isec = 100*islat+iregion
70 return Slat(islat)->Dpx(iregion);
73 Float_t AliMUONSegmentationSlat::Dpy(Int_t isec) const
76 // Returns y-pad (strip) size for given sector isec
80 void AliMUONSegmentationSlat::SetPadDivision(Int_t ndiv[4])
83 // Defines the pad size perp. to the anode wire (y) for different sectors.
84 // Pad sizes are defined as integral fractions ndiv of a basis pad size
87 for (Int_t i=0; i<4; i++) {
92 void AliMUONSegmentationSlat::GlobalToLocal(
93 Float_t x, Float_t y, Float_t z, Int_t &islat, Float_t &xlocal, Float_t &ylocal)
96 // Perform local to global transformation for space coordinates
101 // Transform According to slat plane z-position: negative side is shifted down
102 // positive side is shifted up
103 // by half the overlap
104 zlocal = z-fChamber->Z();
105 Float_t ys = y-TMath::Sign(fShift,zlocal);
107 // Set the signs for the symmetry transformation and transform to first quadrant
109 Float_t yabs=TMath::Abs(ys);
110 Float_t xabs=TMath::Abs(x);
112 Int_t ifirst = (zlocal*ys < Float_t(0))? 0:1;
115 for (i=ifirst; i<fNSlats; i+=2) {
117 if ((yabs >= fYPosition[i]) && (yabs < fYPosition[i]+fSlatY)) break;
121 // Transform to local coordinate system
124 ylocal = yabs-fYPosition[index];
125 xlocal = xabs-fXPosition[index];
127 if (i >= fNSlats) {islat = -1; x=-1; y = -1;}
130 void AliMUONSegmentationSlat::GlobalToLocal(
131 Int_t ix, Int_t iy, Int_t &islat, Int_t &ixlocal, Int_t &iylocal)
134 // Perform global to local transformation for pad coordinates
136 Int_t iytemp = TMath::Abs(iy);
142 // Find slat number (index) and iylocal
143 for (Int_t i=0; i<fNSlats; i++) {
144 iytemp-=Slat(i)->Npy();
147 if (iytemp <= 0) break;
152 ixlocal=TMath::Abs(ix);
158 void AliMUONSegmentationSlat::
159 LocalToGlobal(Int_t islat, Float_t xlocal, Float_t ylocal, Float_t &x, Float_t &y, Float_t &z)
161 // Transform from local to global space coordinates
163 // upper plane (y>0) even slat number is shifted down
164 // upper plane (y>0) odd slat number is shifted up
165 // lower plane (y<0) even slat number is shifted up
166 // lower plane (y<0) odd slat number is shifted down
169 x = (xlocal+fXPosition[islat])*fSym[0];
170 if ((TMath::Even(islat) && fSym[1]>0) || (TMath::Odd(islat)&&fSym[1]<0)) {
171 y=(ylocal+fYPosition[islat])*fSym[1]-fShift;
174 y=(ylocal+fYPosition[islat])*fSym[1]+fShift;
183 void AliMUONSegmentationSlat::LocalToGlobal(
184 Int_t islat, Int_t ixlocal, Int_t iylocal, Int_t &ix, Int_t &iy)
186 // Transform from local to global pad coordinates
192 // Find slat number (index) and iylocal
193 for (i=0; i<islat; i++) iy+=Slat(islat)->Npy();
200 void AliMUONSegmentationSlat::SetSymmetry(Int_t ix, Int_t iy)
202 // Set set signs for symmetry transformation
203 fSym[0]=TMath::Sign(1,ix);
204 fSym[1]=TMath::Sign(1,iy);
208 void AliMUONSegmentationSlat::SetSymmetry(Float_t x, Float_t y)
210 // Set set signs for symmetry transformation
211 fSym[0]=Int_t (TMath::Sign((Float_t)1.,x));
212 fSym[1]=Int_t (TMath::Sign((Float_t)1.,y));
215 void AliMUONSegmentationSlat::
216 GetPadI(Float_t x, Float_t y, Float_t z, Int_t &ix, Int_t &iy)
218 // Returns pad coordinates for given set of space coordinates
221 Float_t xlocal, ylocal;
223 GlobalToLocal(x,y,z,islat,xlocal,ylocal);
228 Slat(islat)->GetPadI(xlocal, ylocal, ix, iy);
229 for (i=0; i<islat; i++) iy+=Slat(islat)->Npy();
231 ix=ix*Int_t(TMath::Sign((Float_t)1.,x));
233 iy=iy*Int_t(TMath::Sign((Float_t)1.,y));
236 void AliMUONSegmentationSlat::
237 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y, Float_t &z)
239 // Returns real coordinates (x,y) for given pad coordinates (ix,iy)
241 Int_t islat, ixlocal, iylocal;
243 // Delegation of transforamtion to slat
244 GlobalToLocal(ix,iy,islat,ixlocal,iylocal);
245 Slat(islat)->GetPadC(ixlocal, iylocal, x, y);
247 x+=fXPosition[islat];
248 y+=fYPosition[islat];
250 // Symmetry transformation of quadrants
251 x=x*TMath::Sign(1,ix);
252 y=y*TMath::Sign(1,iy);
254 // Shift of slat planes
255 if ((TMath::Even(islat)&&iy>0) || (TMath::Odd(islat)&&iy<0)) {
257 z=-fDz+fChamber->Z();
264 Int_t AliMUONSegmentationSlat::ISector()
266 // Returns current sector during tracking
269 iregion = fCurrentSlat->ISector();
270 return 100*fSlatIndex+iregion;
273 Int_t AliMUONSegmentationSlat::Sector(Int_t ix, Int_t iy)
275 Int_t ixlocal, iylocal, iregion, islat;
277 GlobalToLocal(ix,iy,islat,ixlocal,iylocal);
279 iregion = Slat(islat)->Sector(ixlocal, iylocal);
280 return 100*islat+iregion;
284 void AliMUONSegmentationSlat::SetPad(Int_t ix, Int_t iy)
287 // Sets virtual pad coordinates, needed for evaluating pad response
288 // outside the tracking program
289 Int_t islat, ixlocal, iylocal;
293 GlobalToLocal(ix,iy,islat,ixlocal,iylocal);
295 fCurrentSlat=Slat(islat);
296 fCurrentSlat->SetPad(ixlocal, iylocal);
299 void AliMUONSegmentationSlat::SetHit(Float_t xhit, Float_t yhit, Float_t zhit)
301 // Sets current hit coordinates
303 Float_t xlocal, ylocal;
308 GlobalToLocal(xhit,yhit,zhit,islat,xlocal,ylocal);
310 if (islat < 0) printf("\n SetHit: %d", islat);
312 fCurrentSlat=Slat(islat);
313 fCurrentSlat->SetHit(xlocal, ylocal);
317 void AliMUONSegmentationSlat::
318 FirstPad(Float_t xhit, Float_t yhit, Float_t zhit, Float_t dx, Float_t dy)
320 // Initialises iteration over pads for charge distribution algorithm
326 Float_t xlocal, ylocal;
327 GlobalToLocal(xhit, yhit, zhit, islat, xlocal, ylocal);
329 fCurrentSlat=Slat(islat);
330 fCurrentSlat->FirstPad(xlocal, ylocal, dx, dy);
335 void AliMUONSegmentationSlat::NextPad()
337 // Stepper for the iteration over pads
339 fCurrentSlat->NextPad();
343 Int_t AliMUONSegmentationSlat::MorePads()
344 // Stopping condition for the iterator over pads
346 // Are there more pads in the integration region
348 return fCurrentSlat->MorePads();
351 void AliMUONSegmentationSlat::
352 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
354 // Returns integration limits for current pad
357 fCurrentSlat->IntegrationLimits(x1, x2, y1, y2);
361 void AliMUONSegmentationSlat::
362 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
364 // Returns list of neighbours of pad with coordinates iX, iY
366 Int_t i, xListLocal[10], yListLocal[10], iXlocal, iYlocal, islat;
370 GlobalToLocal(iX, iY, islat, iXlocal, iYlocal);
372 Slat(islat)->Neighbours(iXlocal, iYlocal, Nlist, xListLocal, yListLocal);
374 for (i=0; i<*Nlist; i++) LocalToGlobal(islat, xListLocal[i], yListLocal[i], Xlist[i], Ylist[i]);
379 Int_t AliMUONSegmentationSlat::Ix()
381 // Return current pad coordinate ix during stepping
383 ixl=fCurrentSlat->Ix();
384 iyl=fCurrentSlat->Iy();
386 LocalToGlobal(fSlatIndex, ixl, iyl, ix, iy);
389 GlobalToLocal(ix, iy, isc, ixc, iyc);
390 Slat(isc)->GetPadC(ixc,iyc,xc,yc);
395 Int_t AliMUONSegmentationSlat::Iy()
397 // Return current pad coordinate iy during stepping
399 ixl=fCurrentSlat->Ix();
400 iyl=fCurrentSlat->Iy();
401 LocalToGlobal(fSlatIndex, ixl, iyl, ix, iy);
407 // Signal Generation Condition during Stepping
408 Int_t AliMUONSegmentationSlat::SigGenCond(Float_t x, Float_t y, Float_t z)
411 // True if signal generation condition fullfilled
412 Float_t xlocal, ylocal;
414 GlobalToLocal(x, y, z, islat, xlocal, ylocal);
415 return Slat(islat)->SigGenCond(xlocal, ylocal, z);
418 // Initialise signal generation at coord (x,y,z)
419 void AliMUONSegmentationSlat::SigGenInit(Float_t x, Float_t y, Float_t z)
421 // Initialize the signal generation condition
423 Float_t xlocal, ylocal;
426 GlobalToLocal(x, y, z, islat, xlocal, ylocal);
427 Slat(islat)->SigGenInit(xlocal, ylocal, z);
432 void AliMUONSegmentationSlat::Init(Int_t chamber)
435 // Initialize slat modules of quadrant +/+
436 // The other three quadrants are handled through symmetry transformations
438 printf("\n Initialise Segmentation Slat \n");
441 // Initialize Slat modules
445 for (i=0; i<4; i++) ndiv[i]=(*fNDiv)[i];
446 // Half distance between slat planes
450 for (i=0; i<10; i++) fSlatX[i]=0.;
453 // Initialize array of slats
454 fSlats = new TObjArray(fNSlats);
455 // Maximum number of strips (pads) in x and y
458 // for each slat in the quadrant (+,+)
459 for (islat=0; islat<fNSlats; islat++) {
460 (*fSlats)[islat] = CreateSlatModule();
462 AliMUONSegmentationSlatModule *slat = Slat(islat);
467 slat->SetPadSize(fDpx, fDpy);
468 // Forward wire pitch
469 slat->SetDAnod(fWireD);
470 // Foward segmentation
471 slat->SetPadDivision(ndiv);
472 slat->SetPcbBoards(fPcb[islat]);
473 // Initialize slat module
475 // y-position of slat module relative to the first (closest to the beam)
476 fYPosition[islat]=islat*(fSlatY-2.*fShift);
477 if (TMath::Odd(islat)) fYPosition[islat] -= 2*fShift;
480 if (slat->Npx() > fNpx) fNpx=slat->Npx();
482 for (isec=0; isec< 4; isec++)
484 fSlatX[islat]+=40.*fPcb[islat][isec];
488 // Set parent chamber number
489 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
490 fChamber=&(pMUON->Chamber(chamber));
497 void AliMUONSegmentationSlat::SetNPCBperSector(Int_t *npcb)
499 // PCB distribution for station 4 (6 rows with 1+3 segmentation regions)
500 for (Int_t islat=0; islat<fNSlats; islat++){
501 fPcb[islat][0] = *(npcb + 4 * islat);
502 fPcb[islat][1] = *(npcb + 4 * islat + 1);
503 fPcb[islat][2] = *(npcb + 4 * islat + 2);
504 fPcb[islat][3] = *(npcb + 4 * islat + 3);
509 void AliMUONSegmentationSlat::SetSlatXPositions(Float_t *xpos)
511 // Set x-positions of Slats
512 for (Int_t islat=0; islat<fNSlats; islat++) fXPosition[islat]=xpos[islat];
515 AliMUONSegmentationSlatModule* AliMUONSegmentationSlat::Slat(Int_t index) const
516 { return ((AliMUONSegmentationSlatModule*) (*fSlats)[index]);}
519 AliMUONSegmentationSlatModule* AliMUONSegmentationSlat::
522 // Factory method for slat module
523 return new AliMUONSegmentationSlatModule();