LCOV - code coverage report
Current view: top level - MUON/MUONrec - AliMUONPad.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 94 217 43.3 %
Date: 2016-06-14 17:26:59 Functions: 17 26 65.4 %

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

Generated by: LCOV version 1.11