From Laurent:
[u/mrichter/AliRoot.git] / MUON / AliMUONGeometrySegmentation.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 // Class AliMUONGeometrySegmentation
18 // -------------------------------
19 // New class for the module segmentation 
20 // composed of the segmentations of detection elements.
21 // Applies transformations defined in geometry.
22 //
23 // Author:Ivana Hrivnacova, IPN Orsay
24
25 /* $Id$ */
26
27 #include <Riostream.h>
28 #include "TClass.h"
29
30 #include "AliLog.h"
31
32 #include "AliMUONGeometrySegmentation.h"
33 #include "AliMUONVGeometryDESegmentation.h"
34 #include "AliMUONGeometryModule.h"
35 #include "AliMUONGeometryDetElement.h"
36 #include "AliMUONGeometryStore.h"
37 #include "AliMUONSegmentManuIndex.h"
38
39 ClassImp(AliMUONGeometrySegmentation)
40
41 //______________________________________________________________________________
42 AliMUONGeometrySegmentation::AliMUONGeometrySegmentation(
43                                   AliMUONGeometryModule* geometry) 
44 : TObject(),
45   fCurrentDetElemId(0),
46   fCurrentDetElement(0),
47   fCurrentSegmentation(0),
48   fGeometryModule(geometry),
49   fDESegmentations(0)
50   
51 {
52 // Normal constructor
53
54   fDESegmentations 
55     = new AliMUONGeometryStore(geometry->GetDEIndexing(), false);
56 }
57
58 //______________________________________________________________________________
59 AliMUONGeometrySegmentation::AliMUONGeometrySegmentation() 
60 : TObject(),
61   fCurrentDetElemId(0),
62   fCurrentDetElement(0),
63   fCurrentSegmentation(0),
64   fGeometryModule(0),
65   fDESegmentations(0)
66 {
67 // Default Constructor
68 }
69
70 //______________________________________________________________________________
71 AliMUONGeometrySegmentation::AliMUONGeometrySegmentation(
72                                   const AliMUONGeometrySegmentation& rhs) 
73   : TObject(rhs)
74 {
75 // Copy constructor
76   AliFatal("Copy constructor is not implemented.");
77 }
78
79 //______________________________________________________________________________
80 AliMUONGeometrySegmentation::~AliMUONGeometrySegmentation() {
81 // Destructor
82
83   delete fDESegmentations;
84
85
86 //
87 // operators
88 //
89
90 //______________________________________________________________________________
91 AliMUONGeometrySegmentation& 
92 AliMUONGeometrySegmentation::operator=(const AliMUONGeometrySegmentation& rhs)
93 {
94 // Copy operator 
95
96   // check assignement to self
97   if (this == &rhs) return *this;
98
99   AliFatal("Assignment operator is not implemented.");
100     
101   return *this;  
102 }
103
104 //
105 // private methods
106 //
107
108 //______________________________________________________________________________
109 Bool_t AliMUONGeometrySegmentation::OwnNotify(Int_t detElemId) const
110 {
111 // Updates current detection element and segmentation,
112 // and checks if they exist.
113 // Returns true if success.
114 // ---
115
116   if (detElemId != fCurrentDetElemId) {
117
118     // Find detection element and its segmentation
119     AliMUONGeometryDetElement* detElement
120       = fGeometryModule->GetDetElement(detElemId);
121     if (!detElement) {
122       AliError(Form("Detection element %d not defined", detElemId));
123       return false;
124     }     
125
126     AliMUONVGeometryDESegmentation* segmentation 
127       = (AliMUONVGeometryDESegmentation*) fDESegmentations->Get(detElemId);
128     if (!segmentation) {
129       AliError(Form("Segmentation for detection element %d not defined",
130                      detElemId));
131       return false;                  
132     }
133   
134     fCurrentDetElemId = detElemId;
135     fCurrentDetElement = detElement;
136     fCurrentSegmentation = segmentation;
137   }  
138  
139   return true;
140 }         
141
142 //
143 // public methods
144 //
145
146 //______________________________________________________________________________
147 void AliMUONGeometrySegmentation::Add(Int_t detElemId, 
148                                       AliMUONVGeometryDESegmentation* segmentation)
149 {
150 // Add detection element segmentation
151 // ---
152
153   fDESegmentations->Add(detElemId, segmentation); 
154 }  
155
156
157 //______________________________________________________________________________
158 const AliMUONVGeometryDESegmentation* 
159 AliMUONGeometrySegmentation::GetDESegmentation(Int_t detElemId) const
160 {
161 // Return the DE segmentation 
162
163   if (!OwnNotify(detElemId)) return 0;
164
165   return fCurrentSegmentation;
166 }
167
168 //______________________________________________________________________________
169 AliMUONGeometryDirection 
170 AliMUONGeometrySegmentation::GetDirection(Int_t detElemId) const
171 {
172 // Return direction with a constant pad size 
173 // (Direction or coordinate where the resolution is the best)
174
175   if (!OwnNotify(detElemId)) return kDirUndefined;
176
177   return fCurrentSegmentation->GetDirection();
178 }
179
180 //______________________________________________________________________________
181 void AliMUONGeometrySegmentation::Print(Option_t* opt) const
182 {
183 // Print DE segmentations
184
185   std::cout << "fDESegmentations (class " 
186             << fDESegmentations->Class()->GetName() << ") entries=" 
187             << fDESegmentations->GetNofEntries() 
188             << std::endl;
189   fDESegmentations->Print(opt); 
190 }
191
192 //______________________________________________________________________________
193 void AliMUONGeometrySegmentation::SetPadSize(Float_t p1, Float_t p2)
194 {
195 // Set pad size Dx*Dy to all detection element segmentations 
196 // ---
197
198   for (Int_t i=0; i<fDESegmentations->GetNofEntries(); i++) {
199      AliMUONVGeometryDESegmentation* segmentation
200        = (AliMUONVGeometryDESegmentation*)fDESegmentations->GetEntry(i);
201      segmentation->SetPadSize(p1, p2);
202   }   
203 }
204
205 //______________________________________________________________________________
206 void AliMUONGeometrySegmentation::SetDAnod(Float_t d)
207 {
208 // Set anod pitch to all detection element segmentations
209 // ---
210
211   for (Int_t i=0; i<fDESegmentations->GetNofEntries(); i++) {
212      AliMUONVGeometryDESegmentation* segmentation
213        = (AliMUONVGeometryDESegmentation*)fDESegmentations->GetEntry(i);
214      segmentation->SetDAnod(d);
215   }   
216 }
217
218 //______________________________________________________________________________
219 Float_t AliMUONGeometrySegmentation::GetAnod(Int_t detElemId, Float_t xhit) const
220 {
221 // Anod wire coordinate closest to xhit
222 // Returns for a hit position xhit the position of the nearest anode wire
223 // !!! xhit is understand a a distance, not as a position in the space
224 // CHECK
225 // ---
226
227   if (!OwnNotify(detElemId)) return 0;
228
229   return fCurrentSegmentation->GetAnod(xhit);
230 }
231
232 //______________________________________________________________________________
233 Bool_t  AliMUONGeometrySegmentation::GetPadI(Int_t detElemId,
234                                         Float_t xg, Float_t yg, Float_t zg, 
235                                         Int_t& ix, Int_t& iy)
236 {                                       
237 //  Returns pad coordinates (ix,iy) for given real coordinates (x,y)
238 // ---
239
240   if (!OwnNotify(detElemId)) return false;
241   
242   Float_t xl, yl, zl;
243   fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl); 
244
245   if (!fCurrentSegmentation->HasPad(xl, yl, zl)) return false;
246
247   fCurrentSegmentation->GetPadI(xl, yl, zl, ix, iy);
248   return true;
249 }
250
251 //______________________________________________________________________________
252 Bool_t
253 AliMUONGeometrySegmentation::HasPad(Int_t detElemId, Int_t ix, Int_t iy)
254 {
255 // Tells if a given pad exists in a given detector element
256
257         if (!OwnNotify(detElemId)       ) return false;
258         
259         return fCurrentSegmentation->HasPad(ix,iy);
260 }
261                                     
262 //______________________________________________________________________________
263 Bool_t  AliMUONGeometrySegmentation::GetPadC(Int_t detElemId,
264                                         Int_t ix, Int_t iy, 
265                                         Float_t& xg, Float_t& yg, Float_t& zg)
266 {                                       
267 // Transform from pad to real coordinates
268 // ---
269
270   if (!OwnNotify(detElemId)) return false;
271
272   if (!fCurrentSegmentation->HasPad(ix, iy)) return false;
273
274   Float_t xl, yl, zl;
275   fCurrentSegmentation->GetPadC(ix, iy, xl , yl, zl);
276
277   fGeometryModule->Local2Global(detElemId, xl, yl, zl, xg, yg, zg); 
278   return true;
279 }
280
281 //______________________________________________________________________________
282 Bool_t  AliMUONGeometrySegmentation::GetPadE(Int_t detElemId,
283                                         Int_t &ix, Int_t &iy, 
284                                         AliMUONSegmentManuIndex* connect)
285 {
286 // Get pads for a given electronic connection
287 // ---
288
289   if (!OwnNotify(detElemId)) return false;
290
291   if (!fCurrentSegmentation->HasPad(ix, iy)) return false;
292
293   fCurrentSegmentation->GetPadE(ix, iy, connect);
294   return true;
295 }
296
297 //______________________________________________________________________________
298 AliMUONSegmentManuIndex* AliMUONGeometrySegmentation:: GetMpConnection(Int_t detElemId,
299                                                                Int_t ix, Int_t iy)
300 {                                       
301 // Get electronic connection for given pads
302 // ---
303
304   if (!OwnNotify(detElemId)) return 0x0;
305
306   AliMUONSegmentManuIndex* connect;
307
308   connect = fCurrentSegmentation->GetMpConnection(ix, iy);
309   if (connect == 0x0) return 0x0;
310
311   Int_t busPatchId = connect->GetBusPatchId(); 
312
313   Int_t dBusPatch = 0;
314   // not very clean way, to be changed (Ch.F.)
315
316   if (detElemId/100 > 4 && detElemId/100 < 11) 
317     dBusPatch = 4; 
318   else if (detElemId/100 < 5) 
319     dBusPatch = 25; 
320
321   if (detElemId % 100 < 50)
322     busPatchId+= (detElemId/100 - 1)*100 + (detElemId % 100)*dBusPatch;
323   else 
324     busPatchId+= (detElemId/100 - 1)*100 + ((detElemId-50) % 100)*dBusPatch + 50;
325
326   connect->SetBusPatchId(busPatchId); 
327   return connect;
328 }
329
330
331 //______________________________________________________________________________
332 void AliMUONGeometrySegmentation::Init(Int_t chamber)
333 {
334 // Initialize segmentation.
335 // Check that all detection elements have segmanetation set
336 // ---
337
338   // Loop over detection elements
339   AliMUONGeometryStore* detElements = fGeometryModule->GetDetElementStore();
340
341   for (Int_t i=0; i<detElements->GetNofEntries(); i++) {
342
343     // Get detction element Id
344     Int_t detElemId = detElements->GetEntry(i)->GetUniqueID();
345
346     // Check segmentation
347     if (! fDESegmentations->Get(detElemId) ) {
348       AliError(Form("Detection element %d has not a segmentation set.",
349                detElements->GetEntry(i)->GetUniqueID()));
350     }
351     else {              
352       // Initialize DE Segmentation
353       ((AliSegmentation*)fDESegmentations->Get(detElemId))->Init(chamber);
354     }          
355   }                
356 }
357  
358 //______________________________________________________________________________
359 Float_t AliMUONGeometrySegmentation::Dpx(Int_t detElemId) const
360 {
361 // Get pad size in x
362 // ---
363
364   if (!OwnNotify(detElemId)) return 0.;
365   
366   return fCurrentSegmentation->Dpx();
367 }
368
369 //______________________________________________________________________________
370 Float_t AliMUONGeometrySegmentation::Dpy(Int_t detElemId) const
371 {
372 // Get pad size in y
373 // ---
374
375   if (!OwnNotify(detElemId)) return 0.;
376
377   return fCurrentSegmentation->Dpy();
378 }
379  
380 //______________________________________________________________________________
381 Float_t AliMUONGeometrySegmentation::Dpx(Int_t detElemId, Int_t isector) const
382 {
383 // Pad size in x by sector
384 // ---
385
386   if (!OwnNotify(detElemId)) return 0.;
387
388   return fCurrentSegmentation->Dpx(isector);
389
390
391 //______________________________________________________________________________
392 Float_t AliMUONGeometrySegmentation::Dpy(Int_t detElemId, Int_t isector) const
393 {
394 // Pad size in x, y by Sector 
395 // ---
396
397   if (!OwnNotify(detElemId)) return 0.;
398
399   return fCurrentSegmentation->Dpy(isector);
400 }
401
402 //______________________________________________________________________________
403 Int_t AliMUONGeometrySegmentation::Npx(Int_t detElemId) const
404 {
405 // Maximum number of Pads in x
406 // ---
407
408   if (!OwnNotify(detElemId)) return 0;
409
410   return fCurrentSegmentation->Npx();
411 }
412
413 //______________________________________________________________________________
414 Int_t AliMUONGeometrySegmentation::Npy(Int_t detElemId) const
415 {
416 // Maximum number of Pads in y
417 // ---
418
419   if (!OwnNotify(detElemId)) return 0;
420
421   return fCurrentSegmentation->Npy();
422 }
423
424 //______________________________________________________________________________
425 void  AliMUONGeometrySegmentation::SetPad(Int_t detElemId, Int_t ix, Int_t iy)
426 {
427 // Set pad position.
428 // Sets virtual pad coordinates, needed for evaluating pad response 
429 // outside the tracking program.
430 // From AliMUONGeometrySegmentationV01.
431 // ---
432
433   if (!OwnNotify(detElemId)) return;
434
435   fCurrentSegmentation->SetPad(ix, iy);
436 }
437
438 //______________________________________________________________________________
439 void  AliMUONGeometrySegmentation::SetHit(Int_t detElemId, 
440                                         Float_t xghit, Float_t yghit, Float_t zghit)
441 {
442 // Set hit position
443 // Sets virtual hit position, needed for evaluating pad response 
444 // outside the tracking program 
445 // From AliMUONGeometrySegmentationV01.
446
447   if (!OwnNotify(detElemId)) return;
448
449   Float_t xl, yl, zl;
450   fCurrentDetElement->Global2Local(xghit, yghit, zghit, xl, yl, zl); 
451
452   fCurrentSegmentation->SetHit(xl, yl, zl);
453 }
454     
455 //______________________________________________________________________________
456 void  AliMUONGeometrySegmentation::FirstPad(Int_t detElemId,
457                                         Float_t xghit, Float_t yghit, Float_t zghit, 
458                                         Float_t dx, Float_t dy) 
459 {                                        
460 // Iterate over pads - initialiser
461 // ---
462
463   if (!OwnNotify(detElemId)) return;
464
465   Float_t xl, yl, zl;
466   fCurrentDetElement->Global2Local(xghit, yghit, zghit, xl, yl, zl); 
467
468   fCurrentSegmentation->FirstPad(xl, yl, zl, dx, dy);
469 }
470  
471 //______________________________________________________________________________
472 void  AliMUONGeometrySegmentation::NextPad(Int_t detElemId)
473 {
474 // Iterate over pads - stepper
475 // ---
476
477   if (!OwnNotify(detElemId)) return;
478   
479   fCurrentSegmentation->NextPad();
480 }
481
482 //______________________________________________________________________________
483 Int_t AliMUONGeometrySegmentation::MorePads(Int_t detElemId)
484 {
485 // Iterate over pads - condition
486 // ---
487
488   if (!OwnNotify(detElemId)) return 0;
489   
490   return fCurrentSegmentation->MorePads();
491 }
492
493 //______________________________________________________________________________
494 Float_t AliMUONGeometrySegmentation::Distance2AndOffset(Int_t detElemId,
495                                            Int_t ix, Int_t iy, 
496                                            Float_t xg, Float_t yg,  Float_t zg,
497                                            Int_t* dummy)
498 {                                          
499 // Returns the square of the distance between 1 pad
500 // labelled by its channel numbers and a coordinate
501 // ---
502
503   if (!OwnNotify(detElemId)) return 0.;
504
505   Float_t xl, yl, zl;
506   fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl); 
507
508   return fCurrentSegmentation->Distance2AndOffset(ix, iy, xl, yl, dummy);
509 }
510
511 //______________________________________________________________________________
512 void AliMUONGeometrySegmentation::GetNParallelAndOffset(Int_t detElemId,
513                                             Int_t ix, Int_t iy,
514                                             Int_t* nparallel, Int_t* offset)
515 {                                          
516 // Number of pads read in parallel and offset to add to x 
517 // (specific to LYON, but mandatory for display)
518 // CHECK
519 // ---
520
521   if (!OwnNotify(detElemId)) return;
522
523   fCurrentSegmentation->GetNParallelAndOffset(ix, iy, nparallel, offset);  
524 }
525
526
527 //______________________________________________________________________________
528 void AliMUONGeometrySegmentation::Neighbours(Int_t detElemId,
529                                            Int_t ix, Int_t iy, 
530                                            Int_t* nlist, 
531                                            Int_t xlist[10], Int_t ylist[10])
532 {                                         
533 // Get next neighbours 
534 // ---
535
536   if (!OwnNotify(detElemId)) return;
537
538   fCurrentSegmentation->Neighbours(ix, iy, nlist, xlist, ylist);
539 }
540
541 //______________________________________________________________________________
542 Int_t  AliMUONGeometrySegmentation::Ix()
543 {
544 // Current pad cursor during disintegration
545 // x, y-coordinate
546 // ---
547
548   return fCurrentSegmentation->Ix();
549 }
550
551 //______________________________________________________________________________
552 Int_t  AliMUONGeometrySegmentation::Iy()
553 {
554 // Current pad cursor during disintegration
555 // x, y-coordinate
556 // ---
557
558   return fCurrentSegmentation->Iy();
559 }
560
561 //______________________________________________________________________________
562 Int_t  AliMUONGeometrySegmentation::DetElemId()
563 {
564 // Current pad cursor during disintegration
565 // x, y-coordinate
566 // ---
567
568   return fCurrentDetElemId;
569 }
570
571 //______________________________________________________________________________
572 Int_t  AliMUONGeometrySegmentation::ISector()
573 {
574 // Current sector
575 // ---
576
577   return fCurrentSegmentation->ISector();
578 }
579
580 //______________________________________________________________________________
581 Int_t AliMUONGeometrySegmentation::Sector(Int_t detElemId, Int_t ix, Int_t iy)
582 {
583 // Calculate sector from pad coordinates
584 // ---
585
586   if (!OwnNotify(detElemId)) return 0;
587
588   return fCurrentSegmentation->Sector(ix, iy);
589 }
590
591 //______________________________________________________________________________
592 Int_t AliMUONGeometrySegmentation::Sector(Int_t detElemId,
593                                         Float_t xg, Float_t yg, Float_t zg)
594 {
595 // Calculate sector from pad coordinates
596 // ---
597
598   if (!OwnNotify(detElemId)) return 0;
599
600   Float_t xl, yl, zl;
601   fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl); 
602
603   return fCurrentSegmentation->Sector(xl, yl);
604 }
605
606 //______________________________________________________________________________
607 void  AliMUONGeometrySegmentation::IntegrationLimits(Int_t detElemId,
608                                         Float_t& x1, Float_t& x2,
609                                         Float_t& y1, Float_t& y2)
610 {                                                 
611 // Current integration limits 
612 // ---
613  
614   if (!OwnNotify(detElemId)) return;
615
616   fCurrentSegmentation->IntegrationLimits(x1, x2, y1, y2);
617 }
618
619 //______________________________________________________________________________
620 Int_t AliMUONGeometrySegmentation::SigGenCond(Int_t detElemId,
621                                         Float_t xg, Float_t yg, Float_t zg)
622 {
623 // Signal Generation Condition during Stepping
624 //  0: don't generate signal
625 //  1: generate signal 
626 //  Comments: 
627 //
628 //  Crossing of pad boundary and mid plane between neighbouring wires is checked.
629 //  To correctly simulate the dependence of the spatial resolution on the angle 
630 //  of incidence signal must be generated for constant steps on 
631 //  the projection of the trajectory along the anode wire.
632 //
633 //  Signal will be generated if particle crosses pad boundary or
634 //  boundary between two wires. 
635 // ---
636
637   if (!OwnNotify(detElemId)) return 0;
638
639   Float_t xl, yl, zl;
640   fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl); 
641
642   return fCurrentSegmentation->SigGenCond(xl, yl, zl);
643  }
644
645 //______________________________________________________________________________
646 void  AliMUONGeometrySegmentation::SigGenInit(Int_t detElemId,
647                                        Float_t xg, Float_t yg, Float_t zg)
648 {
649 // Initialise signal generation at coord (x,y,z)
650 // Initialises pad and wire position during stepping.
651 // From AliMUONGeometrySegmentationV01
652 // ---
653
654   if (!OwnNotify(detElemId)) return;
655
656   Float_t xl, yl, zl;
657   fCurrentDetElement->Global2Local(xg, yg, zg, xl, yl, zl); 
658
659   if (!fCurrentSegmentation->HasPad(xl, yl, zl)) {
660     AliWarningStream()
661          << "No pad at " << detElemId 
662          << " global position: " << xg << "  " << yg << "  " << zg
663          << " local position: " << xl << "  " << yl << "  " << zl << endl;
664     return ;
665   }  
666
667   fCurrentSegmentation->SigGenInit(xl, yl, zl);
668 }                   
669     
670 //______________________________________________________________________________
671 void AliMUONGeometrySegmentation::GiveTestPoints(Int_t /*detElemId*/,
672                                        Int_t& /*n*/, 
673                                        Float_t* /*xg*/, Float_t* /*yg*/) const
674 {                                             
675 // Test points for auto calibration
676 // Returns test point on the pad plane.
677 // Used during determination of the segmoid correction of the COG-method
678 // From AliMUONGeometrySegmentationV01
679 // ---
680
681   // Requires change of interface
682   // to convert points from local to global we need z coordinate
683   AliError("Not implemented.");
684 }
685
686 //______________________________________________________________________________
687 void AliMUONGeometrySegmentation::Draw(const char* opt)
688 {
689 // Draws the segmentation zones for all detElemId 
690 // ---
691
692   for (Int_t i=0; i<fDESegmentations->GetNofEntries(); i++) {
693      AliMUONVGeometryDESegmentation* segmentation
694        = (AliMUONVGeometryDESegmentation*)fDESegmentations->GetEntry(i);
695      segmentation->Draw(opt);
696   }   
697 }
698
699 //______________________________________________________________________________
700 void AliMUONGeometrySegmentation::Draw(Int_t detElemId, const char* opt)
701 {
702 // Draw the segmentation zones for a given detElemId.
703 // ---
704
705   if (!OwnNotify(detElemId)) return;
706
707   fCurrentSegmentation->Draw(opt);
708 }
709
710 //______________________________________________________________________________
711 void AliMUONGeometrySegmentation::SetCorrFunc(Int_t detElemId, 
712                                               Int_t isec, TF1* func)
713 {
714 // Set the correction function.
715 // From AliMUONGeometrySegmentationV01
716 // ---
717
718   if (!OwnNotify(detElemId)) return;
719
720   fCurrentSegmentation->SetCorrFunc(isec, func);
721 }
722
723 //______________________________________________________________________________
724 TF1* AliMUONGeometrySegmentation::CorrFunc(Int_t detElemId, Int_t isec) const
725 {
726 // Get the correction Function.
727 // From AliMUONGeometrySegmentationV01
728 // ---
729
730   if (!OwnNotify(detElemId)) return 0;
731
732   return  fCurrentSegmentation->CorrFunc(isec);
733
734