#include "AliMpPCB.h"
#include "AliMpMotif.h"
#include "AliMpSlatMotifMap.h"
#include "AliMpMotifPosition.h"
#include "AliMpMotifSpecial.h"
#include "AliMpMotifType.h"
#include "AliLog.h"
#include "Riostream.h"
#include "TList.h"
#include "TObjString.h"
#include "TMath.h"
#include <sstream>
using std::cout;
using std::endl;
using std::ofstream;
ClassImp(AliMpPCB)
AliMpPCB::AliMpPCB()
: TObject(),
fId(""),
fPadSizeX(0),
fPadSizeY(0),
fEnveloppeSizeX(0),
fEnveloppeSizeY(0),
fXoffset(0),
fActiveXmin(0),
fActiveXmax(0),
fIxmin(99999),
fIxmax(0),
fIymin(99999),
fIymax(0),
fMotifPositions(),
fNofPads(0),
fMotifMap(0)
{
fMotifPositions.SetOwner(kTRUE);
AliDebug(1,Form("this=%p",this));
}
AliMpPCB::AliMpPCB(AliMpSlatMotifMap* motifMap, const char* id, Double_t padSizeX, Double_t padSizeY,
Double_t enveloppeSizeX, Double_t enveloppeSizeY)
: TObject(),
fId(id),
fPadSizeX(padSizeX),
fPadSizeY(padSizeY),
fEnveloppeSizeX(enveloppeSizeX),
fEnveloppeSizeY(enveloppeSizeY),
fXoffset(0),
fActiveXmin(0),
fActiveXmax(0),
fIxmin(99999),
fIxmax(0),
fIymin(99999),
fIymax(0),
fMotifPositions(),
fNofPads(0),
fMotifMap(motifMap)
{
fMotifPositions.SetOwner(kTRUE);
AliDebug(1,Form("this=%p id=%s",this,id));
}
AliMpPCB::AliMpPCB(const AliMpPCB& o)
: TObject(o),
fId(0),
fPadSizeX(0),
fPadSizeY(0),
fEnveloppeSizeX(0),
fEnveloppeSizeY(0),
fXoffset(0),
fActiveXmin(0),
fActiveXmax(0),
fIxmin(99999),
fIxmax(0),
fIymin(99999),
fIymax(0),
fMotifPositions(),
fNofPads(0),
fMotifMap(0x0)
{
fMotifPositions.SetOwner(kTRUE);
AliDebug(1,Form("this=%p (copy ctor) : begin",this));
o.Copy(*this);
AliDebug(1,Form("this=%p (copy ctor) : end",this));
}
AliMpPCB::AliMpPCB(const char* id, AliMpMotifSpecial* ms)
: TObject(),
fId(id),
fPadSizeX(-1.0),
fPadSizeY(-1.0),
fEnveloppeSizeX(ms->DimensionX()*2.0),
fEnveloppeSizeY(ms->DimensionY()*2.0),
fXoffset(0.0),
fActiveXmin(0.0),
fActiveXmax(fEnveloppeSizeX),
fIxmin(0),
fIxmax(ms->GetMotifType()->GetNofPadsX()-1),
fIymin(0),
fIymax(ms->GetMotifType()->GetNofPadsY()-1),
fMotifPositions(),
fNofPads(ms->GetMotifType()->GetNofPads()),
fMotifMap(0x0)
{
AliDebug(1,Form("this=%p (ctor special motif)",this));
fMotifPositions.SetOwner(kTRUE);
Double_t posx = ms->DimensionX();
Double_t posy = ms->DimensionY();
AliMpMotifPosition* mp = new AliMpMotifPosition(-1,ms,posx,posy);
mp->SetLowIndicesLimit(fIxmin,fIymin);
mp->SetHighIndicesLimit(fIxmax,fIymax);
fMotifPositions.AddLast(mp);
}
AliMpPCB&
AliMpPCB::operator=(const AliMpPCB& o)
{
AliDebug(1,Form("this=%p (assignment op) : begin",this));
o.Copy(*this);
AliDebug(1,Form("this=%p (assignment op) : end",this));
return *this;
}
AliMpPCB::~AliMpPCB()
{
AliDebug(1,Form("this=%p",this));
}
Double_t
AliMpPCB::ActiveXmin() const
{
return fActiveXmin;
}
Double_t
AliMpPCB::ActiveXmax() const
{
return fActiveXmax;
}
void
AliMpPCB::Add(AliMpMotifType* mt, Int_t ix, Int_t iy)
{
TString id(Form("%s-%e-%e",mt->GetID().Data(),PadSizeX(),PadSizeY()));
AliMpVMotif* motif = fMotifMap->FindMotif(id);
if (!motif)
{
motif = new AliMpMotif(id,mt,PadSizeX()/2.0,PadSizeY()/2.0);
AliDebug(1,Form("Adding motif %s to motifMap",id.Data()));
fMotifMap->AddMotif(motif);
}
else
{
AliDebug(1,Form("Got motif %s from motifMap",id.Data()));
}
Double_t posx(0.);
Double_t posy(0.);
Int_t ixmin(-1);
Int_t iymin(-1);
if ( ix >= 0 && iy >= 0 )
{
posx = ix*PadSizeX();
posy = iy*PadSizeY();
ixmin = ix;
iymin = iy;
}
else
if ( ix >= 0 && iy < 0 )
{
posx = ix*PadSizeX();
posy = Ymax()+iy*PadSizeY();
ixmin = ix;
iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
}
else
if ( ix < 0 && iy < 0 )
{
posx = Xmax()+ix*PadSizeX();
posy = Ymax()+iy*PadSizeY();
ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
iymin = TMath::Nint(Ymax()/PadSizeY()) + iy;
}
else
if ( ix < 0 && iy >=0 )
{
posx = Xmax()+ix*PadSizeX();
posy = iy*PadSizeY();
ixmin = TMath::Nint(Xmax()/PadSizeX()) + ix;
iymin = iy;
}
posx += motif->DimensionX();
posy += motif->DimensionY();
AliMpMotifPosition* mp
= new AliMpMotifPosition(-1,motif,posx, posy);
Int_t ixmax = ixmin + mt->GetNofPadsX() - 1;
Int_t iymax = iymin + mt->GetNofPadsY() - 1;
mp->SetLowIndicesLimit(ixmin,iymin);
mp->SetHighIndicesLimit(ixmax,iymax);
fMotifPositions.AddLast(mp);
fIxmin = TMath::Min(fIxmin,ixmin);
fIxmax = TMath::Max(fIxmax,ixmax);
fIymin = TMath::Min(fIymin,iymin);
fIymax = TMath::Max(fIymax,iymax);
fActiveXmin = fIxmin*PadSizeX();
fActiveXmax = (fIxmax+1)*PadSizeX();
fNofPads += mt->GetNofPads();
}
AliMpArea
AliMpPCB::Area() const
{
return AliMpArea((Xmin()+Xmax())/2.0,DY(), DX(), DY() );
}
TObject*
AliMpPCB::Clone(const char* ) const
{
AliDebug(1,"begin");
TObject* object = new AliMpPCB(*this);
AliDebug(1,"end");
return object;
}
AliMpPCB*
AliMpPCB::Clone(const TArrayI& manuids, Int_t ixOffset, Double_t xOffset) const
{
AliDebug(1,"begin");
AliMpPCB* pcb = static_cast<AliMpPCB*>(Clone());
if ( Int_t(pcb->GetSize()) != manuids.GetSize() )
{
AliError(Form("Cannot Clone PCB %s because I do not get the correct number of "
"manu ids (got %d, wanted %d)",pcb->GetID(),
manuids.GetSize(),pcb->GetSize()));
return 0;
}
MpPair_t shift = AliMp::Pair(-fIxmin+ixOffset,0);
for ( Int_t i = 0; i < pcb->GetSize(); ++i )
{
AliMpMotifPosition* mp = pcb->GetMotifPosition(i);
mp->SetID(manuids[i]);
Double_t posx = mp->GetPositionX() + xOffset;
Double_t posy = mp->GetPositionY();
mp->SetPosition(posx, posy);
MpPair_t low = mp->GetLowIndicesLimit();
low += shift;
mp->SetLowIndicesLimit(low);
MpPair_t high = mp->GetHighIndicesLimit();
high += shift;
mp->SetHighIndicesLimit(high);
}
pcb->fIxmin += AliMp::PairFirst(shift);
pcb->fIxmax += AliMp::PairFirst(shift);
pcb->fXoffset = xOffset;
pcb->fActiveXmin += xOffset;
pcb->fActiveXmax += xOffset;
AliDebug(1,"end");
return pcb;
}
void
AliMpPCB::Copy(TObject& o) const
{
AliDebug(1,"begin");
TObject::Copy(o);
AliMpPCB& pcb = static_cast<AliMpPCB&>(o);
pcb.fId = fId;
pcb.fPadSizeX = fPadSizeX;
pcb.fPadSizeY = fPadSizeY;
pcb.fEnveloppeSizeX = fEnveloppeSizeX;
pcb.fEnveloppeSizeY = fEnveloppeSizeY;
pcb.fXoffset = fXoffset;
pcb.fIxmin = fIxmin;
pcb.fIxmax = fIxmax;
pcb.fIymin = fIymin;
pcb.fIymax = fIymax;
pcb.fActiveXmin = fActiveXmin;
pcb.fActiveXmax = fActiveXmax;
AliDebug(1,"Deleting pcb.fMotifPositions");
pcb.fMotifPositions.Delete();
AliDebug(1,"Deleting pcb.fMotifPositions : done");
for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
{
AliMpMotifPosition* pos = (AliMpMotifPosition*)fMotifPositions[i];
AliMpMotifPosition* pcbpos
= new AliMpMotifPosition(pos->GetID(), pos->GetMotif(),
pos->GetPositionX(), pos->GetPositionY());
pcbpos->SetLowIndicesLimit(pos->GetLowIndicesLimit());
pcbpos->SetHighIndicesLimit(pos->GetHighIndicesLimit());
pcb.fMotifPositions.AddLast(pcbpos);
}
pcb.fNofPads = fNofPads;
pcb.fMotifMap = fMotifMap;
AliDebug(1,"end");
}
Double_t
AliMpPCB::ActiveDX() const
{
return GetNofPadsX()*fPadSizeX/2.0;
}
Double_t
AliMpPCB::DX() const
{
return fEnveloppeSizeX/2.0;
}
Double_t
AliMpPCB::ActiveDY() const
{
return GetNofPadsY()*fPadSizeY/2.0;
}
Double_t
AliMpPCB::DY() const
{
return fEnveloppeSizeY/2.0;
}
AliMpMotifPosition*
AliMpPCB::FindMotifPosition(Int_t ix, Int_t iy) const
{
for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
{
AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
if ( mp->HasPadByIndices(AliMp::Pair(ix,iy)) )
{
return mp;
}
}
return 0;
}
AliMpMotifPosition*
AliMpPCB::FindMotifPosition(Double_t x, Double_t y) const
{
for (Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
{
AliMpMotifPosition* mp = (AliMpMotifPosition*)fMotifPositions[i];
Double_t localPosX = x - mp->GetPositionX();
Double_t localPosY = y - mp->GetPositionY();
MpPair_t localIndices(
mp->GetMotif()->PadIndicesLocal(localPosX, localPosY));
if ( localIndices >= 0 &&
mp->GetMotif()->GetMotifType()->HasPadByLocalIndices(localIndices) )
{
return mp;
}
}
return 0;
}
const char*
AliMpPCB::GetID() const
{
return fId.Data();
}
AliMpMotifPosition*
AliMpPCB::GetMotifPosition(Int_t i) const
{
if ( i >= fMotifPositions.GetEntriesFast() ) return 0;
return (AliMpMotifPosition*)fMotifPositions[i];
}
Int_t
AliMpPCB::GetNofPadsX() const
{
return fIxmax-fIxmin+1;
}
Int_t
AliMpPCB::GetNofPadsY() const
{
return fIymax-fIymin+1;
}
Int_t
AliMpPCB::GetSize() const
{
return fMotifPositions.GetEntriesFast();
}
Bool_t
AliMpPCB::HasMotifPositionID(Int_t manuId) const
{
TIter next(&fMotifPositions);
AliMpMotifPosition* pos;
while ( ( pos = static_cast<AliMpMotifPosition*>(next()) ) )
{
if ( pos->GetID() == manuId ) return kTRUE;
}
return kFALSE;
}
Int_t
AliMpPCB::Ixmin() const
{
return fIxmin;
}
Int_t
AliMpPCB::Ixmax() const
{
return Ixmin() + GetNofPadsX() - 1;
}
Int_t
AliMpPCB::Iymin() const
{
return fIymin;
}
Int_t
AliMpPCB::Iymax() const
{
return Iymin() + GetNofPadsY() - 1;
}
Double_t
AliMpPCB::PadSizeX() const
{
return fPadSizeX;
}
Double_t
AliMpPCB::PadSizeY() const
{
return fPadSizeY;
}
void
AliMpPCB::Print(Option_t* option) const
{
cout << "PCB " << GetID() << " PADSIZES=(" << fPadSizeX << ","
<< fPadSizeY << ") iMin=(" << fIxmin << "," << fIymin << ") "
<< "iMax=(" << fIxmax << "," << fIymax << ") "
<< " EnvXmin,max=(" << Xmin() << "," << Xmax()
<< ") Xmin,max=(" << ActiveXmin() << "," << ActiveXmax() << ")"
<< endl;
if ( option && option[0] == 'M' )
{
for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
{
fMotifPositions[i]->Print(option+1);
}
}
}
void
AliMpPCB::Save() const
{
TString fileName(fId);
fileName += ".pcb";
TList lines;
lines.SetOwner(kTRUE);
for ( Int_t i = 0; i < fMotifPositions.GetEntriesFast(); ++i )
{
AliMpMotifPosition* pos = GetMotifPosition(i);
AliMpVMotif* motif = pos->GetMotif();
Double_t lowerLeftX = pos->GetPositionX()-pos->GetDimensionX();
Double_t lowerLeftY = pos->GetPositionY()-pos->GetDimensionY();
TString id(motif->GetID());
Ssiz_t index = id.Index("-");
if ( index < 1 )
{
AliError(Form("id=%s does not meet expectations",id.Data()));
return;
}
TString motifName(id(0,index));
lines.Add(new TObjString(Form("MOTIF %s %d %d",
motifName.Data(),
TMath::Nint(lowerLeftX/fPadSizeX),
TMath::Nint(lowerLeftY/fPadSizeY))));
}
ofstream out(fileName.Data());
out.precision(9);
out << "SIZES " << fPadSizeX << " " << fPadSizeY
<< " " << fEnveloppeSizeX << " " << fEnveloppeSizeY
<< endl;
TIter next(&lines);
TObjString* s;
while ( ( s = (TObjString*)next() ) )
{
out << s->String().Data() << endl;
}
out.close();
}
Double_t
AliMpPCB::X() const
{
return fXoffset + DX();
}
Double_t
AliMpPCB::Xmin() const
{
return X() - DX();
}
Double_t
AliMpPCB::Xmax() const
{
return X() + DX();
}
Double_t
AliMpPCB::Y() const
{
return DY();
}
Double_t
AliMpPCB::Ymin() const
{
return Y() - DY();
}
Double_t
AliMpPCB::Ymax() const
{
return Y() + DY();
}