]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSegmentationSlat.cxx
Changes needed to work with Root 3.01 (substitute lhs [] operator). (Jiri Chudoba)
[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.12  2001/05/16 14:57:17  alibrary
19 New files for folders and Stack
20
21 Revision 1.11  2001/01/26 21:25:48  morsch
22 Empty default constructors and.
23
24 Revision 1.10  2001/01/23 18:58:19  hristov
25 Initialisation of some pointers
26
27 Revision 1.9  2001/01/17 20:53:40  hristov
28 Destructors corrected to avoid memory leaks
29
30 Revision 1.8  2000/12/21 22:12:41  morsch
31 Clean-up of coding rule violations,
32
33 Revision 1.7  2000/11/08 13:01:40  morsch
34 Chamber half-planes of stations 3-5 at different z-positions.
35
36 Revision 1.6  2000/11/06 09:20:43  morsch
37 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
38 Draw() method. This avoids code and parameter replication.
39
40 Revision 1.5  2000/10/23 13:37:40  morsch
41 Correct z-position of slat planes.
42
43 Revision 1.4  2000/10/22 16:55:43  morsch
44 Use only x-symmetry in global to local transformations and delegation.
45
46 Revision 1.3  2000/10/18 11:42:06  morsch
47 - AliMUONRawCluster contains z-position.
48 - Some clean-up of useless print statements during initialisations.
49
50 Revision 1.2  2000/10/09 14:06:18  morsch
51 Some type cast problems of type  (TMath::Sign((Float_t)1.,x)) corrected (P.H.)
52
53 Revision 1.1  2000/10/06 09:00:47  morsch
54 Segmentation class for chambers built out of slats.
55
56 */
57
58 #include "AliMUONSegmentationSlat.h"
59 #include "AliMUONSegmentationSlatModule.h"
60 #include "AliMUON.h"
61 #include "AliMUONChamber.h"
62 #include "TArrayI.h"
63 #include "TObjArray.h"
64 #include "AliRun.h"
65 #include <TMath.h>
66 #include <TBRIK.h>
67 #include <TNode.h>
68 #include <TGeometry.h>
69 #include <iostream.h>
70
71 //___________________________________________
72 ClassImp(AliMUONSegmentationSlat)
73
74 AliMUONSegmentationSlat::AliMUONSegmentationSlat() 
75 {
76 // Default constructor
77 }
78
79 AliMUONSegmentationSlat::AliMUONSegmentationSlat(Int_t nsec) 
80 {
81 // Non default constructor
82     fSlats=0;            
83     fNDiv = new TArrayI(4);
84     fChamber = 0;
85     fCurrentSlat = 0;
86 }
87
88 AliMUONSegmentationSlat::~AliMUONSegmentationSlat(){
89   //PH Delete TObjArrays
90   if (fSlats) {
91     fSlats->Delete();
92     delete fSlats;
93   }
94
95   if (fNDiv) {
96     delete fNDiv;
97   }
98
99 }
100
101 void AliMUONSegmentationSlat::SetPadSize(Float_t p1, Float_t p2)
102 {
103 //  Sets the pad (strip) size 
104 //  
105     fDpx=p1;
106     fDpy=p2;
107 }
108
109 Float_t AliMUONSegmentationSlat::GetAnod(Float_t xhit) const
110 {
111 // Returns for a hit position xhit the position of the nearest anode wire    
112     Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5;
113     return fWireD*wire;
114 }
115
116 Float_t AliMUONSegmentationSlat::Dpx(Int_t isec) const
117 {
118 //
119 // Returns x-pad size for given sector isec
120 // isec = 100*islat+iregion
121 //
122     Int_t islat, iregion;
123     islat    = isec/100;
124     iregion  = isec%100;
125     return Slat(islat)->Dpx(iregion);
126 }
127
128 Float_t AliMUONSegmentationSlat::Dpy(Int_t isec) const
129 {
130 //
131 // Returns y-pad (strip)  size for given sector isec
132    return fDpy;
133 }
134
135 void AliMUONSegmentationSlat::SetPadDivision(Int_t ndiv[4])
136 {
137 //
138 // Defines the pad size perp. to the anode wire (y) for different sectors. 
139 // Pad sizes are defined as integral fractions ndiv of a basis pad size
140 // fDpx
141 // 
142     for (Int_t i=0; i<4; i++) {
143         (*fNDiv)[i]=ndiv[i];
144     }
145 }
146
147 void AliMUONSegmentationSlat::GlobalToLocal(
148     Float_t x, Float_t y, Float_t z, Int_t &islat, Float_t &xlocal, Float_t &ylocal)
149 {
150 //
151 // Perform local to global transformation for space coordinates
152 //
153     Float_t zlocal;
154     Int_t i;
155     Int_t index=-1;
156 // Transform According to slat plane z-position: negative side is shifted down 
157 //                                                 positive side is shifted up
158 // by half the overlap
159     zlocal = z-fChamber->Z();
160     zlocal = (x>0) ? zlocal-2.*fDz : zlocal+2.*fDz;
161 //  Set the signs for the symmetry transformation and transform to first quadrant
162     SetSymmetry(x);
163     Float_t xabs=TMath::Abs(x);
164
165     Int_t ifirst = (zlocal < Float_t(0))? 0:1;
166 //
167 // Find slat number                      
168     for (i=ifirst; i<fNSlats; i+=2) {
169         index=i;
170         if ((y >= fYPosition[i]) && (y < fYPosition[i]+fSlatY)) break;
171     }
172     
173 //
174 // Transform to local coordinate system
175
176     
177     ylocal = y   -fYPosition[index];
178     xlocal = xabs-fXPosition[index];
179     islat  = index;
180     if (i >= fNSlats) {islat = -1; x=-1; y = -1;}
181 }
182
183 void AliMUONSegmentationSlat::GlobalToLocal(
184     Int_t ix, Int_t iy, Int_t &islat, Int_t &ixlocal, Int_t &iylocal)
185 {
186 //
187 // Perform global to local transformation for pad coordinates
188 //
189     Int_t iytemp = iy;
190     Int_t index  =  0;
191     
192     iylocal = iytemp;
193
194 //
195 // Find slat number (index) and iylocal  
196     for (Int_t i=0; i<fNSlats; i++) {
197         iytemp-=Slat(i)->Npy();
198         
199         
200         if (iytemp <= 0) break;
201         iylocal = iytemp;
202         index=i+1;
203     }
204
205     ixlocal=TMath::Abs(ix);
206     islat=index;
207 }
208
209 void AliMUONSegmentationSlat::
210 LocalToGlobal(Int_t islat, Float_t  xlocal, Float_t  ylocal, Float_t  &x, Float_t  &y, Float_t &z)
211 {
212 // Transform from local to global space coordinates
213 //
214 // upper plane (y>0) even slat number is shifted down
215 // upper plane (y>0)  odd slat number is shifted up 
216 // lower plane (y<0) even slat number is shifted up
217 // lower plane (y<0)  odd slat number is shifted down
218 //
219
220     x = (xlocal+fXPosition[islat])*fSym;
221     y=(ylocal+fYPosition[islat]);
222
223     z = (TMath::Even(islat)) ?     -fDz : fDz ; 
224     z = (x>0)                ? z+2.*fDz : z-2.*fDz ; 
225
226     z+=fChamber->Z();
227 }
228
229
230 void AliMUONSegmentationSlat::LocalToGlobal(
231     Int_t islat, Int_t ixlocal, Int_t iylocal, Int_t &ix, Int_t &iy)
232 {
233 // Transform from local to global pad coordinates
234 //
235     Int_t i;
236     iy=iylocal;
237     
238 //
239 // Find slat number (index) and iylocal  
240     for (i=0; i<islat; i++) iy+=Slat(islat)->Npy();
241
242     ix=ixlocal*fSym;
243     iy=iy;
244 }
245
246
247 void AliMUONSegmentationSlat::SetSymmetry(Int_t   ix)
248 {
249 // Set set signs for symmetry transformation
250     fSym=TMath::Sign(1,ix);
251 }
252
253 void AliMUONSegmentationSlat::SetSymmetry(Float_t  x)
254 {
255 // Set set signs for symmetry transformation
256     fSym=Int_t (TMath::Sign((Float_t)1.,x));
257 }
258
259 void AliMUONSegmentationSlat::
260 GetPadI(Float_t x, Float_t y, Float_t z, Int_t &ix, Int_t &iy)
261 {
262 // Returns pad coordinates for given set of space coordinates
263
264     Int_t islat, i;
265     Float_t xlocal, ylocal;
266     
267     GlobalToLocal(x,y,z,islat,xlocal,ylocal);
268     if (islat == -1) {
269         ix=0; iy=0; return;
270     }
271     
272     Slat(islat)->GetPadI(xlocal, ylocal, ix, iy);
273     for (i=0; i<islat; i++) iy+=Slat(islat)->Npy();
274
275     ix=ix*Int_t(TMath::Sign((Float_t)1.,x));    
276 }
277
278
279 void AliMUONSegmentationSlat::
280 GetPadC(Int_t ix, Int_t iy, Float_t &x, Float_t &y, Float_t &z)
281 {
282 //  Returns real coordinates (x,y) for given pad coordinates (ix,iy)
283 //
284     Int_t islat, ixlocal, iylocal;
285 //
286 // Delegation of transforamtion to slat
287     GlobalToLocal(ix,iy,islat,ixlocal,iylocal);
288     Slat(islat)->GetPadC(ixlocal, iylocal, x, y);
289 // Slat offset
290     x+=fXPosition[islat];
291     y+=fYPosition[islat];    
292
293 // Symmetry transformation of half planes
294     x=x*TMath::Sign(1,ix);
295
296 // z-position
297     z = (TMath::Even(islat)) ?      -fDz : fDz ; 
298     z = (x>0)                ?  z+2.*fDz : z-2.*fDz ; 
299     z += fChamber->Z();
300 }
301
302 Int_t AliMUONSegmentationSlat::ISector()
303 {
304 // Returns current sector during tracking
305     Int_t iregion;
306     
307     iregion =  fCurrentSlat->ISector();
308     return 100*fSlatIndex+iregion;
309 }
310
311 Int_t AliMUONSegmentationSlat::Sector(Int_t ix, Int_t iy)
312 {
313 // Returns sector for pad coordiantes (ix,iy)
314     Int_t ixlocal, iylocal, iregion, islat;
315
316     GlobalToLocal(ix,iy,islat,ixlocal,iylocal);
317     
318     iregion =  Slat(islat)->Sector(ixlocal, iylocal);
319     return 100*islat+iregion;
320 }
321
322
323 void AliMUONSegmentationSlat::SetPad(Int_t ix, Int_t iy)
324 {
325     //
326     // Sets virtual pad coordinates, needed for evaluating pad response 
327     // outside the tracking program
328     Int_t islat, ixlocal, iylocal;
329
330     SetSymmetry(ix);
331     
332     GlobalToLocal(ix,iy,islat,ixlocal,iylocal);
333     fSlatIndex=islat;
334     fCurrentSlat=Slat(islat);
335     fCurrentSlat->SetPad(ixlocal, iylocal);
336 }
337
338 void  AliMUONSegmentationSlat::SetHit(Float_t xhit, Float_t yhit, Float_t zhit)
339 {   //
340     // Sets current hit coordinates
341
342     Float_t xlocal, ylocal;
343     Int_t islat;
344
345     
346
347     GlobalToLocal(xhit,yhit,zhit,islat,xlocal,ylocal);
348     fSlatIndex=islat;
349     if (islat < 0) printf("\n SetHit: %d", islat);
350     
351     fCurrentSlat=Slat(islat);
352     fCurrentSlat->SetHit(xlocal, ylocal);
353 }
354
355
356 void AliMUONSegmentationSlat::
357 FirstPad(Float_t xhit, Float_t yhit, Float_t zhit, Float_t dx, Float_t dy)
358 {
359 // Initialises iteration over pads for charge distribution algorithm
360 //
361
362
363
364     Int_t islat;
365     Float_t xlocal, ylocal;
366     GlobalToLocal(xhit, yhit, zhit, islat, xlocal, ylocal);
367     fSlatIndex=islat;
368     fCurrentSlat=Slat(islat);
369     fCurrentSlat->FirstPad(xlocal, ylocal, dx, dy);
370
371 }
372
373
374 void AliMUONSegmentationSlat::NextPad()
375 {
376 // Stepper for the iteration over pads
377 //
378     fCurrentSlat->NextPad();
379 }
380
381
382 Int_t AliMUONSegmentationSlat::MorePads()
383 // Stopping condition for the iterator over pads
384 //
385 // Are there more pads in the integration region
386
387     return fCurrentSlat->MorePads();
388 }
389
390 void AliMUONSegmentationSlat::
391 IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2)
392 {
393 //  Returns integration limits for current pad
394 //
395     
396     fCurrentSlat->IntegrationLimits(x1, x2, y1, y2);
397
398 }
399
400 void AliMUONSegmentationSlat::
401 Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10])
402 {
403 // Returns list of neighbours of pad with coordinates iX, iY
404
405     Int_t i, xListLocal[10], yListLocal[10], iXlocal, iYlocal, islat;
406     
407     SetSymmetry(iX);
408
409     GlobalToLocal(iX, iY, islat, iXlocal, iYlocal);
410  
411     Slat(islat)->Neighbours(iXlocal, iYlocal, Nlist, xListLocal, yListLocal);
412     
413     for (i=0; i<*Nlist; i++) LocalToGlobal(islat, xListLocal[i], yListLocal[i], Xlist[i], Ylist[i]);
414
415 }
416
417
418 Int_t  AliMUONSegmentationSlat::Ix()
419 {
420 // Return current pad coordinate ix during stepping
421     Int_t ixl,iyl,ix,iy;
422     ixl=fCurrentSlat->Ix();
423     iyl=fCurrentSlat->Iy();
424     
425     LocalToGlobal(fSlatIndex, ixl, iyl, ix, iy);
426     Int_t ixc, iyc, isc;
427     Float_t xc, yc;
428     GlobalToLocal(ix, iy, isc, ixc, iyc);
429     Slat(isc)->GetPadC(ixc,iyc,xc,yc);
430     return ix;
431 }
432
433
434 Int_t  AliMUONSegmentationSlat::Iy()
435 {
436 // Return current pad coordinate iy during stepping
437     Int_t ixl,iyl,ix,iy;
438     ixl=fCurrentSlat->Ix();
439     iyl=fCurrentSlat->Iy();
440     LocalToGlobal(fSlatIndex, ixl, iyl, ix, iy);
441     return iy;
442 }
443
444
445
446    // Signal Generation Condition during Stepping
447 Int_t AliMUONSegmentationSlat::SigGenCond(Float_t x, Float_t y, Float_t z)
448
449 //
450 //  True if signal generation condition fullfilled
451     Float_t xlocal, ylocal;
452     Int_t islat;
453     GlobalToLocal(x, y, z, islat, xlocal, ylocal);
454     return Slat(islat)->SigGenCond(xlocal, ylocal, z);
455 }
456
457 // Initialise signal generation at coord (x,y,z)
458 void  AliMUONSegmentationSlat::SigGenInit(Float_t x, Float_t y, Float_t z)
459 {
460 // Initialize the signal generation condition
461 //
462     Float_t xlocal, ylocal;
463     Int_t islat;
464
465     GlobalToLocal(x, y, z, islat, xlocal, ylocal);
466     Slat(islat)->SigGenInit(xlocal, ylocal, z);
467 }
468
469
470
471 void AliMUONSegmentationSlat::Init(Int_t chamber)
472 {
473 //    
474 // Initialize slat modules of quadrant +/+    
475 // The other three quadrants are handled through symmetry transformations
476 //
477   //printf("\n Initialise Segmentation Slat \n");
478 //
479
480 // Initialize Slat modules
481     Int_t islat, i;
482     Int_t ndiv[4];
483 // Pad division
484     for (i=0; i<4; i++) ndiv[i]=(*fNDiv)[i];
485 //
486     fDz=0.813;
487 // Slat height    
488     fSlatY=40.;
489     for (i=0; i<15; i++) fSlatX[i]=0.;
490     
491 // Initialize array of slats 
492     fSlats  = new TObjArray(fNSlats);
493 // Maximum number of strips (pads) in x and y
494     fNpy=0;   
495     fNpx=0;
496 // for each slat in the quadrant (+,+)    
497     for (islat=0; islat<fNSlats; islat++) {
498         fSlats->AddAt(CreateSlatModule(),islat);
499
500         AliMUONSegmentationSlatModule *slat =  Slat(islat);
501         // Configure Slat
502         slat->SetId(islat);
503         
504 // Foward pad size
505         slat->SetPadSize(fDpx, fDpy);
506 // Forward wire pitch
507         slat->SetDAnod(fWireD);
508 // Foward segmentation 
509         slat->SetPadDivision(ndiv);
510         slat->SetPcbBoards(fPcb[islat]);
511 // Initialize slat module
512         slat->Init(chamber);
513 // y-position of slat module relative to the first (closest to the beam)
514         fYPosition[islat]= fYPosOrigin+islat*(fSlatY-2.*fShift);
515 //
516         fNpy+=slat->Npy();
517         if (slat->Npx() > fNpx) fNpx=slat->Npx();
518         Int_t isec;
519         for (isec=0; isec< 4; isec++)
520         {
521             fSlatX[islat]+=40.*fPcb[islat][isec];
522         }
523         
524     }
525 // Set parent chamber number
526     AliMUON *pMUON  = (AliMUON *) gAlice->GetModule("MUON");
527     fChamber=&(pMUON->Chamber(chamber));
528     fId=chamber;
529 }
530
531
532
533
534
535 void AliMUONSegmentationSlat::SetNPCBperSector(Int_t *npcb)
536
537     //  PCB distribution for station 4 (6 rows with 1+3 segmentation regions)
538     for (Int_t islat=0; islat<fNSlats; islat++){ 
539         fPcb[islat][0] = *(npcb + 4 * islat);
540         fPcb[islat][1] = *(npcb + 4 * islat + 1);
541         fPcb[islat][2] = *(npcb + 4 * islat + 2);
542         fPcb[islat][3] = *(npcb + 4 * islat + 3);
543     }
544 }
545
546
547 void  AliMUONSegmentationSlat::SetSlatXPositions(Float_t *xpos)
548 {
549 // Set x-positions of Slats
550     for (Int_t islat=0; islat<fNSlats; islat++) fXPosition[islat]=xpos[islat];
551 }
552
553 AliMUONSegmentationSlatModule*  AliMUONSegmentationSlat::Slat(Int_t index) const
554 { return ((AliMUONSegmentationSlatModule*) (*fSlats)[index]);}
555
556
557 AliMUONSegmentationSlatModule* AliMUONSegmentationSlat::
558 CreateSlatModule()
559 {
560     // Factory method for slat module
561     return new AliMUONSegmentationSlatModule(4);
562 }
563
564
565 void AliMUONSegmentationSlat::Draw(const char* opt) const
566 {
567 // Draw method for event display
568 // 
569   if (!strcmp(opt,"eventdisplay")) { 
570     const int kColorMUON1 = kYellow;
571     const int kColorMUON2 = kBlue; 
572     //
573     //  Drawing Routines for example for Event Display
574     Int_t i,j;
575     Int_t npcb[15];
576     char nameChamber[9], nameSlat[9], nameNode[9];
577     
578     //
579     // Number of modules per slat
580     for (i=0; i<fNSlats; i++) {
581       npcb[i]=0;
582       for (j=0; j<4; j++) npcb[i]+=fPcb[i][j];
583     }  
584     //
585     TNode* top=gAlice->GetGeometry()->GetNode("alice");
586     sprintf(nameChamber,"C_MUON%d",fId+1);
587     new TBRIK(nameChamber,"Mother","void",340,340,5.);
588     top->cd();
589     sprintf(nameNode,"MUON%d",100+fId+1);
590     TNode* node = new TNode(nameNode,"Chambernode",nameChamber,0,0,fChamber->Z(),"");
591     
592     node->SetLineColor(kBlack);
593     AliMUON *pMUON  = (AliMUON *) gAlice->GetModule("MUON");
594     (pMUON->Nodes())->Add(node);
595     TNode* nodeSlat;
596     Int_t color;
597     
598     for (j=0; j<fNSlats; j++)
599       {
600         sprintf(nameSlat,"SLAT%d",100*fId+1+j);
601         Float_t dx = 20.*npcb[j];
602         Float_t dy = 20;
603         new TBRIK(nameSlat,"Slat Module","void",dx,20.,0.25);
604         node->cd();
605         color =  TMath::Even(j) ? kColorMUON1 : kColorMUON2;
606         
607         sprintf(nameNode,"SLAT%d",100*fId+1+j);
608         nodeSlat = 
609           new TNode(nameNode,"Slat Module",nameSlat, dx+fXPosition[j],fYPosition[j]+dy,0,"");
610         nodeSlat->SetLineColor(color);
611         node->cd();
612         sprintf(nameNode,"SLAT%d",100*fId+1+j+fNSlats);
613         nodeSlat = 
614           new TNode(nameNode,"Slat Module",nameSlat,-dx-fXPosition[j],fYPosition[j]+dy,0,"");
615         nodeSlat->SetLineColor(color);
616       }
617   }
618 }
619
620
621