#include "AliMUONNode.h"
#include "AliLog.h"
#include "AliMUONSegment.h"
#include "Riostream.h"
#include "TMath.h"
#include "TObjArray.h"
#include "TString.h"
using std::cout;
using std::endl;
ClassImp(AliMUONNode)
AliMUONNode::AliMUONNode(Double_t a, Double_t b, Double_t midpoint)
: fLeftNode(0x0), fRightNode(0x0), fMin(a), fMax(b), fMidPoint(midpoint), fC(0), fP(0)
{
}
AliMUONNode::~AliMUONNode()
{
delete fLeftNode;
delete fRightNode;
}
void
AliMUONNode::Print(const char* opt) const
{
cout << opt << Form("[%7.2f,%7.2f]",fMin,fMax);
if ( !TMath::IsNaN(fMidPoint) ) cout << Form(" (%7.2f)",fMidPoint);
cout << endl;
TString sopt(opt);
sopt += " ";
if ( fLeftNode )
{
fLeftNode->Print(sopt.Data());
}
if ( fRightNode )
{
fRightNode->Print(sopt.Data());
}
}
void
AliMUONNode::Contribution(Double_t b, Double_t e, TObjArray& stack)
{
if ( fMax < fMin )
{
AliError(Form("fMax(%10.5f) < fMin(%10.5f",fMax,fMin));
}
if ( fC == 0 )
{
if ( IsFullyContained(b,e) && fP == 0 )
{
AliMUONSegment* back = static_cast<AliMUONSegment*>(stack.Last());
if ( back && AliMUONSegment::AreEqual(back->EndY(),fMin) )
{
Double_t y(back->StartY());
back->Set(0.0,y,0.0,fMax);
}
else
{
stack.Add(new AliMUONSegment(0.0,fMin,0.0,fMax));
}
}
else
{
if ( b < fMidPoint )
{
fLeftNode->Contribution(b,e,stack);
}
if ( fMidPoint < e )
{
fRightNode->Contribution(b,e,stack);
}
}
}
}
Bool_t
AliMUONNode::IsFullyContained(Double_t b, Double_t e) const
{
return ( ( b < fMin || AliMUONSegment::AreEqual(b,fMin) ) && ( fMax < e || AliMUONSegment::AreEqual(e,fMax)) );
}
void
AliMUONNode::InsertInterval(Double_t b, Double_t e, TObjArray& stack)
{
if ( IsFullyContained(b,e) )
{
C(1);
}
else
{
if ( b < fMidPoint )
{
fLeftNode->InsertInterval(b,e,stack);
}
if ( fMidPoint < e )
{
fRightNode->InsertInterval(b,e,stack);
}
}
Update();
}
void
AliMUONNode::DeleteInterval(Double_t b, Double_t e, TObjArray& stack)
{
if ( IsFullyContained(b,e) )
{
C(-1);
}
else
{
if ( fC > 0 ) Demote();
if ( b < fMidPoint )
{
fLeftNode->DeleteInterval(b,e,stack);
}
if ( fMidPoint < e )
{
fRightNode->DeleteInterval(b,e,stack);
}
}
Update();
}
void
AliMUONNode::Update()
{
if ( !fLeftNode )
{
fP = 0;
}
else
{
if (fLeftNode->C() > 0 && fRightNode->C() > 0 )
{
Promote();
}
if (fLeftNode->C()==0 && fRightNode->C()==0 && fLeftNode->P()==0 && fRightNode->P()==0 )
{
fP = 0;
}
else
{
fP = 1;
}
}
}
void
AliMUONNode::Promote()
{
fLeftNode->C(-1);
fRightNode->C(-1);
C(+1);
}
void
AliMUONNode::Demote()
{
fLeftNode->C(+1);
fRightNode->C(+1);
C(-1);
fP = 1;
}