#include <TMath.h>
#include <TSystem.h>
#include <TString.h>
#include "AliTPCmapper.h"
#include "AliTPCAltroMapping.h"
#include "AliTPCROC.h"
#include "AliLog.h"
#include "AliDAQ.h"
ClassImp(AliTPCmapper)
AliTPCmapper::AliTPCmapper() :
fNside(0),
fNsector(0),
fNrcu(0),
fNbranch(0),
fNaltro(0),
fNchannel(0),
fNpadrow(0),
fNpadrowIROC(0),
fNpadrowOROC(0),
fTpcDdlOffset(0)
{
for ( Int_t i = 0; i < 6; i++ ) fMapping[i]=0;
}
AliTPCmapper::AliTPCmapper(const char * dirname) :
fNside(0),
fNsector(0),
fNrcu(0),
fNbranch(0),
fNaltro(0),
fNchannel(0),
fNpadrow(0),
fNpadrowIROC(0),
fNpadrowOROC(0),
fTpcDdlOffset(0)
{
Init(dirname);
}
AliTPCmapper::~AliTPCmapper()
{
for ( Int_t i = 0; i < fNrcu; i++ ) {
delete fMapping[i];
fMapping[i] = 0;
}
}
AliTPCmapper::AliTPCmapper(const AliTPCmapper& mapper) :
TObject(mapper),
fNside(mapper.fNside),
fNsector(mapper.fNsector),
fNrcu(mapper.fNrcu),
fNbranch(mapper.fNbranch),
fNaltro(mapper.fNaltro),
fNchannel(mapper.fNchannel),
fNpadrow(mapper.fNpadrow),
fNpadrowIROC(mapper.fNpadrowIROC),
fNpadrowOROC(mapper.fNpadrowOROC),
fTpcDdlOffset(mapper.fTpcDdlOffset)
{
for ( Int_t i = 0; i < 6; i++ ) fMapping[i]=0;
for ( Int_t i = 0; i < fNrcu; i++ ) fMapping[i] = mapper.fMapping[i];
}
AliTPCmapper& AliTPCmapper::operator = (const AliTPCmapper& mapper)
{
if(&mapper == this) return *this;
((TObject *)this)->operator=(mapper);
for ( Int_t i = 0; i < fNrcu; i++ ) fMapping[i] = mapper.fMapping[i];
fNside = mapper.fNside;
fNsector = mapper.fNsector;
fNrcu = mapper.fNrcu;
fNbranch = mapper.fNbranch;
fNaltro = mapper.fNaltro;
fNchannel = mapper.fNchannel;
fNpadrow = mapper.fNpadrow;
fNpadrowIROC = mapper.fNpadrowIROC;
fNpadrowOROC = mapper.fNpadrowOROC;
fTpcDdlOffset = mapper.fTpcDdlOffset;
return *this;
}
void AliTPCmapper::Init(const char *dirname)
{
fNside = 2;
fNsector = 18;
fNrcu = 6;
fNbranch = 2;
fNaltro = 8;
fNchannel = 16;
TString path;
if (dirname==0){
path =gSystem->Getenv("ALICE_ROOT");
path += "/TPC/mapping/Patch";
}else{
path = dirname;
path +="Patch";
}
TString path2;
for(Int_t i = 0; i < fNrcu; i++) {
path2 = path;
path2 += i;
path2 += ".data";
fMapping[i] = new AliTPCAltroMapping(path2.Data());
}
AliTPCROC *fROC = AliTPCROC::Instance();
fNpadrowIROC = fROC->GetNRows(0);
fNpadrowOROC = fROC->GetNRows(36);
fNpadrow = fNpadrowIROC+fNpadrowOROC;
AliDAQ daq;
fTpcDdlOffset = daq.DdlIDOffset("TPC");
}
Int_t AliTPCmapper::GetHWAddress(Int_t roc, Int_t padrow, Int_t pad) const
{
Int_t patch = GetPatch(roc, padrow, pad);
if ( (patch >= fNrcu) || (patch < 0) ) return -1;
return fMapping[patch]->GetHWAddress(padrow, pad, roc);
}
Int_t AliTPCmapper::GetHWAddressSector(Int_t globalpadrow, Int_t pad) const
{
Int_t patch = 0;
Int_t hwAddress=-1;
if ( globalpadrow < fNpadrowIROC ) {
patch = GetPatch(0, globalpadrow, pad);
if (patch>-1)
hwAddress = fMapping[patch]->GetHWAddress(globalpadrow, pad, 0);
} else if ( globalpadrow < fNpadrow ) {
patch = GetPatch(36, globalpadrow - fNpadrowIROC, pad);
if (patch>-1)
hwAddress = fMapping[patch]->GetHWAddress(globalpadrow - fNpadrowIROC, pad, 36);
} else {
AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
hwAddress = -1;
}
return hwAddress;
}
Int_t AliTPCmapper::GetRcu(Int_t roc, Int_t padrow, Int_t pad) const
{
return GetPatch(roc, padrow, pad);
}
Int_t AliTPCmapper::GetPatch(Int_t roc, Int_t padrow, Int_t pad) const
{
if ( (padrow < 0) || (pad < 0) || (roc < 0) ) {
AliWarning(Form("Pad coordinates outside range (padrow %d, pad %d, roc %d) !", padrow, pad, roc));
return -1;
}
if ( roc < 36 ) {
Int_t padsInRow = GetNpads(padrow);
if ( (padsInRow < 0) || (pad >= padsInRow) ) {
AliWarning(Form("Pad index outside range (padrow %d, pad %d, roc %d) !", padrow, pad, roc));
return -1;
}
if ( padrow < 30 ) { return 0;
} else if ( padrow == 30 ) {
if ( (pad < 37) || (pad > 48) ) return 1;
else return 0;
} else if ( padrow < fNpadrowIROC ) { return 1;
} else {
AliWarning(Form("Padrow outside range (padrow %d, roc %d) !", padrow, roc));
return -1;
}
} else if ( roc < 72 ) {
Int_t padsInRow = GetNpads(fNpadrowIROC+padrow);
if ( (padsInRow < 0) || (pad >= padsInRow) ) {
AliWarning(Form("Pad index outside range (padrow %d, pad %d, roc %d) !", padrow, pad, roc));
return -1;
}
if ( padrow < 27 ) { return 2;
} else if ( padrow == 27 ) {
if ( (pad >= 43) && (pad <= 46) ) return 3;
else return 2;
} else if ( padrow < 54 ) { return 3;
} else if ( padrow < 76 ) { return 4;
} else if ( padrow == 76) {
if ( (pad >= 33) && (pad <= 88) ) return 5;
else return 4;
} else if ( padrow < fNpadrowOROC ) { return 5;
} else {
AliWarning(Form("Padrow outside range (padrow %d, roc %d) !", padrow, roc));
return -1;
}
}
return -1;
}
Int_t AliTPCmapper::GetRcuSector(Int_t globalpadrow, Int_t pad) const
{
return GetPatchSector(globalpadrow, pad);
}
Int_t AliTPCmapper::GetPatchSector(Int_t globalpadrow, Int_t pad) const
{
if ( globalpadrow >= fNpadrow ) {
AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
return -1;
}
if ( globalpadrow < fNpadrowIROC ) return GetPatch(0, globalpadrow, pad);
else return GetPatch(36, globalpadrow-fNpadrowIROC, pad);
}
Int_t AliTPCmapper::GetPadRow(Int_t patch, Int_t hwAddress) const
{
if ( (patch >= fNrcu) || (patch < 0) ) {
AliWarning(Form("Patch index outside range (patch %d) !", patch));
return -1;
}
return fMapping[patch]->GetPadRow(hwAddress);
}
Int_t AliTPCmapper::GetGlobalPadRow(Int_t patch, Int_t hwAddress) const
{
if ( patch < 2 ) return GetPadRow(patch, hwAddress);
else return GetPadRow(patch, hwAddress) + fNpadrowIROC;
}
Int_t AliTPCmapper::GetPad(Int_t patch, Int_t hwAddress) const
{
if ( (patch >= fNrcu) || (patch < 0) ) {
AliWarning(Form("Patch index outside range (patch %d) !", patch));
return -1;
}
return fMapping[patch]->GetPad(hwAddress);
}
Int_t AliTPCmapper::GetPadRow(Int_t patch, Int_t branch, Int_t fec, Int_t chip,
Int_t channel) const
{
if ( (patch >= fNrcu) || (branch >= fNbranch) || (chip >= fNaltro) || (channel >= fNchannel)
|| (patch < 0) || (branch < 0) || (chip < 0) || (channel < 0) ) {
AliWarning(Form("Coordinates outside range (patch %d, branch %d, fec %d, chip %d, channel %d)) !",
patch, branch, fec, chip, channel));
return -1;
}
return GetPadRow(patch, CodeHWAddress(branch, fec, chip, channel));
}
Int_t AliTPCmapper::GetGlobalPadRow(Int_t patch, Int_t branch, Int_t fec, Int_t chip,
Int_t channel) const
{
if ( (patch >= fNrcu) || (branch >= fNbranch) || (chip >= fNaltro) || (channel >= fNchannel)
|| (patch < 0) || (branch < 0) || (chip < 0) || (channel < 0) ) {
AliWarning(Form("Coordinates outside range (patch %d, branch %d, fec %d, chip %d, channel %d)) !",
patch, branch, fec, chip, channel));
return -1;
}
if ( patch < 2 ) return GetPadRow(patch, branch, fec, chip, channel);
else return GetPadRow(patch, branch, fec, chip, channel) + fNpadrowIROC;
}
Int_t AliTPCmapper::GetPad(Int_t patch, Int_t branch, Int_t fec, Int_t chip, Int_t channel) const
{
if ( (patch >= fNrcu) || (branch >= fNbranch) || (chip >= fNaltro) || (channel >= fNchannel)
|| (patch < 0) || (branch < 0) || (chip < 0) || (channel < 0) ) {
AliWarning(Form("Coordinates outside range (patch %d, branch %d, fec %d, chip %d, channel %d)) !",
patch, branch, fec, chip, channel));
return -1;
}
return GetPad(patch, CodeHWAddress(branch, fec, chip, channel));
}
Int_t AliTPCmapper::GetBranch(Int_t roc, Int_t padrow, Int_t pad) const
{
return DecodedHWAddressBranch(GetHWAddress(roc, padrow, pad));
}
Int_t AliTPCmapper::GetBranchSector(Int_t globalpadrow, Int_t pad) const
{
return DecodedHWAddressBranch(GetHWAddressSector(globalpadrow, pad));
}
Int_t AliTPCmapper::GetFEChw(Int_t roc, Int_t padrow, Int_t pad) const
{
return DecodedHWAddressFECaddr(GetHWAddress(roc, padrow, pad));
}
Int_t AliTPCmapper::GetFEChwSector(Int_t globalpadrow, Int_t pad) const
{
return DecodedHWAddressFECaddr(GetHWAddressSector(globalpadrow, pad));
}
Int_t AliTPCmapper::GetFEC(Int_t roc, Int_t padrow, Int_t pad) const
{
Int_t patch = GetPatch(roc, padrow, pad);
Int_t fec = DecodedHWAddressFECaddr(GetHWAddress(roc, padrow, pad));
Int_t branch = DecodedHWAddressBranch(GetHWAddress(roc, padrow, pad));
if ( (fec < 0) || (branch < 0) || (patch < 0) ) return -1;
return HwToOffline(patch, branch, fec);
}
Int_t AliTPCmapper::GetFECSector(Int_t globalpadrow, Int_t pad) const
{
Int_t patch = GetPatchSector(globalpadrow, pad);
Int_t fec = DecodedHWAddressFECaddr(GetHWAddressSector(globalpadrow, pad));
Int_t branch = DecodedHWAddressBranch(GetHWAddressSector(globalpadrow, pad));
if ( (fec < 0) || (branch < 0) || (patch < 0) ) return -1;
return HwToOffline(patch, branch, fec);
}
Int_t AliTPCmapper::GetChip(Int_t roc, Int_t padrow, Int_t pad) const
{
return DecodedHWAddressChipaddr(GetHWAddress(roc, padrow, pad));
}
Int_t AliTPCmapper::GetChipSector(Int_t globalpadrow, Int_t pad) const
{
return DecodedHWAddressChipaddr(GetHWAddressSector(globalpadrow, pad));
}
Int_t AliTPCmapper::GetChannel(Int_t roc, Int_t padrow, Int_t pad) const
{
return DecodedHWAddressChanneladdr(GetHWAddress(roc, padrow, pad));
}
Int_t AliTPCmapper::GetChannelSector(Int_t globalpadrow, Int_t pad) const
{
return DecodedHWAddressChanneladdr(GetHWAddressSector(globalpadrow, pad));
}
Int_t AliTPCmapper::CodeHWAddress(Int_t branch, Int_t fec, Int_t chip, Int_t channel) const
{
return ((branch&1)<<11) + ((fec&0xf)<<7) + ((chip&0x7)<<4) + (channel&0xf);
}
Int_t AliTPCmapper::DecodedHWAddressBranch(Int_t hwAddress) const
{
if ( hwAddress < 0 ) return -1;
return ((hwAddress>>11)&1);
}
Int_t AliTPCmapper::DecodedHWAddressFECaddr(Int_t hwAddress) const
{
if ( hwAddress < 0 ) return -1;
return ((hwAddress>>7)&0xf);
}
Int_t AliTPCmapper::DecodedHWAddressChipaddr(Int_t hwAddress) const
{
if ( hwAddress < 0 ) return -1;
return ((hwAddress>>4)&0x7);
}
Int_t AliTPCmapper::DecodedHWAddressChanneladdr(Int_t hwAddress) const
{
if ( hwAddress < 0 ) return -1;
return ((hwAddress&0xf));
}
Int_t AliTPCmapper::GetNpads(Int_t roc, Int_t padrow) const{
AliTPCROC *fROC = AliTPCROC::Instance();
Int_t retval = fROC->GetNPads((UInt_t)roc, (UInt_t)padrow);
return retval;
}
Int_t AliTPCmapper::GetNpads(Int_t globalpadrow) const{
if ( globalpadrow >= fNpadrow ) {
AliWarning(Form("Padrow outside range (globalpadrow %d) !", globalpadrow));
return -1;
}
if ( globalpadrow < fNpadrowIROC ) return GetNpads(0, globalpadrow);
else return GetNpads(36, globalpadrow - fNpadrowIROC);
return -1;
}
Int_t AliTPCmapper::GetNpadrows(Int_t roc) const
{
if (roc < 36) return fNpadrowIROC;
else if (roc < 72) return fNpadrowOROC;
return -1;
}
Int_t AliTPCmapper::GetNfec(Int_t patch) const
{
Int_t retval = 0;
switch(patch){
case(0):
retval = 18;
break;
case(1):
retval = 25;
break;
case(2):
retval = 18;
break;
case(3):
retval = 20;
break;
case(4):
retval = 20;
break;
case(5):
retval = 20;
break;
};
return retval;
}
Int_t AliTPCmapper::GetNfec(Int_t patch, Int_t branch) const
{
Int_t retval = 0;
switch(patch){
case(0):
retval = 9;
break;
case(1):
retval = 13;
break;
case(2):
retval = 9;
break;
case(3):
retval = 10;
break;
case(4):
retval = 10;
break;
case(5):
retval = 10;
break;
};
if( (branch == 1) && (patch == 1) ){
retval = 12;
}
return retval;
}
Int_t AliTPCmapper::OfflineToHwFec(Int_t patch, Int_t fec) const
{
if ( (patch < 0) || (fec < 0) ) {
AliWarning(Form("Patch (%d) or Fec number (%d) outside range !", patch, fec));
return -1;
}
if ( (patch > 5) || (fec >= GetNfec(patch)) ) {
AliWarning(Form("Patch (%d) or Fec number (%d) outside range !", patch, fec));
return -1;
}
Int_t fecsInBranchA = GetNfec(patch, 0);
if ( fec < fecsInBranchA )
return (fecsInBranchA - 1 - fec);
else
return (fec - fecsInBranchA);
return -1;
}
Int_t AliTPCmapper::OfflineToHwBranch(Int_t patch, Int_t fec) const
{
if ( (patch < 0) || (fec < 0) ) {
AliWarning(Form("Patch (%d) or Fec number (%d) outside range !", patch, fec));
return -1;
}
if ( (patch > 5) || (fec >= GetNfec(patch)) ) {
AliWarning(Form("Patch (%d) or Fec number (%d) outside range !", patch, fec));
return -1;
}
if ( fec < GetNfec(patch, 0) ) return 0;
else return 1;
return -1;
}
Int_t AliTPCmapper::HwToOffline(Int_t patch, Int_t branch, Int_t fec) const
{
if ( (patch < 0) || (fec < 0) || (branch < 0) ) {
AliWarning(Form("Patch (%d), branch (%d) or Fec number (%d) outside range !", patch, branch, fec));
return -1;
}
if ( (patch > 5) || (branch > 1) || (fec >= GetNfec(patch, branch)) ) {
AliWarning(Form("Patch (%d), branch (%d) or Fec number (%d) outside range !", patch, branch, fec));
return -1;
}
Int_t fecsInBranchA = GetNfec(patch, 0);
if ( branch == 0 )
return (fecsInBranchA - 1 - fec);
else
return (fec + fecsInBranchA);
return -1;
}
Int_t AliTPCmapper::GetEquipmentID(Int_t roc, Int_t padrow, Int_t pad) const
{
Int_t side = GetSideFromRoc(roc);
if ( side < 0 ) return -1;
Int_t sector = GetSectorFromRoc(roc);
if ( sector < 0 ) return -1;
Int_t patch = GetPatch(roc, padrow, pad);
if ( patch < 0 ) return -1;
return GetEquipmentIDfromPatch(side, sector, patch);
}
Int_t AliTPCmapper::GetEquipmentIDsector(Int_t side, Int_t sector, Int_t globalpadrow, Int_t pad) const
{
Int_t patch = GetPatchSector(globalpadrow, pad);
if ( patch < 0 ) return -1;
Int_t roc = GetRocFromPatch(side, sector, patch);
if ( roc < 0 ) return -1;
if ( globalpadrow < fNpadrowIROC )
return GetEquipmentID(roc, globalpadrow, pad);
else
return GetEquipmentID(roc, globalpadrow-fNpadrowIROC, pad);
}
Int_t AliTPCmapper::GetEquipmentIDfromPatch(Int_t side, Int_t sector, Int_t patch) const
{
Int_t roc = GetRocFromPatch(side, sector, patch);
Int_t ddl = 0;
if (patch < 2)
ddl = roc*2 + patch;
else
ddl = (roc-36)*4 + 36*2 + (patch-2);
return ddl+fTpcDdlOffset;
}
Int_t AliTPCmapper::GetPatchFromEquipmentID(Int_t equipmentID) const
{
Int_t retval = 0;
if ( (equipmentID < fTpcDdlOffset) || (equipmentID > 983) ) {
AliWarning(Form("Equipment ID (%d) outside range !", equipmentID));
return -1;
}
if ( ( (int)equipmentID - 840 ) < 0) retval = (equipmentID-768)%2;
else retval = (equipmentID-840)%4 + 2;
return retval;
}
Int_t AliTPCmapper::GetSideFromEquipmentID(Int_t equipmentID) const
{
if ( equipmentID < fTpcDdlOffset ) {
AliWarning(Form("Equipment ID (%d) outside range !", equipmentID));
return -1;
}
if ( equipmentID < 804 ) return 0;
else if ( equipmentID < 840 ) return 1;
else if ( equipmentID < 912 ) return 0;
else if ( equipmentID < 984 ) return 1;
else {
AliWarning(Form("Equipment ID (%d) outside range !", equipmentID));
return -1;
}
}
Int_t AliTPCmapper::GetSectorFromEquipmentID(Int_t equipmentID) const
{
Int_t retval = 0;
if ( (equipmentID < fTpcDdlOffset) || (equipmentID >= fTpcDdlOffset+216) ) {
AliWarning(Form("Equipment ID (%d) outside range !", equipmentID));
return -1;
}
Int_t side = GetSideFromEquipmentID(equipmentID);
if ( side < 0 ) return -1;
if ( (equipmentID - 840) < 0 ) {
if ( side == 0 ) retval = (equipmentID-fTpcDdlOffset)/2;
else retval = (equipmentID-fTpcDdlOffset-18*2)/2;
} else {
if ( side == 0 ) retval = (equipmentID-840)/4;
else retval = (equipmentID-840-18*4)/4;
}
return retval;
}
Int_t AliTPCmapper::GetRocFromEquipmentID(Int_t equipmentID) const
{
Int_t side = GetSideFromEquipmentID(equipmentID);
if ( side < 0 ) return -1;
Int_t sector = GetSectorFromEquipmentID(equipmentID);
if ( sector < 0 ) return -1;
Int_t patch = GetPatchFromEquipmentID(equipmentID);
if ( patch < 0 ) return -1;
return GetRocFromPatch(side, sector, patch);
}
Int_t AliTPCmapper::GetSectorFromRoc(Int_t roc) const
{
if ( roc < 0 ) {
AliWarning(Form("Roc outside range (roc %d) !", roc));
return -1;
} else if ( roc < 18 ) {
return roc;
} else if ( roc < 36 ) {
return (roc-18);
} else if ( roc < 54 ) {
return (roc-36);
} else if ( roc < 72 ) {
return (roc-54);
} else {
AliWarning(Form("Roc outside range (roc %d) !", roc));
return -1;
}
}
Int_t AliTPCmapper::GetSideFromRoc(Int_t roc) const
{
if ( roc < 0 ) {
AliWarning(Form("Roc outside range (roc %d) !", roc));
return -1;
} else if ( roc < 18 ) {
return 0;
} else if ( roc < 36 ) {
return 1;
} else if ( roc < 54 ) {
return 0;
} else if ( roc < 72 ) {
return 1;
} else {
AliWarning(Form("Roc outside range (roc %d) !", roc));
return -1;
}
}
Int_t AliTPCmapper::GetRocFromPatch(Int_t side, Int_t sector, Int_t patch) const
{
if ( (side < 0) || (side >= fNside) ) {
AliWarning(Form("Side outside range (side %d) !", side));
return -1;
}
if ( (sector < 0) || (sector >= fNsector) ) {
AliWarning(Form("Sector outside range (sector %d) !", sector));
return -1;
}
if ( (patch < 0) || (patch >= fNrcu) ) {
AliWarning(Form("Patch (rcu) outside range (patch %d) !", patch));
return -1;
}
if ( side == 0 ) {
if ( patch < 2 ) return sector;
else return 36+sector;
} else {
if ( patch < 2 ) return 18+sector;
else return 54+sector;
}
}
Int_t AliTPCmapper::GetRoc(Int_t side, Int_t sector, Int_t globalpadrow, Int_t pad) const
{
Int_t patch = GetPatchSector(globalpadrow, pad);
if ( patch < 0 ) return -1;
return GetRocFromPatch(side, sector, patch);
}
Bool_t AliTPCmapper::IsIROC(Int_t roc) const
{
if ( roc < 0 ) {
AliWarning(Form("Roc outside range (roc %d) !", roc));
return -1;
} else if ( roc < 36 ) {
return true;
} else if ( roc < 72 ) {
return false;
} else {
AliWarning(Form("Roc outside range (roc %d) !", roc));
return -1;
}
}
Bool_t AliTPCmapper::IsOROC(Int_t roc) const
{
if ( roc < 0 ) {
AliWarning(Form("Roc outside range (roc %d) !", roc));
return -1;
} else if ( roc < 36 ) {
return false;
} else if ( roc < 72 ) {
return true;
} else {
AliWarning(Form("Roc outside range (roc %d) !", roc));
return -1;
}
}