]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPad.cxx
Added class to read reconstruction parameters from OCDB (Yuri)
[u/mrichter/AliRoot.git] / MUON / AliMUONPad.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 // $Id$
17
18 #include "AliMUONPad.h"
19
20 #include "AliLog.h"
21 #include "AliMpArea.h"
22
23 #include "Riostream.h"
24 #include "TVirtualPad.h"
25 #include "TVirtualX.h"
26 #include "TVector2.h"
27 #include "TMath.h"
28
29 /// \class AliMUONPad
30 ///
31 /// Object gathering information about a hit pad.
32 /// 
33 /// Can be seen as a combination of a Digit (which brings the charge) 
34 /// and an MpPad (which brings location and position)
35 ///
36 /// Also provided are some static functions to compute overlap and
37 /// get neighboring information.
38 ///
39 /// \author Laurent Aphecetche
40
41 /// \cond CLASSIMP
42 ClassImp(AliMUONPad)
43 /// \endcond
44
45 namespace
46 {
47   AliMpArea
48   Intersect(const AliMpArea& a, const AliMpArea& b)
49   { 
50     //
51     // Returns the common part of a and b.
52     //
53     Double_t xmin = TMath::Max(a.LeftBorder(),b.LeftBorder());
54     Double_t xmax = TMath::Min(a.RightBorder(),b.RightBorder());
55     Double_t ymin = TMath::Max(a.DownBorder(),b.DownBorder());
56     Double_t ymax = TMath::Min(a.UpBorder(),b.UpBorder());
57     AliMpArea c( TVector2( (xmin+xmax)/2.0, (ymin+ymax)/2.0 ),
58                  TVector2( (xmax-xmin)/2.0, (ymax-ymin)/2.0 ) );
59         
60     return c;
61   }
62 }
63
64 //_____________________________________________________________________________
65 AliMUONPad::AliMUONPad()
66 :
67 TObject(),
68 fIsSaturated(kFALSE),
69 fIsReal(kFALSE),
70 fClusterId(-1),
71 fCathode(-1),
72 fDetElemId(-1),
73 fDigitIndex(-1),
74 fIx(-1),
75 fIy(-1),
76 fStatus(0),
77 fDimensions(),
78 fPosition(),
79 fCharge(0.0),
80 fChargeBackup(0.0)
81 {
82   /// Default ctor
83   Init(-1,-1,-1,-1,TVector2(0,0),TVector2(0,0),0);
84 }
85
86 //_____________________________________________________________________________
87 AliMUONPad::AliMUONPad(Int_t detElemId, Int_t cathode,
88                        Int_t ix, Int_t iy, Double_t x, Double_t y,
89                        Double_t dx, Double_t dy, Double_t charge)
90 :
91 TObject(),
92 fIsSaturated(kFALSE),
93 fIsReal(kFALSE),
94 fClusterId(-1),
95 fCathode(-1),
96 fDetElemId(-1),
97 fDigitIndex(-1),
98 fIx(-1),
99 fIy(-1),
100 fStatus(0),
101 fDimensions(),
102 fPosition(),
103 fCharge(0.0),
104 fChargeBackup(0.0)
105
106 {
107   /// Normal ctor, using full information
108   Init(detElemId,cathode,ix,iy,TVector2(x,y),TVector2(dx,dy),charge);
109 }
110
111 //_____________________________________________________________________________
112 AliMUONPad::AliMUONPad(Double_t x, Double_t y,
113                        Double_t dx, Double_t dy, Double_t charge)
114 : TObject(),
115 fIsSaturated(kFALSE),
116 fIsReal(kFALSE),
117 fClusterId(-1),
118 fCathode(-1),
119 fDetElemId(-1),
120 fDigitIndex(-1),
121 fIx(-1),
122 fIy(-1),
123 fStatus(0),
124 fDimensions(),
125 fPosition(),
126 fCharge(0.0),
127 fChargeBackup(0.0)
128 {
129   /// Truncated constructor (w/o DE, cath, ix, iy)
130   Init(-1,-1,-1,-1,TVector2(x,y),TVector2(dx,dy),charge);
131 }
132
133 //_____________________________________________________________________________
134 AliMUONPad::AliMUONPad(const TVector2& position, const TVector2& dimensions,
135                        Double_t charge)
136 : TObject(),
137 fIsSaturated(kFALSE),
138 fIsReal(kFALSE),
139 fClusterId(-1),
140 fCathode(-1),
141 fDetElemId(-1),
142 fDigitIndex(-1),
143 fIx(-1),
144 fIy(-1),
145 fStatus(0),
146 fDimensions(),
147 fPosition(),
148 fCharge(0.0),
149 fChargeBackup(0.0)
150 {
151   /// Alternate ctor
152   Init(-1,-1,-1,-1,position,dimensions,charge);
153 }
154
155 //_____________________________________________________________________________
156 AliMUONPad::~AliMUONPad()
157 {
158 /// Dtor
159 }
160
161 //_____________________________________________________________________________
162 Bool_t 
163 AliMUONPad::AreNeighbours(const AliMUONPad& d1, const AliMUONPad& d2) 
164 {
165   /// Whether 2 pads are neighbours or not
166   if ( d1.DetElemId() != d2.DetElemId() || 
167        d1.Cathode() != d2.Cathode() )
168   {
169     return kFALSE;
170   }
171   else
172   {
173     static Double_t precision = 1E-4; // cm
174     static TVector2 precisionAdjustment(-precision,-precision);    
175     return AreOverlapping(d1,d2,precisionAdjustment);
176   }
177 }
178
179 //_____________________________________________________________________________
180 Bool_t
181 AliMUONPad::AreOverlapping(const AliMUONPad& d1, const AliMUONPad& d2,
182                            const TVector2& precision)
183 {
184   /// Checks the overlap between 2 pads.
185   /// The actual overlap is computed not on d1 and d2, but on d1 and d2
186   /// "re-scaled" using the precision vector (conceptually equivalent to 
187   /// d.Dimensions() += precision)
188   ///
189   /// So, if the elements (x,y) of precision are :
190   ///
191   /// - positive, the overlap is "computed" from smaller d1 and d2  
192   ///   which is, modulo the precision, what you would think as a normal
193   ///   overlap calculation
194   /// - negative, overlap is from "bigger" d1 and d2, which is usefull to "tweek"
195   ///   what we call an overlap, e.g. to consider 2 pads touching only by their
196   ///   corners to be overlapping.
197   
198   AliMpArea a1(d1.Position(),d1.Dimensions());
199   AliMpArea a2(d2.Position(),d2.Dimensions());
200   
201   if ( a1.LeftBorder() > a2.RightBorder() - precision.X() ||
202        a1.RightBorder() < a2.LeftBorder() + precision.X() )
203   {
204     return kFALSE;
205   }
206   
207   if ( a1.DownBorder() > a2.UpBorder() - precision.Y() ||
208        a1.UpBorder() < a2.DownBorder() + precision.Y() )
209   {
210     return kFALSE;
211   }
212   return kTRUE;
213 }
214
215 //_____________________________________________________________________________
216 Bool_t
217 AliMUONPad::AreOverlapping(const AliMUONPad& d1, const AliMUONPad& d2,
218                            const TVector2& precision,
219                            AliMpArea& overlapRegion) 
220 {
221   /// Checks the overlap between 2 pads, and returns the overlap area
222   /// 
223   /// See comments on the other AreOverlapping method, too : in this
224   /// method, the overlapRegion does *not* depend on the precision parameter,
225   /// which is only used to decide whether the pads are overlapping, while
226   /// the actual overlap region is computed w/o reference to precision.
227   ///
228   if ( AreOverlapping(d1,d2,precision) )
229   {
230     overlapRegion = Overlap(d1,d2);
231     if ( !overlapRegion.IsValid() )
232     {
233       cerr << "Something is wrong : the 2 pads below are flagged as overlapping"
234       << ", but the overlapRegion is not valid"
235       << endl;
236       d1.Print("corners");
237       d2.Print("corners");
238     }
239     return kTRUE;
240   }
241   return kFALSE;
242 }
243
244 //_____________________________________________________________________________
245 Int_t 
246 AliMUONPad::Compare(const TObject* obj) const
247 {
248   /// Compare 2 pads. 
249   /// Ordering is as complete as possible.
250   
251   const AliMUONPad* pad = static_cast<const AliMUONPad*>(obj);
252     
253   if ( DetElemId() > pad->DetElemId() )
254   {
255     return 1;
256   }
257   else if ( DetElemId() > pad->DetElemId() )
258   {
259     return 1;
260   }
261   else
262   {
263     // same DetElemId...
264     if ( Cathode() > pad->Cathode() )
265     {
266       return 1;
267     }
268     else if ( Cathode() < pad->Cathode() ) 
269     {
270       return -1;
271     }
272     else
273     {
274       // same cathode...
275       if ( Ix() > pad->Ix() )
276       {
277         return 1;
278       }
279       else if ( Ix() < pad->Ix() ) 
280       {
281         return -1;
282       }
283       else
284       {
285         // same ix....
286         if ( Iy() > pad->Iy() )
287         {
288           return 1;
289         }
290         else if ( Iy() < pad->Iy() ) 
291         {
292           return -1;
293         }
294         else
295         {
296           // same iy....
297           if ( X() > pad->X() )
298           {
299             return 1;
300           }
301           else if ( X() < pad->X() )
302           {
303             return -1;
304           }
305           else
306           {
307             // same X
308             if ( Y() > pad->Y() )
309             {
310               return 1;
311             }
312             else if ( Y() < pad->Y() )
313             {
314               return -1;
315             }
316             else
317             {
318               // same Y
319               return ( Charge() < pad->Charge() ) ? -1:1;              
320             }            
321           }          
322         }        
323       }
324     }
325   }
326 }
327
328 //_____________________________________________________________________________
329 Double_t
330 AliMUONPad::Coord(Int_t ixy) const
331 {
332   /// To be friendly and backward compatible with AZ code, which 
333   /// used that kind of coordinate accessing.
334   
335   if ( ixy == 0 ) 
336   {
337     return X();
338   }
339   else if ( ixy == 1 )
340   {
341     return Y();
342   }
343   AliError(Form("Incorrect coordinates index %d (only 0,1 are valid)",ixy));
344   return 0;
345 }
346
347 //_____________________________________________________________________________
348 void 
349 AliMUONPad::Init(Int_t detElemId, Int_t cathode,
350                  Int_t ix, Int_t iy,
351                  const TVector2& position,
352                  const TVector2& dimensions,
353                  Double_t charge)
354 {
355   /// Called by all the ctors
356   fIsSaturated = kFALSE;
357   fIsReal = kTRUE;
358   fDetElemId = detElemId;
359   fCathode = cathode;
360   fIx = ix;
361   fIy = iy;
362   fPosition = position;
363   fDimensions = dimensions;
364   fCharge = charge;
365   fChargeBackup = fCharge;
366   
367   fClusterId = -1;
368   fDigitIndex = -1;
369
370   fStatus = 0;
371 }
372
373 //_____________________________________________________________________________
374 AliMpArea
375 AliMUONPad::Overlap(const AliMUONPad& d1, const AliMUONPad& d2)
376 {  
377   /// Return the overlap region between two pads
378   AliMpArea a1(d1.Position(),d1.Dimensions());
379   AliMpArea a2(d2.Position(),d2.Dimensions());
380   return Intersect(a1,a2);
381 }
382
383
384 //_____________________________________________________________________________
385 void
386 AliMUONPad::Paint(Option_t*)
387 {
388   /// Paint pad on screen
389   TVector2 ll = Position() - Dimensions();
390   TVector2 ur = Position() + Dimensions();
391
392   gPad->PaintBox(ll.X(),ll.Y(),ur.X(),ur.Y());
393 }
394
395 //_____________________________________________________________________________
396 void
397 AliMUONPad::Print(Option_t* opt) const
398 {
399   /// Printout
400   TString sopt(opt);
401   sopt.ToLower();
402   
403   ios_base::fmtflags oldflags = cout.flags();
404   if ( Cathode() >= 0 )
405   {
406     cout << "DetEle " << setw(5) << DetElemId()
407     << " Cath " << setw(2) << Cathode()
408     << " (Ix,Iy)=(" << setw(3) << Ix() << "," << setw(3) << Iy() << ") ";
409   }
410   cout.setf(ios::fixed);
411   cout.precision(6);
412   cout << " (x,y)=(" << setw(9) << X() << "," << setw(9) << Y() << ") "
413   << " (dx,dy)=(" << setw(9) << DX() << "," << setw(9) << DY() << ") "
414   << " Charge=";
415   cout.precision(2);
416   cout << setw(7) << Charge();
417   if ( sopt.Contains("full") )
418   {
419     cout 
420     << " Used=" << (IsUsed()?Form("YES (ClusterId %d)",fClusterId):"NO")
421     << (IsSaturated()?"(S)":"   ")
422     << (IsReal()?"   ":"(V)")
423     << " Status=" << setw(4) << Status()
424     << " ChargeBackup=" << ChargeBackup();
425   }
426   if ( sopt.Contains("corners") )
427   {
428     cout << Form(" (xmin,xmax)=(%e,%e) (ymin,ymax)=(%e,%e)",
429                  X()-DX(),X()+DX(),
430                  Y()-DY(),Y()+DY()) << endl;
431   }
432   cout << endl;
433   cout.flags(oldflags);
434 }
435
436 //_____________________________________________________________________________
437 void 
438 AliMUONPad::SetCoord(Int_t ixy, Double_t coord)
439 {
440   /// Set the pad coordinate (ixy=0 means x, ixy=1 means y)
441   if ( ixy == 0 ) 
442   {
443     fPosition.Set(coord,Y());
444   }
445   else if ( ixy == 1 )
446   {
447     fPosition.Set(X(),coord);
448   }
449   else
450   {
451     AliError(Form("Incorrect coordinates index %d (only 0,1 are valid)",ixy));
452   }
453 }
454
455 //_____________________________________________________________________________
456 void 
457 AliMUONPad::SetSize(Int_t ixy, Double_t size)
458 {
459   /// Set the pad half size (ixy=0 means x half size, ixy=1 means y half size)
460   if ( ixy == 0 ) 
461   {
462     fDimensions.Set(size,DY());
463   }
464   else if ( ixy == 1 )
465   {
466     fDimensions.Set(DX(),size);
467   }
468   else
469   {
470     AliError(Form("Incorrect coordinates index %d (only 0,1 are valid)",ixy));
471   }
472 }
473
474 //_____________________________________________________________________________
475 void 
476 AliMUONPad::Shift(Int_t ixy, Double_t shift)
477 {
478   /// Shift the position by "shift"
479   SetCoord(ixy,Coord(ixy)+shift);
480 }
481
482 //_____________________________________________________________________________
483 Double_t
484 AliMUONPad::Size(Int_t ixy) const
485 {
486   /// Returns the half size along a direction, given by ixy
487   /// (see SetSize for ixy meaning)
488   
489   if ( ixy == 0 ) 
490   {
491     return DX();
492   }
493   else if ( ixy == 1 )
494   {
495     return DY();
496   }
497   AliError(Form("Incorrect coordinates index %d (only 0,1 are valid)",ixy));
498   return 0;
499 }