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