#include "hcategory.h"
#include "hiterator.h"
#include "hpidreconstructor.h"
#include "hpidalgorithm.h"
#include "hpidreconstructorpar.h"
#include "hruntimedb.h"
#include "hpidtrackcand.h"
#include "hades.h"
#include "hkicktrack.h"
#include "hpidtrackfiller.h"
#include "hpidtrackdata.h"
#include "hpidhitdata.h"
#include "hpidfl.h"
#include "hpidphysicsconstants.h"
#include "TROOT.h"
#include "TClass.h"
ClassImp(HPidReconstructor)
#define SAFE_DELETE(A) { if(A) { delete (A); A = NULL; }}
HPidReconstructor::HPidReconstructor(const Option_t par[],Float_t HadronBias)
: HReconstructor("PidReconstructor", "Set of all PID algorithms")
{
setDefault();
setParameters(par);
fHadronBias=HadronBias;
}
HPidReconstructor::HPidReconstructor(const Text_t name[],const Text_t title[],
const Option_t par[], Float_t HadronBias)
: HReconstructor(name, title)
{
setDefault();
setParameters(par);
fHadronBias=HadronBias;
}
HPidReconstructor::~HPidReconstructor(void)
{
bInDelete = kTRUE;
SAFE_DELETE(pitInput);
SAFE_DELETE(pitList);
if(pAlgorithms != NULL)
{
pAlgorithms->SetOwner();
delete pAlgorithms;
}
bInDelete = kFALSE;
}
void HPidReconstructor::setDefault(void)
{
iSelectedMomAlg = -1;
pInputCat = NULL;
pitInput = NULL;
pOutCat = NULL;
bInDelete = kFALSE;
for(Int_t i = 0; i < kMaxParticles; i++)
aParticles[i] = nPID_DUMMY;
pAlgorithms = new TList();
pitList = pAlgorithms->MakeIterator();
iParticles = 0;
iAlgorithms = 0;
iDebug = 0;
iVectPerAlg = 0;
pParams = NULL;
bInitOk = kFALSE;
bCalcPDF = kTRUE;
bCalcCL = kTRUE;
bCalcRelints = kTRUE;
}
void HPidReconstructor::setParameters(const Option_t par[])
{
TString s = par;
Char_t *p;
s.ToUpper();
bCalcPDF = (strstr(s.Data(), "PDF") != NULL);
bCalcCL = (strstr(s.Data(), "CL") != NULL);
bCalcRelints = (strstr(s.Data(), "RELINTS") != NULL);
iDebug = 0;
if((p = strstr(s.Data(), "DEBUG")) != NULL)
{
if(sscanf(p + strlen("DEBUG"), "%d", &iDebug) <= 0)
iDebug = 1;
}
if(strstr(s.Data(),"ALG_KICK")!=NULL) iSelectedMomAlg=ALG_KICK;
if(strstr(s.Data(),"ALG_KICK123")!=NULL) iSelectedMomAlg=ALG_KICK123;
if(strstr(s.Data(),"ALG_SPLINE")!=NULL) iSelectedMomAlg=ALG_SPLINE;
if(strstr(s.Data(),"ALG_REFT")!=NULL) iSelectedMomAlg=ALG_REFT;
if(strstr(s.Data(),"ALG_RUNGEKUTTA")!=NULL) iSelectedMomAlg=ALG_RUNGEKUTTA;
}
Bool_t HPidReconstructor::init(void)
{
HPidAlgorithm *pAlg;
Bool_t bReturn = kTRUE;
Int_t i;
bInitOk = kFALSE;
if(( ! bCalcPDF) && ( ! bCalcCL))
{
Error("init", "No output defined");
return kFALSE;
}
if(bCalcRelints)
{
if((pParams = (HPidReconstructorPar *)gHades->getRuntimeDb()
->getContainer(PIDRECONSTRUCTORPAR_NAME)) == NULL)
{
Error("init", "Cannot get parameters: %s", PIDRECONSTRUCTORPAR_NAME);
return kFALSE;
}
}
if((pInputCat = HPidTrackCand::buildPidTrackCandCategory()) == NULL)
{
Error("init", "Cannot build HPidTrackCand Category");
return kFALSE;
}
if((pitInput = (HIterator *)pInputCat->MakeIterator()) == NULL)
{
Error("init", "Cannot make an iterator for HPidTrackCand Category");
return kFALSE;
}
if(pAlgorithms->GetSize() < 1)
{
Error("init", "At least one algorithm must be set");
return kFALSE;
}
if(iParticles < 1)
{
Error("init", "At least one particle id must be set");
return kFALSE;
}
i = pAlgorithms->GetSize();
iVectPerAlg = 1;
if((bCalcPDF) && (bCalcCL))
{
i *= 2;
iVectPerAlg = 2;
}
i++;
iAlgorithms = i;
if((pOutCat = HPidCandidate::buildPidCandidateCategory()) == NULL)
{
Error("init", "Cannot build HPidCandidate category");
return kFALSE;
}
pitList->Reset();
while((pAlg = (HPidAlgorithm *)pitList->Next()) != NULL)
bReturn &= pAlg->init();
bInitOk = bReturn;
print();
return bReturn;
}
Bool_t HPidReconstructor::reinit(void)
{
HPidAlgorithm *pAlg;
Bool_t bReturn = bInitOk;
if(bInitOk == kFALSE)
Warning("reinit", "HPidTrackFiller::init() didn't succeed");
pitList->Reset();
while((pAlg = (HPidAlgorithm *)pitList->Next()) != NULL)
bReturn &= pAlg->reinit();
if(bInitOk)
bInitOk = bReturn;
return bReturn;
}
Bool_t HPidReconstructor::finalize(void)
{
HPidAlgorithm *pAlg;
Bool_t bReturn = kTRUE;
pitList->Reset();
while((pAlg = (HPidAlgorithm *)pitList->Next()) != NULL)
bReturn &= pAlg->finalize();
return bReturn;
}
Int_t HPidReconstructor::execute(void)
{
HPidAlgorithm *pAlg;
HPidTrackCand *pTrack;
HPidCandidate *pCand;
Int_t iAlgs;
Float_t *pPDF;
Float_t *pCL;
if(bInitOk == kFALSE)
{
Error("execute", "Class not initialized");
return -1;
}
if(pitInput == NULL)
{
Error("execute", "pitInput == NULL");
return 0;
}
pOutCat->Clear();
pitInput->Reset();
while((pTrack = (HPidTrackCand *)pitInput->Next()) != NULL)
{
if(pTrack->getTrackData()->bIsAccepted[iSelectedMomAlg]==kFALSE) continue;
if(pTrack->getHitData()->iSystem==-1) continue;
if(iDebug)
printf(".");
if((pCand = getNextSlot()) == NULL)
{
Error("HPidReconstructor::execute()","No new slot in catPidCandidate available");
return 0;
}
pCand->setTrackCandIndex(pInputCat->getIndex(pTrack));
pCand->setFlagField(pTrack->getFlagField());
pitList->Reset();
iAlgs = 0;
while((pAlg = (HPidAlgorithm *)pitList->Next()) != NULL)
{
pPDF = pCL = NULL;
if(bCalcPDF)
{
pPDF = pCand->getValuesVectorByIndex(iAlgs);
pCand->setAlgorithmIdByIndex(iAlgs, pAlg->getAlgId());
iAlgs++;
}
if(bCalcCL)
{
pCL = pCand->getValuesVectorByIndex(iAlgs);
pCand->setAlgorithmIdByIndex(iAlgs, pAlg->getAlgId() + CL_ALOGRITHM_OFFSET);
iAlgs++;
}
if(iDebug > 1)
printf("Alg: %d %p %p\n", iAlgs, pPDF, pCL);
Short_t dummy;
pAlg->execute(pTrack, pPDF, pCL, dummy);
if(pPDF != NULL)
normalize(pPDF, iParticles);
}
calculateRelInts(pTrack, pCand);
}
if(iDebug)
printf("\n");
return 0;
}
HPidCandidate* HPidReconstructor::getNextSlot(void)
{
HPidCandidate *pOut = NULL;
static HLocation locDummy;
if(pOutCat == NULL)
{
Error("getNextSlot", "Output category not set: use init/reinit");
return NULL;
}
if((pOut = (HPidCandidate *) pOutCat->getNewSlot(locDummy)) == NULL)
{
Error("getNextSlot", "No new slot");
return NULL;
}
pOut = (HPidCandidate *) new (pOut) HPidCandidate(iParticles,iAlgorithms,0,iSelectedMomAlg);
pOut->setTrackCandIndex(-1);
pOut->setParticleIds( aParticles, iParticles );
return pOut;
}
void HPidReconstructor::calculateRelInts(HPidTrackCand *pTrack,
HPidCandidate *pCand)
{
Int_t iPart;
Float_t fTheta, fMom;
Int_t iMax = pCand->getNAlgorithms() - 1;
Int_t iSys, iSect;
pCand->setAlgorithmIdByIndex(iMax, algRelInt);
HPidTrackData* pTrackData = pTrack->getTrackData();
HPidHitData* pHitData = pTrack->getHitData();
if(!pTrackData->bIsAccepted[iSelectedMomAlg])
{
Error("HPidReconstructor::calculateRelints()","The current track is not accepted. Tis should be intercepted");
exit(-1);
}
fMom = pTrackData->fMomenta[iSelectedMomAlg];
if(fMom<0)
{
Error("HPidReconstructor::calculateRelints()","The current track has negative momentum");
exit(-1);
}
fTheta = pHitData->fMdcTheta;
iSys = pHitData->iSystem;
iSect = pHitData->nSector;
Float_t *fRelInt = pCand->getValuesVectorByIndex(iMax);
if(bCalcRelints)
{
for(iPart = 0;
(iPart < kMaxParticles) && (aParticles[iPart] != nPID_DUMMY);
iPart++)
{
fRelInt[iPart] = pParams->getIntensity(aParticles[iPart],
iSys, iSect, fMom, fTheta);
Float_t scale_protons = fHadronBias;
Float_t scale_piplus = fHadronBias;
Float_t scale_piminus = fHadronBias;
Float_t scale_electrons = 1.0;
Float_t scale_positrons = 1.0;
Float_t scale_fakeminus = 1.0;
Float_t scale_fakeplus = 1.0;
Float_t scale_default = 1.0;
switch (aParticles[iPart]){
case 14:
fRelInt[iPart]*=scale_protons;
break;
case 8:
fRelInt[iPart]*=scale_piplus;
break;
case 9:
fRelInt[iPart]*=scale_piminus;
break;
case 3:
fRelInt[iPart]*=scale_electrons;
break;
case 2:
fRelInt[iPart]*=scale_positrons;
break;
case -1:
fRelInt[iPart]*=scale_fakeminus;
break;
case -2:
fRelInt[iPart]*=scale_fakeplus;
break;
default:
fRelInt[iPart]*=scale_default;
break;
}
}
}
else
{
for(iPart = 0;
(iPart < kMaxParticles) && (aParticles[iPart] != nPID_DUMMY);
iPart++)
{
fRelInt[iPart] = 1.0;
}
}
}
Bool_t HPidReconstructor::addAlgorithm(HPidAlgorithm *pAlg)
{
if(pAlg == NULL)
{
Error("addAlgorithm", "NULL algorithm");
return kFALSE;
}
if(getAlgorithm(pAlg->getAlgId()) != NULL)
{
Error("addAlgorithm", "Algorithm %d already in the set",
pAlg->getAlgId());
return kFALSE;
}
pAlgorithms->AddLast(pAlg);
pAlg->setReconstructor(this);
return kTRUE;
}
HPidAlgorithm* HPidReconstructor::getAlgorithm(const TString &sName) const
{
HPidAlgorithm *pAlg;
pitList->Reset();
while((pAlg = (HPidAlgorithm *)pitList->Next()) != NULL)
{
if(sName.CompareTo(pAlg->getName()) == 0)
return pAlg;
}
return NULL;
}
HPidAlgorithm* HPidReconstructor::getAlgorithm(EnumPidAlgorithm_t eId) const
{
HPidAlgorithm *pAlg;
pitList->Reset();
while((pAlg = (HPidAlgorithm *)pitList->Next()) != NULL)
{
if(eId == pAlg->getAlgId())
return pAlg;
}
return NULL;
}
Bool_t HPidReconstructor::removeAlgorithm(HPidAlgorithm *pAlg)
{
if(bInDelete)
return kTRUE;
if(pAlgorithms->Remove(pAlg) == NULL)
{
Error("removeAlgorithm", "Algorithm %p not in the set", pAlg);
return kFALSE;
}
return kTRUE;
}
Bool_t HPidReconstructor::removeAlgorithm(const TString &sName)
{
HPidAlgorithm *pAlg;
if(bInDelete)
return kTRUE;
if((pAlg = getAlgorithm(sName)) == NULL)
{
Error("removeAlgorithm", "Algorithm %s not in the set", sName.Data());
return kFALSE;
}
return removeAlgorithm(pAlg);
}
Bool_t HPidReconstructor::removeAlgorithm(EnumPidAlgorithm_t eId)
{
HPidAlgorithm *pAlg;
if(bInDelete)
return kTRUE;
if((pAlg = getAlgorithm(eId)) == NULL)
{
Error("removeAlgorithm", "Algorithm %d not in the set", eId);
return kFALSE;
}
return removeAlgorithm(pAlg);
}
Short_t HPidReconstructor::getParticleId(Int_t iPos) const
{
if((iPos < 0) || (iPos > iParticles))
{
Error("getParticleId", "%d out of bounds", iPos);
return -1;
}
return aParticles[iPos];
}
Int_t HPidReconstructor::getParticleIndex(Short_t nType) const
{
for(Int_t i = 0; i < kMaxParticles; i++)
{
if(aParticles[i] == nType)
return i;
}
return -1;
}
Int_t HPidReconstructor::addParticleId(Short_t nType)
{
for(Int_t i = 0; i < kMaxParticles; i++)
{
if(aParticles[i] == nType)
{
Error("addParticleId", "Particle %d already in the array", nType);
return -2;
}
if(aParticles[i] == nPID_DUMMY)
{
aParticles[i] = nType;
if(iParticles <= i)
iParticles = i + 1;
return i;
}
}
Error("addParticleId", "No place for new particle type in the array");
return -1;
}
void HPidReconstructor::setParticleId(Int_t iPos, Short_t nType)
{
if((iPos < 0) || (iPos >= kMaxParticles))
Error("setParticleId", "%d out of bounds", iPos);
else
{
aParticles[iPos] = nType;
if(iParticles <= iPos)
iParticles = iPos + 1;
}
}
void HPidReconstructor::setParticleIds(Short_t aIds[], Int_t iSize)
{
if(iSize <= 0)
{
Error("setParticleIds", "iSize <= 0");
return;
}
if(iSize > kMaxParticles)
{
Warning("setParticleIds", "Only %d from %d ids used", kMaxParticles,
iSize);
iSize = kMaxParticles;
}
memcpy(aParticles, aIds, iSize * sizeof(Short_t));
iParticles = iSize;
for(Int_t i = iParticles; i < kMaxParticles; i++)
aParticles[i] = nPID_DUMMY;
fprintf( stderr, "iParticles = %i, kMaxParticles = %i, IDs : ", iParticles, kMaxParticles );
for( Int_t loop = 0; loop < iParticles; loop++ ) fprintf( stderr, "%i ", aParticles[loop] );
fprintf(stderr, "\n" );
}
void HPidReconstructor::setDefaultParticleIds(void)
{
Short_t aPartIds[] =
{
2,
3,
8,
9,
14,
45,
11,
12,
HPidPhysicsConstants::fakeNeg(),
HPidPhysicsConstants::fakePos()
};
setParticleIds(aPartIds, sizeof(aPartIds) / sizeof(Short_t));
}
void HPidReconstructor::print(void) const
{
HPidAlgorithm *pAlg;
Int_t i;
printf("PidReconstructor:print():\nParticles: ");
for(i = 0; (i < iParticles) && (aParticles[i] >= 0); i++)
printf(" %d", aParticles[i]);
printf("\nOutputs : %s %s\n", (bCalcPDF) ? "PDF" : "",
(bCalcCL) ? "CL" : "");
printf("\nRelints: %s \n", (bCalcRelints) ? "yes" : "no");
printf("\nAlgorithms:\n");
pitList->Reset();
while((pAlg = (HPidAlgorithm *)pitList->Next()) != NULL)
{
printf("* %d %s, weight: %f\n", pAlg->getAlgId(),
pAlg->getName().Data(), pAlg->getWeight());
pAlg->print();
}
}
void HPidReconstructor::normalize(Float_t af[], UInt_t iSize)
{
Float_t fSum = 0.0;
UInt_t i;
for(i = 0; i < iSize; i++)
{
if(af[i] >= 0.0f)
fSum += af[i];
}
if((fSum > 0.0f) && (fSum != 1.0f))
{
fSum = 1.0f / fSum;
for(i = 0; i < iSize; i++)
{
if(af[i] >= 0.0f)
af[i] *= fSum;
}
}
}
Last change: Sat May 22 13:07:23 2010
Last generated: 2010-05-22 13:07
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.