#include "AliMUONPad.h"
#include "AliLog.h"
#include "AliMpArea.h"
#include "Riostream.h"
#include "TVirtualPad.h"
#include "TVirtualX.h"
#include "TVector2.h"
#include "TMath.h"
using std::setw;
using std::cout;
using std::endl;
using std::ios_base;
using std::cerr;
using std::ios;
ClassImp(AliMUONPad)
namespace
{
AliMpArea
Intersect(const AliMpArea& a, const AliMpArea& b)
{
Double_t xmin = TMath::Max(a.LeftBorder(),b.LeftBorder());
Double_t xmax = TMath::Min(a.RightBorder(),b.RightBorder());
Double_t ymin = TMath::Max(a.DownBorder(),b.DownBorder());
Double_t ymax = TMath::Min(a.UpBorder(),b.UpBorder());
AliMpArea c( (xmin+xmax)/2.0, (ymin+ymax)/2.0 ,
(xmax-xmin)/2.0, (ymax-ymin)/2.0 );
return c;
}
}
AliMUONPad::AliMUONPad()
:
TObject(),
fIsSaturated(kFALSE),
fIsReal(kFALSE),
fClusterId(-1),
fCathode(-1),
fDetElemId(-1),
fIx(-1),
fIy(-1),
fStatus(0),
fDimensions(),
fPosition(),
fCharge(0.0),
fChargeBackup(0.0)
{
Init(-1,-1,-1,-1,TVector2(0,0),TVector2(0,0),0);
}
AliMUONPad::AliMUONPad(Int_t detElemId, Int_t cathode,
Int_t ix, Int_t iy, Double_t x, Double_t y,
Double_t dx, Double_t dy, Double_t charge)
:
TObject(),
fIsSaturated(kFALSE),
fIsReal(kFALSE),
fClusterId(-1),
fCathode(-1),
fDetElemId(-1),
fIx(-1),
fIy(-1),
fStatus(0),
fDimensions(),
fPosition(),
fCharge(0.0),
fChargeBackup(0.0)
{
Init(detElemId,cathode,ix,iy,TVector2(x,y),TVector2(dx,dy),charge);
}
AliMUONPad::AliMUONPad(Double_t x, Double_t y,
Double_t dx, Double_t dy, Double_t charge)
: TObject(),
fIsSaturated(kFALSE),
fIsReal(kFALSE),
fClusterId(-1),
fCathode(-1),
fDetElemId(-1),
fIx(-1),
fIy(-1),
fStatus(0),
fDimensions(),
fPosition(),
fCharge(0.0),
fChargeBackup(0.0)
{
Init(-1,-1,-1,-1,TVector2(x,y),TVector2(dx,dy),charge);
}
AliMUONPad::AliMUONPad(const TVector2& position, const TVector2& dimensions,
Double_t charge)
: TObject(),
fIsSaturated(kFALSE),
fIsReal(kFALSE),
fClusterId(-1),
fCathode(-1),
fDetElemId(-1),
fIx(-1),
fIy(-1),
fStatus(0),
fDimensions(),
fPosition(),
fCharge(0.0),
fChargeBackup(0.0)
{
Init(-1,-1,-1,-1,position,dimensions,charge);
}
AliMUONPad::~AliMUONPad()
{
}
Bool_t
AliMUONPad::AreNeighbours(const AliMUONPad& d1, const AliMUONPad& d2)
{
if ( d1.DetElemId() != d2.DetElemId() ||
d1.Cathode() != d2.Cathode() )
{
return kFALSE;
}
else
{
static Double_t precision = 1E-4;
static TVector2 precisionAdjustment(-precision,-precision);
return AreOverlapping(d1,d2,precisionAdjustment);
}
}
Bool_t
AliMUONPad::AreOverlapping(const AliMUONPad& d1, const AliMUONPad& d2,
const TVector2& precision)
{
AliMpArea a1(d1.X(),d1.Y(),d1.DX(),d1.DY());
AliMpArea a2(d2.X(),d2.Y(),d2.DX(),d2.DY());
if ( a1.LeftBorder() > a2.RightBorder() - precision.X() ||
a1.RightBorder() < a2.LeftBorder() + precision.X() )
{
return kFALSE;
}
if ( a1.DownBorder() > a2.UpBorder() - precision.Y() ||
a1.UpBorder() < a2.DownBorder() + precision.Y() )
{
return kFALSE;
}
return kTRUE;
}
Bool_t
AliMUONPad::AreOverlapping(const AliMUONPad& d1, const AliMUONPad& d2,
const TVector2& precision,
AliMpArea& overlapRegion)
{
if ( AreOverlapping(d1,d2,precision) )
{
overlapRegion = Overlap(d1,d2);
if ( !overlapRegion.IsValid() )
{
cerr << "Something is wrong : the 2 pads below are flagged as overlapping"
<< ", but the overlapRegion is not valid"
<< endl;
d1.Print("corners");
d2.Print("corners");
}
return kTRUE;
}
return kFALSE;
}
Int_t
AliMUONPad::Compare(const TObject* obj) const
{
const AliMUONPad* pad = static_cast<const AliMUONPad*>(obj);
if (DetElemId() < 0)
{
if (Charge() == pad->Charge()) return 0;
return ( Charge() < pad->Charge() ) ? 1:-1;
}
if ( DetElemId() > pad->DetElemId() )
{
return 1;
}
else if ( DetElemId() < pad->DetElemId() )
{
return -1;
}
else
{
if ( Cathode() > pad->Cathode() )
{
return 1;
}
else if ( Cathode() < pad->Cathode() )
{
return -1;
}
else
{
if ( Ix() > pad->Ix() )
{
return 1;
}
else if ( Ix() < pad->Ix() )
{
return -1;
}
else
{
if ( Iy() > pad->Iy() )
{
return 1;
}
else if ( Iy() < pad->Iy() )
{
return -1;
}
else
{
if ( X() > pad->X() )
{
return 1;
}
else if ( X() < pad->X() )
{
return -1;
}
else
{
if ( Y() > pad->Y() )
{
return 1;
}
else if ( Y() < pad->Y() )
{
return -1;
}
else
{
if ( Charge() < pad->Charge() )
{
return -1;
}
else if ( Charge() > pad->Charge() )
{
return 1;
}
else
{
return 0;
}
}
}
}
}
}
}
return 0;
}
Double_t
AliMUONPad::Coord(Int_t ixy) const
{
if ( ixy == 0 )
{
return X();
}
else if ( ixy == 1 )
{
return Y();
}
AliError(Form("Incorrect coordinates index %d (only 0,1 are valid)",ixy));
return 0;
}
void
AliMUONPad::Init(Int_t detElemId, Int_t cathode,
Int_t ix, Int_t iy,
const TVector2& position,
const TVector2& dimensions,
Double_t charge)
{
fIsSaturated = kFALSE;
fIsReal = kTRUE;
fDetElemId = detElemId;
fCathode = cathode;
fIx = ix;
fIy = iy;
fPosition = position;
fDimensions = dimensions;
fCharge = charge;
fChargeBackup = fCharge;
fClusterId = -1;
fStatus = 0;
}
AliMpArea
AliMUONPad::Overlap(const AliMUONPad& d1, const AliMUONPad& d2)
{
AliMpArea a1(d1.X(),d1.Y(),d1.DX(),d1.DY());
AliMpArea a2(d2.X(),d2.Y(),d2.DX(),d2.DY());
return Intersect(a1,a2);
}
void
AliMUONPad::Paint(Option_t*)
{
TVector2 ll = Position() - Dimensions();
TVector2 ur = Position() + Dimensions();
gPad->PaintBox(ll.X(),ll.Y(),ur.X(),ur.Y());
}
void
AliMUONPad::Print(Option_t* opt) const
{
TString sopt(opt);
sopt.ToLower();
ios_base::fmtflags oldflags = cout.flags();
if ( Cathode() >= 0 )
{
cout << "DetEle " << setw(5) << DetElemId()
<< " Cath " << setw(2) << Cathode()
<< " (Ix,Iy)=(" << setw(3) << Ix() << "," << setw(3) << Iy() << ") ";
}
cout.setf(ios::fixed);
cout.precision(6);
cout << " (x,y)=(" << setw(9) << X() << "," << setw(9) << Y() << ") "
<< " (dx,dy)=(" << setw(9) << DX() << "," << setw(9) << DY() << ") "
<< " Charge=";
cout.precision(2);
cout << setw(7) << Charge();
if ( sopt.Contains("full") )
{
cout
<< " Used=" << (IsUsed()?Form("YES (ClusterId %d)",fClusterId):"NO")
<< (IsSaturated()?"(S)":" ")
<< (IsReal()?" ":"(V)")
<< " Status=" << setw(4) << Status()
<< " ChargeBackup=" << ChargeBackup();
}
if ( sopt.Contains("corners") )
{
cout << Form(" (xmin,xmax)=(%e,%e) (ymin,ymax)=(%e,%e)",
X()-DX(),X()+DX(),
Y()-DY(),Y()+DY()) << endl;
}
cout << endl;
cout.precision(6);
cout.flags(oldflags);
}
void
AliMUONPad::SetCoord(Int_t ixy, Double_t coord)
{
if ( ixy == 0 )
{
fPosition.Set(coord,Y());
}
else if ( ixy == 1 )
{
fPosition.Set(X(),coord);
}
else
{
AliError(Form("Incorrect coordinates index %d (only 0,1 are valid)",ixy));
}
}
void
AliMUONPad::SetSize(Int_t ixy, Double_t size)
{
if ( ixy == 0 )
{
fDimensions.Set(size,DY());
}
else if ( ixy == 1 )
{
fDimensions.Set(DX(),size);
}
else
{
AliError(Form("Incorrect coordinates index %d (only 0,1 are valid)",ixy));
}
}
void
AliMUONPad::Shift(Int_t ixy, Double_t shift)
{
SetCoord(ixy,Coord(ixy)+shift);
}
Double_t
AliMUONPad::Size(Int_t ixy) const
{
if ( ixy == 0 )
{
return DX();
}
else if ( ixy == 1 )
{
return DY();
}
AliError(Form("Incorrect coordinates index %d (only 0,1 are valid)",ixy));
return 0;
}