]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSegmentationSlat.cxx
- AliMUONRawCluster contains z-position.
[u/mrichter/AliRoot.git] / MUON / AliMUONSegmentationSlat.cxx
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 /*
17 $Log$
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.)
20
21 Revision 1.1  2000/10/06 09:00:47  morsch
22 Segmentation class for chambers built out of slats.
23
24 */
25
26 #include "AliMUONSegmentationSlat.h"
27 #include "AliMUONSegmentationSlatModule.h"
28 #include "AliMUON.h"
29 #include "AliMUONChamber.h"
30 #include "TArrayI.h"
31 #include "TObjArray.h"
32 #include "AliRun.h"
33 #include <TMath.h>
34 #include <iostream.h>
35
36 //___________________________________________
37 ClassImp(AliMUONSegmentationSlat)
38
39 AliMUONSegmentationSlat::AliMUONSegmentationSlat() 
40 {
41 // Default constructor
42     fSlats=0;            
43     fNDiv = new TArrayI(4);   
44 }
45
46 void AliMUONSegmentationSlat::SetPadSize(Float_t p1, Float_t p2)
47 {
48 //  Sets the pad (strip) size 
49 //  
50     fDpx=p1;
51     fDpy=p2;
52 }
53
54 Float_t AliMUONSegmentationSlat::GetAnod(Float_t xhit) const
55 {
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;
58     return fWireD*wire;
59 }
60
61 Float_t AliMUONSegmentationSlat::Dpx(Int_t isec) const
62 {
63 //
64 // Returns x-pad size for given sector isec
65 // isec = 100*islat+iregion
66 //
67     Int_t islat, iregion;
68     islat    = isec/100;
69     iregion  = isec%100;
70     return Slat(islat)->Dpx(iregion);
71 }
72
73 Float_t AliMUONSegmentationSlat::Dpy(Int_t isec) const
74 {
75 //
76 // Returns y-pad (strip)  size for given sector isec
77    return fDpy;
78 }
79
80 void AliMUONSegmentationSlat::SetPadDivision(Int_t ndiv[4])
81 {
82 //
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
85 // fDpx
86 // 
87     for (Int_t i=0; i<4; i++) {
88         (*fNDiv)[i]=ndiv[i];
89     }
90 }
91
92 void AliMUONSegmentationSlat::GlobalToLocal(
93     Float_t x, Float_t y, Float_t z, Int_t &islat, Float_t &xlocal, Float_t &ylocal)
94 {
95 //
96 // Perform local to global transformation for space coordinates
97 //
98     Float_t zlocal;
99     Int_t i;
100     Int_t index=-1;
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);
106
107 //  Set the signs for the symmetry transformation and transform to first quadrant
108     SetSymmetry(x,ys);
109     Float_t yabs=TMath::Abs(ys);
110     Float_t xabs=TMath::Abs(x);
111
112     Int_t ifirst = (zlocal*ys < Float_t(0))? 0:1;
113 //
114 // Find slat number                      
115     for (i=ifirst; i<fNSlats; i+=2) {
116         index=i;
117         if ((yabs >= fYPosition[i]) && (yabs < fYPosition[i]+fSlatY)) break;
118     }
119     
120 //
121 // Transform to local coordinate system
122
123     
124     ylocal = yabs-fYPosition[index];
125     xlocal = xabs-fXPosition[index];
126     islat  = index;
127     if (i >= fNSlats) {islat = -1; x=-1; y = -1;}
128 }
129
130 void AliMUONSegmentationSlat::GlobalToLocal(
131     Int_t ix, Int_t iy, Int_t &islat, Int_t &ixlocal, Int_t &iylocal)
132 {
133 //
134 // Perform global to local transformation for pad coordinates
135 //
136     Int_t iytemp = TMath::Abs(iy);
137     Int_t index  = 0;
138     
139     iylocal = iytemp;
140
141 //
142 // Find slat number (index) and iylocal  
143     for (Int_t i=0; i<fNSlats; i++) {
144         iytemp-=Slat(i)->Npy();
145         
146         
147         if (iytemp <= 0) break;
148         iylocal = iytemp;
149         index=i+1;
150     }
151
152     ixlocal=TMath::Abs(ix);
153     islat=index;
154     
155 // Done !
156 }
157
158 void AliMUONSegmentationSlat::
159 LocalToGlobal(Int_t islat, Float_t  xlocal, Float_t  ylocal, Float_t  &x, Float_t  &y, Float_t &z)
160 {
161 // Transform from local to global space coordinates
162 //
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
167 //
168
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;
172         z=-fDz;
173     } else {
174         y=(ylocal+fYPosition[islat])*fSym[1]+fShift;
175         z=fDz;
176     }
177
178     z+=fChamber->Z();
179
180 }
181
182
183 void AliMUONSegmentationSlat::LocalToGlobal(
184     Int_t islat, Int_t ixlocal, Int_t iylocal, Int_t &ix, Int_t &iy)
185 {
186 // Transform from local to global pad coordinates
187 //
188     Int_t i;
189     iy=iylocal;
190     
191 //
192 // Find slat number (index) and iylocal  
193     for (i=0; i<islat; i++) iy+=Slat(islat)->Npy();
194
195     ix=ixlocal*fSym[0];
196     iy=iy*fSym[1];
197 }
198
199
200 void AliMUONSegmentationSlat::SetSymmetry(Int_t   ix,   Int_t iy)
201 {
202 // Set set signs for symmetry transformation
203     fSym[0]=TMath::Sign(1,ix);
204     fSym[1]=TMath::Sign(1,iy);
205     
206 }
207
208 void AliMUONSegmentationSlat::SetSymmetry(Float_t  x, Float_t  y)
209 {
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));
213 }
214
215 void AliMUONSegmentationSlat::
216 GetPadI(Float_t x, Float_t y, Float_t z, Int_t &ix, Int_t &iy)
217 {
218 // Returns pad coordinates for given set of space coordinates
219
220     Int_t islat, i;
221     Float_t xlocal, ylocal;
222     
223     GlobalToLocal(x,y,z,islat,xlocal,ylocal);
224     if (islat == -1) {
225         ix=0; iy=0; return;
226     }
227     
228     Slat(islat)->GetPadI(xlocal, ylocal, ix, iy);
229     for (i=0; i<islat; i++) iy+=Slat(islat)->Npy();
230
231     ix=ix*Int_t(TMath::Sign((Float_t)1.,x));    
232 // Transform y 
233     iy=iy*Int_t(TMath::Sign((Float_t)1.,y));   
234 }
235
236 void AliMUONSegmentationSlat::
237 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y, Float_t &z)
238 {
239 //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
240 //
241     Int_t islat, ixlocal, iylocal;
242 //
243 // Delegation of transforamtion to slat
244     GlobalToLocal(ix,iy,islat,ixlocal,iylocal);
245     Slat(islat)->GetPadC(ixlocal, iylocal, x, y);
246 // Slat offset
247     x+=fXPosition[islat];
248     y+=fYPosition[islat];    
249
250 // Symmetry transformation of quadrants    
251     x=x*TMath::Sign(1,ix);
252     y=y*TMath::Sign(1,iy);    
253
254 // Shift of slat planes
255     if ((TMath::Even(islat)&&iy>0) || (TMath::Odd(islat)&&iy<0)) {
256         y-=fShift;
257         z=-fDz+fChamber->Z();
258     } else {
259         y+=fShift;
260         z=fDz+fChamber->Z();
261     }
262 }
263
264 Int_t AliMUONSegmentationSlat::ISector()
265 {
266 // Returns current sector during tracking
267     Int_t iregion;
268     
269     iregion =  fCurrentSlat->ISector();
270     return 100*fSlatIndex+iregion;
271 }
272
273 Int_t AliMUONSegmentationSlat::Sector(Int_t ix, Int_t iy)
274 {
275     Int_t ixlocal, iylocal, iregion, islat;
276
277     GlobalToLocal(ix,iy,islat,ixlocal,iylocal);
278     
279     iregion =  Slat(islat)->Sector(ixlocal, iylocal);
280     return 100*islat+iregion;
281 }
282
283
284 void AliMUONSegmentationSlat::SetPad(Int_t ix, Int_t iy)
285 {
286     //
287     // Sets virtual pad coordinates, needed for evaluating pad response 
288     // outside the tracking program
289     Int_t islat, ixlocal, iylocal;
290
291     SetSymmetry(ix,iy);
292     
293     GlobalToLocal(ix,iy,islat,ixlocal,iylocal);
294     fSlatIndex=islat;
295     fCurrentSlat=Slat(islat);
296     fCurrentSlat->SetPad(ixlocal, iylocal);
297 }
298
299 void  AliMUONSegmentationSlat::SetHit(Float_t xhit, Float_t yhit, Float_t zhit)
300 {   //
301     // Sets current hit coordinates
302
303     Float_t xlocal, ylocal;
304     Int_t islat;
305
306     
307
308     GlobalToLocal(xhit,yhit,zhit,islat,xlocal,ylocal);
309     fSlatIndex=islat;
310     if (islat < 0) printf("\n SetHit: %d", islat);
311     
312     fCurrentSlat=Slat(islat);
313     fCurrentSlat->SetHit(xlocal, ylocal);
314 }
315
316
317 void AliMUONSegmentationSlat::
318 FirstPad(Float_t xhit, Float_t yhit, Float_t zhit, Float_t dx, Float_t dy)
319 {
320 // Initialises iteration over pads for charge distribution algorithm
321 //
322
323
324
325     Int_t islat;
326     Float_t xlocal, ylocal;
327     GlobalToLocal(xhit, yhit, zhit, islat, xlocal, ylocal);
328     fSlatIndex=islat;
329     fCurrentSlat=Slat(islat);
330     fCurrentSlat->FirstPad(xlocal, ylocal, dx, dy);
331
332 }
333
334
335 void AliMUONSegmentationSlat::NextPad()
336 {
337 // Stepper for the iteration over pads
338 //
339     fCurrentSlat->NextPad();
340 }
341
342
343 Int_t AliMUONSegmentationSlat::MorePads()
344 // Stopping condition for the iterator over pads
345 //
346 // Are there more pads in the integration region
347
348     return fCurrentSlat->MorePads();
349 }
350
351 void AliMUONSegmentationSlat::
352 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
353 {
354 //  Returns integration limits for current pad
355 //
356     
357     fCurrentSlat->IntegrationLimits(x1, x2, y1, y2);
358
359 }
360
361 void AliMUONSegmentationSlat::
362 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
363 {
364 // Returns list of neighbours of pad with coordinates iX, iY
365
366     Int_t i, xListLocal[10], yListLocal[10], iXlocal, iYlocal, islat;
367     
368     SetSymmetry(iX,iY);
369
370     GlobalToLocal(iX, iY, islat, iXlocal, iYlocal);
371  
372     Slat(islat)->Neighbours(iXlocal, iYlocal, Nlist, xListLocal, yListLocal);
373     
374     for (i=0; i<*Nlist; i++) LocalToGlobal(islat, xListLocal[i], yListLocal[i], Xlist[i], Ylist[i]);
375
376 }
377
378
379 Int_t  AliMUONSegmentationSlat::Ix()
380 {
381 // Return current pad coordinate ix during stepping
382     Int_t ixl,iyl,ix,iy;
383     ixl=fCurrentSlat->Ix();
384     iyl=fCurrentSlat->Iy();
385     
386     LocalToGlobal(fSlatIndex, ixl, iyl, ix, iy);
387     Int_t ixc, iyc, isc;
388     Float_t xc, yc;
389     GlobalToLocal(ix, iy, isc, ixc, iyc);
390     Slat(isc)->GetPadC(ixc,iyc,xc,yc);
391     return ix;
392 }
393
394
395 Int_t  AliMUONSegmentationSlat::Iy()
396 {
397 // Return current pad coordinate iy during stepping
398     Int_t ixl,iyl,ix,iy;
399     ixl=fCurrentSlat->Ix();
400     iyl=fCurrentSlat->Iy();
401     LocalToGlobal(fSlatIndex, ixl, iyl, ix, iy);
402     return iy;
403 }
404
405
406
407    // Signal Generation Condition during Stepping
408 Int_t AliMUONSegmentationSlat::SigGenCond(Float_t x, Float_t y, Float_t z)
409
410 //
411 //  True if signal generation condition fullfilled
412     Float_t xlocal, ylocal;
413     Int_t islat;
414     GlobalToLocal(x, y, z, islat, xlocal, ylocal);
415     return Slat(islat)->SigGenCond(xlocal, ylocal, z);
416 }
417
418 // Initialise signal generation at coord (x,y,z)
419 void  AliMUONSegmentationSlat::SigGenInit(Float_t x, Float_t y, Float_t z)
420 {
421 // Initialize the signal generation condition
422 //
423     Float_t xlocal, ylocal;
424     Int_t islat;
425
426     GlobalToLocal(x, y, z, islat, xlocal, ylocal);
427     Slat(islat)->SigGenInit(xlocal, ylocal, z);
428 }
429
430
431
432 void AliMUONSegmentationSlat::Init(Int_t chamber)
433 {
434 //    
435 // Initialize slat modules of quadrant +/+    
436 // The other three quadrants are handled through symmetry transformations
437 //
438     printf("\n Initialise Segmentation Slat \n");
439 //
440
441 //    Initialize Slat modules
442     Int_t islat, i;
443     Int_t ndiv[4];
444 // Pad division
445     for (i=0; i<4; i++) ndiv[i]=(*fNDiv)[i];
446 // Half distance between slat planes
447     fDz=1.76;
448 // Slat height    
449     fSlatY=40.;
450     for (i=0; i<10; i++) fSlatX[i]=0.;
451     
452     
453 // Initialize array of slats 
454     fSlats  = new TObjArray(fNSlats);
455 // Maximum number of strips (pads) in x and y
456     fNpy=0;   
457     fNpx=0;
458 // for each slat in the quadrant (+,+)    
459     for (islat=0; islat<fNSlats; islat++) {
460         (*fSlats)[islat] = CreateSlatModule();
461
462         AliMUONSegmentationSlatModule *slat =  Slat(islat);
463         // Configure Slat
464         slat->SetId(islat);
465         
466 // Foward pad size
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
474         slat->Init(chamber);
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;
478 //
479         fNpy+=slat->Npy();
480         if (slat->Npx() > fNpx) fNpx=slat->Npx();
481         Int_t isec;
482         for (isec=0; isec< 4; isec++)
483         {
484             fSlatX[islat]+=40.*fPcb[islat][isec];
485         }
486         
487     }
488 // Set parent chamber number
489     AliMUON *pMUON  = (AliMUON *) gAlice->GetModule("MUON");
490     fChamber=&(pMUON->Chamber(chamber));
491 }
492
493
494
495
496
497 void AliMUONSegmentationSlat::SetNPCBperSector(Int_t *npcb)
498
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);
505     }
506 }
507
508
509 void  AliMUONSegmentationSlat::SetSlatXPositions(Float_t *xpos)
510 {
511 // Set x-positions of Slats
512     for (Int_t islat=0; islat<fNSlats; islat++) fXPosition[islat]=xpos[islat];
513 }
514
515 AliMUONSegmentationSlatModule*  AliMUONSegmentationSlat::Slat(Int_t index) const
516 { return ((AliMUONSegmentationSlatModule*) (*fSlats)[index]);}
517
518
519 AliMUONSegmentationSlatModule* AliMUONSegmentationSlat::
520 CreateSlatModule()
521 {
522     // Factory method for slat module
523     return new AliMUONSegmentationSlatModule();
524 }
525
526
527
528
529