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