#include "AliMpSlat.h"
#include "AliMpExMapIterator.h"
#include "AliLog.h"
#include "AliMpMotifPosition.h"
#include "AliMpPCB.h"
#include "Riostream.h"
#include "TArrayI.h"
#include <cassert>
using std::cout;
using std::endl;
ClassImp(AliMpSlat)
AliMpSlat::AliMpSlat(TRootIOCtor* ioCtor)
: TObject(),
fId(""),
fPlaneType(AliMp::kNonBendingPlane),
fDX(0),
fDY(0),
fNofPadsX(0),
fMaxNofPadsY(0),
fManuMap(ioCtor),
fPCBs(),
fPositionX(0.),
fPositionY(0.),
fNofPads(0)
{
AliDebug(1,Form("this=%p Empty ctor",this));
fPCBs.SetOwner(kTRUE);
fManuMap.SetOwner(kFALSE);
}
AliMpSlat::AliMpSlat(const char* id, AliMp::PlaneType bendingOrNonBending)
: TObject(),
fId(id),
fPlaneType(bendingOrNonBending),
fDX(0),
fDY(0),
fNofPadsX(0),
fMaxNofPadsY(0),
fManuMap(),
fPCBs(),
fPositionX(0.),
fPositionY(0.),
fNofPads(0)
{
AliDebug(1,Form("this=%p id=%s",this,id));
fPCBs.SetOwner(kTRUE);
fManuMap.SetOwner(kFALSE);
}
AliMpSlat::~AliMpSlat()
{
AliDebug(1,Form("this=%p fId=%s",this,fId.Data()));
fPCBs.Delete();
}
void
AliMpSlat::Add(const AliMpPCB& pcbType, const TArrayI& manuList)
{
Int_t ixOffset = 0;
if ( GetSize() )
{
ixOffset = GetPCB(GetSize()-1)->Ixmax()+1;
}
else
{
ixOffset = pcbType.Ixmin();
}
Double_t xOffset = DX()*2;
AliMpPCB* pcb = pcbType.Clone(manuList,ixOffset,xOffset);
fPCBs.AddLast(pcb);
fDY = TMath::Max(pcb->DY(),fDY);
fDX += pcb->DX();
fNofPadsX += pcb->GetNofPadsX();
fMaxNofPadsY = TMath::Max(fMaxNofPadsY,pcb->GetNofPadsY());
Int_t n(0);
for ( Int_t i = 0; i < pcb->GetSize(); ++i )
{
AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
Int_t manuID = mp->GetID();
TObject* there = fManuMap.GetValue(manuID);
if ( there == 0 )
{
++n;
AliDebug(1,Form("Adding %d-th manuId=%d (%d) to ManuMap (size=%d)",n,manuID,mp->GetID(),fManuMap.GetSize()));
fManuMap.Add(manuID,(TObject*)mp);
}
else
{
AliError(Form("ManuID %d is duplicated for PCB %s",manuID,pcbType.GetID()));
}
}
fPositionX = DX();
fPositionY = DY();
fNofPads += pcb->NofPads();
}
Double_t
AliMpSlat::DX() const
{
return fDX;
}
Double_t
AliMpSlat::DY() const
{
return fDY;
}
AliMpMotifPosition*
AliMpSlat::FindMotifPosition(Int_t manuID) const
{
return static_cast<AliMpMotifPosition*>(fManuMap.GetValue(manuID));
}
AliMpMotifPosition*
AliMpSlat::FindMotifPosition(Int_t ix, Int_t iy) const
{
const AliMpPCB* pcb = FindPCB(ix);
if ( pcb )
{
return pcb->FindMotifPosition(ix,iy);
}
else
{
return 0;
}
}
AliMpMotifPosition*
AliMpSlat::FindMotifPosition(Double_t x, Double_t y) const
{
const AliMpPCB* pcb = FindPCB(x,y);
if (pcb)
{
return pcb->FindMotifPosition(x,y);
}
else
{
return 0;
}
}
AliMpPCB*
AliMpSlat::FindPCB(Int_t ix) const
{
for ( Int_t i = 0; i < GetSize(); ++i )
{
AliMpPCB* pcb = GetPCB(i);
if ( ix >= pcb->Ixmin() && ix <= pcb->Ixmax() )
{
return pcb;
}
}
return 0;
}
Int_t
AliMpSlat::FindPCBIndex(Int_t ix) const
{
for ( Int_t i = 0; i < GetSize(); ++i )
{
AliMpPCB* pcb = GetPCB(i);
if ( ix >= pcb->Ixmin() && ix <= pcb->Ixmax() )
{
return i;
}
}
return -1;
}
AliMpPCB*
AliMpSlat::FindPCB(Double_t x, Double_t y) const
{
for ( Int_t i = 0; i < GetSize(); ++i )
{
AliMpPCB* pcb = GetPCB(i);
if ( x < pcb->Xmin() || x >= pcb->Xmax() ||
y < pcb->Ymin() || y >= pcb->Ymax() )
{
continue;
}
return pcb;
}
return 0;
}
Int_t
AliMpSlat::FindPCBIndex(Double_t x, Double_t y) const
{
for ( Int_t i = 0; i < GetSize(); ++i )
{
AliMpPCB* pcb = GetPCB(i);
if ( x >= pcb->Xmin() && x < pcb->Xmax() &&
y >= pcb->Ymin() && y < pcb->Ymax() )
{
return i;
}
}
return -1;
}
Int_t
AliMpSlat::FindPCBIndexByMotifPositionID(Int_t manuId) const
{
for ( Int_t i = 0; i< GetSize(); ++i )
{
AliMpPCB* pcb = GetPCB(i);
if ( pcb->HasMotifPositionID(manuId) ) return i;
}
return -1;
}
void
AliMpSlat::ForcePosition(Double_t x, Double_t y)
{
fPositionX = x;
fPositionY = y;
}
void
AliMpSlat::GetAllMotifPositionsIDs(TArrayI& ecn) const
{
Int_t nofElectronicCards(GetNofElectronicCards());
assert(nofElectronicCards>0);
ecn.Set(nofElectronicCards);
TIter next(fManuMap.CreateIterator());
AliMpMotifPosition* mp;
Int_t n(0);
while ( ( mp = static_cast<AliMpMotifPosition*>(next()) ) )
{
ecn.AddAt(mp->GetID(),n);
++n;
}
assert(n==nofElectronicCards);
}
const char*
AliMpSlat::GetID() const
{
return fId.Data();
}
Int_t
AliMpSlat::GetMaxNofPadsY() const
{
return fMaxNofPadsY;
}
Int_t
AliMpSlat::GetMaxPadIndexX() const
{
AliMpPCB* last = GetPCB(GetSize()-1);
if (last)
{
return last->Ixmax();
}
return 0;
}
const char*
AliMpSlat::GetName() const
{
TString name(GetID());
if ( fPlaneType == AliMp::kBendingPlane )
{
name += ".Bending";
}
else if ( fPlaneType == AliMp::kNonBendingPlane )
{
name += ".NonBending";
}
else
{
name += ".Invalid";
}
return name.Data();
}
Int_t
AliMpSlat::GetNofElectronicCards() const
{
return fManuMap.GetSize();
}
Int_t
AliMpSlat::GetNofPadsX() const
{
return fNofPadsX;
}
AliMpPCB*
AliMpSlat::GetPCB(Int_t i) const
{
if ( i >= fPCBs.GetEntriesFast() ) return 0;
return (AliMpPCB*)fPCBs[i];
}
Int_t
AliMpSlat::GetSize() const
{
return fPCBs.GetEntriesFast();
}
void
AliMpSlat::Print(Option_t* option) const
{
cout << "SLAT " << GetID() << " 1/2 DIM = (" << DX() << "," << DY() << ")"
<< " POS = " << GetPositionX() << "," << GetPositionY()
<< " NPADSX = " << GetNofPadsX()
<< " MAXNPADSY = " << GetMaxNofPadsY()
<< " NPCBs=" << GetSize() << endl;
TString soption(option);
if ( soption.Contains("P") )
{
for ( Int_t i = 0; i < GetSize() ; ++i )
{
cout << " ";
if ( option )
{
fPCBs[i]->Print(option+1);
}
else
{
fPCBs[i]->Print();
}
}
}
if ( soption.Contains("M") || soption.Contains("L") )
{
cout << fManuMap.GetSize() << " ";
cout << "Electronic card (manu or local board) Ids : ";
TIter next(fManuMap.CreateIterator());
AliMpMotifPosition* mp;
while ( ( mp = static_cast<AliMpMotifPosition*>(next())) )
{
cout << mp->GetID() << " ";
}
cout << endl;
}
}