// @(#)$Id: hpidcandidate.cc,v 1.12 2006/11/24 16:00:29 christ Exp $
//*-- Author : Marcin Jaskula 27/07/2002
// Modified : Marcin Jaskula 06/09/2002
// Modified : Marcin Jaskula 16/09/2002
// - now this is an abstract class
// Modified : Marcin Jaskula 31/10/2002
// - buildPidCandidateCategory moved from global to static function
// Modified : Marcin Jaskula 01/12/2002
// - new method getPidCandidate()
// - getCandidate() rewritten
// Modified : Marcin Jaskula 18/04/2003
// - functions for calculation of the merged PDF and Bayes added
// Redesigned by Tassilo Christ to reduce number of classes to one by managing
// size of values array dynamically (HCategory has now the possibility to set
// a flag "hasDynamicObjects" which allows to stream objects of a size which
// isn't known at compile-time.
//
//_HADES_CLASS_DESCRIPTION
////////////////////////////////////////////////////////////////////////////////
//
// HPidCandidate
//
//
// The container consists of all values returend by PidAlgorithms
// for a specific HPidTrackCand
// The idea of this container was to make it as flexible as possible and do not
// fix the number and type of algorithms and reconstructed partices for which
// the values are stored. The organization of the data in the container looks
// like:
//
// ...... pAlogrithms ......
// . -------------------------
// . | |
// p | |
// P | |
// a | |
// r | |
// t | pValues |
// i | |
// c | |
// l | |
// e | |
// s | |
// . | |
// . | |
// . -------------------------
//
// Ids of used algorithms are stored in aAlogrithms vector constisting of
// values from EnumPidAlgorithm_t (piddef.h). Ids larger then 100 mean
// values for CL for algorihm (id - 100)
// Ids of particles are stored in aParticles vector (from Geant).
//
//
// The values returned from the algorithms are stored in 2D array
// aValues[PID_ALG][PARTICLE] - where indices corresponds to values in
// aAlogrithms and aParticles vectors.
//
////////////////////////////////////////////////////////////////////////////////
#pragma implementation
#include "hpidcandidate.h"
#include "hpidtrackcand.h"
#include "hpidfl.h"
#include "hades.h"
#include "hevent.h"
#include "hlinearcategory.h"
#include <iostream>
#include <TError.h>
#include <TROOT.h>
using namespace std;
// -----------------------------------------------------------------------------
ClassImp(HPidCandidate)
// -----------------------------------------------------------------------------
HPidCandidate::HPidCandidate(void)
{
//default constructor to satisfy root!
}
HPidCandidate::HPidCandidate(Short_t numpart, Int_t numalgs, Int_t candIndex, Int_t momAlgIndex)
{
NUM_PARTICLES=numpart;
NUM_ALGORITHMS=numalgs;
NUM_VALUES=numpart*numalgs;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Here the "dynamic" part of memory allocation occurs. At compile time the number of algorithms and
// particles isn't known - so we need to build the array at runtime.
// As we overload the Clear-Function (see below) and set "DynamicObjects" to kTRUE the HLinearCategory
// does the cleanup for us in HLinearCategory::Clear(Option_t). When the flag is set kTRUE it calls the
// Clear Function of HPidCandidate which frees the memory again.
// (See implementation of HLinearCategory::Clear(Otion_t)
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
aAlgorithms.Set(NUM_ALGORITHMS);
aParticles.Set(NUM_PARTICLES);
aValues.Set(NUM_PARTICLES*NUM_ALGORITHMS);
iTrackCandIndex = candIndex;
nMomAlgIndex = momAlgIndex;
Reset();
}
// -----------------------------------------------------------------------------
HPidCandidate::~HPidCandidate(void)
{
// Default destructor. Do not do anything
}
// -----------------------------------------------------------------------------
//This function frees the memory occupied by objects of type HPidCandidate in
//the TClonesArray.
void HPidCandidate::Clear(Option_t* opt)
{
aAlgorithms.Set(0);
aParticles.Set(0);
aValues.Set(0);
}
// Clears the arrays setting them to the default values
void HPidCandidate::Reset(void)
{
Int_t i, iMax;
if((iMax = getNAlgorithms()) > 0 && aAlgorithms.GetSize()== iMax)
{
for(i = 0; i < iMax; i++)
{
aAlgorithms[i] = algNotSet;
}
}
else Error("HPidCandidate::Reset","There was a mismatch in the number of algorithms and the size of the array");
if(((iMax = getNParticles()) > 0) && (aParticles.GetSize() ==iMax))
{
for(i = 0; i < iMax; i++)
aParticles[i] = -99;
}
else Error("HPidCandidate::Reset","There was a mismatch in the number of particles and the size of the array");
iMax = getNParticles() * getNAlgorithms();
if(iMax == aValues.GetSize())
{ for(i = 0; i < iMax; i++)
{
aValues[i] = nUNKNOWN;
}
}
else Error("HPidCandidate::Reset","There was a mismatch in the number of values and the size of the array");
}
// -----------------------------------------------------------------------------
Int_t HPidCandidate::print(void) const
{
UInt_t iAlg;
UInt_t iPart;
Bool_t arraysOK=kTRUE;
printf(" P \ A |");
if(aAlgorithms.GetSize() != (Int_t)getNAlgorithms())
{
arraysOK=kFALSE;
printf("Mismatch in size of algorithms array");
}
if(aParticles.GetSize() != (Int_t)getNParticles())
{
arraysOK=kFALSE;
printf("Mismatch in size of particles array");
}
if((aValues.GetSize() != (Int_t)getNValues()))
{
arraysOK=kFALSE;
printf("Mismatch in size of values array");
}
if(arraysOK)
{
for(iAlg = 0; iAlg < getNAlgorithms(); iAlg++)
printf(" %6d |", aAlgorithms[iAlg]);
printf("n-------+");
for(iAlg = 0; iAlg < getNAlgorithms(); iAlg++)
printf("---------+");
printf("n");
for(iPart = 0; iPart < getNParticles(); iPart++)
{
printf("%6d |", aParticles[iPart]);
for(iAlg = 0; iAlg < getNAlgorithms(); iAlg++)
printf("%8.4f |", aValues[getValuePositionByIndex(iAlg, iPart)]);
printf("n");
}
}
printf("n");
return 0; // allow to use in T.Draw(...)
}
// -----------------------------------------------------------------------------
//Return the HPidTrackCandidate object that was the origin of the HPidCandidate
HPidTrackCand* HPidCandidate::getTrackCandidate(HCategory *pCat) const
{
// Returns HPidTrackCand object corresponding to iTrackCandIndex (if it exists)
// Works when pCat is set or gHades->getCurrentEvent() is accessible
if(iTrackCandIndex < 0)
return NULL;
return HPidFL::getTrackCand(iTrackCandIndex, pCat);
}
// -----------------------------------------------------------------------------
// Set algorithm Id eAlg at uiPos. Arrays bounds are checked
void HPidCandidate::setAlgorithmIdByIndex(UInt_t uiPos, Short_t eAlg)
{
if((aAlgorithms.GetSize()<(Int_t)NUM_ALGORITHMS) || (uiPos >=NUM_ALGORITHMS))
{
Error("setAlgorithmIdByIndex", "out of bound: [0, %d)", NUM_ALGORITHMS);
return;
}
aAlgorithms[uiPos] = eAlg;
}
// -----------------------------------------------------------------------------
// Set whole vector of algoritms. The input array must have getNAlgorithms() members
void HPidCandidate::setAlgorithmIds(Short_t aeAlgs[])
{
if(sizeof(aeAlgs)/sizeof(Short_t)!=NUM_ALGORITHMS)
{
::Error("HPidCandidate::setAlgorithms","Number of algorithms not matching selection!");
return;
}
if(aAlgorithms.GetSize() != (Int_t)NUM_ALGORITHMS)
{
Error("setAlgorithms", "Mismatch in size of algorithms array");
return;
}
aAlgorithms.Set(NUM_ALGORITHMS,aeAlgs);
}
// -----------------------------------------------------------------------------
// Get algorithm Id from the array of algorithms at position uiPos.
// algNotSet is return if uiPos is out of bounds.
Int_t HPidCandidate::getAlgorithmIdByIndex(UInt_t uiPos) const
{
if((aAlgorithms.GetSize()<=(Int_t)uiPos) || (uiPos >= NUM_ALGORITHMS))
{
Error("getAlgorithmIdByIndex", "out of bound: [0, %d)", NUM_ALGORITHMS);
return algNotSet;
}
return aAlgorithms[uiPos];
}
// -----------------------------------------------------------------------------
Int_t HPidCandidate::getAlgorithmIndexById(Int_t eAlg) const
{
// Find the position of the eAlg algorithm in the array of algorithms.
// Returns -1 if algorithm not set.
// Existing of the proper algorithms array is checked
Int_t i, iMax;
iMax = getNAlgorithms();
for(i = 0; i < iMax; i++)
{
if(aAlgorithms[i] == eAlg)
return i;
}
return -1;
}
// -----------------------------------------------------------------------------
void HPidCandidate::setParticleIdByIndex(UInt_t uiPos, Short_t nPart)
{
// Sets particle id nPart in the array of particle ids at position uiPos. Array bounds are checked.
if((aParticles.GetSize() <= (Int_t)uiPos) || (uiPos >= getNParticles()))
{
Error("setParticleIdByIndex", "out of bound: [0, %d)", getNParticles());
return;
}
aParticles[uiPos] = nPart;
}
// -----------------------------------------------------------------------------
// Set whole vector of particle Ids. The input array must have getNParticles() members
void HPidCandidate::setParticleIds(Short_t anPart[], Int_t nrOfParticles)
{
if( nrOfParticles != (Int_t)NUM_PARTICLES )
{
::Error("HPidCandidate::setParticleIds","Number of particles does not match");
return;
}
if(aParticles.GetSize() != nrOfParticles)
{
Error("setParticleIds", "Mismatch in size of particles array");
return;
}
aParticles.Set(NUM_PARTICLES,anPart);
}
// -----------------------------------------------------------------------------
Short_t HPidCandidate::getParticleIdByIndex(UInt_t uiPos) const
{
// Gets particle id nPart at position uiPos in the array of particle ids used.
// Array bounds are checked and -10 returned in case of out of bounds.
if((aParticles.GetSize()<=(Int_t)uiPos) || (uiPos >= getNParticles()))
{
Error("getParticleIdByIndex", "out of bound: [0, %d)", getNParticles());
return -10;
}
return aParticles[uiPos];
}
// -----------------------------------------------------------------------------
Int_t HPidCandidate::getParticleIndexById(Short_t nPartId) const
{
// Find the position of the particle with PID nPartId in the array of involved species.
// Returns -1 if particle id not set.
// Existing of a propper particlesId array is checked.
Int_t i, iMax;
iMax = getNParticles();
for(i = 0; i < iMax; i++)
{
if(aParticles[i] == nPartId)
return i;
}
return -1;
}
// -----------------------------------------------------------------------------
void HPidCandidate::setValueById(Int_t eAlg, Short_t nPartId,
Float_t fVal)
{
// Set value in the array of pdf-values for the specified algorithm and particle Id
Int_t iPart, iAlg;
if(aValues.GetSize()!=(Int_t)(getNParticles())*(Int_t)(getNAlgorithms()))
{
Error("setValueById", "Mismatch in size of values array");
return;
}
if(((iAlg = getAlgorithmIndexById(eAlg)) < 0)
|| ((iPart = getParticleIndexById(nPartId)) < 0))
{
return;
}
aValues[getValuePositionByIndex(iAlg, iPart)] = fVal;
}
// -----------------------------------------------------------------------------
void HPidCandidate::setValueByIndex(UInt_t uiAlgIdx, UInt_t uiPartIdx,
Float_t fVal)
{
// Set value fVal for known position in the values array
Int_t i;
if((i = getValuePositionByIndex(uiAlgIdx, uiPartIdx)) < 0)
Error("setValueByIndex", "Out of bounds");
else
aValues[i] = fVal;
}
// -----------------------------------------------------------------------------
Float_t HPidCandidate::getValueById(Int_t eAlg, Short_t nPartId) const
{
// Returns value computed by algorithm eAlg for the particle nPartId
// or 0.0 if algorithm or particle not in the arrays
#warning This implementation has to be extended to strict checking
Int_t iPart, iAlg;
if(((iAlg = getAlgorithmIndexById(eAlg)) < 0)
|| ((iPart = getParticleIndexById(nPartId)) < 0))
{
return 0.0f;
}
return aValues[getValuePositionByIndex(iAlg, iPart)];
}
// -----------------------------------------------------------------------------
Float_t HPidCandidate::getValueByIndex(UInt_t uiAlgIdx, UInt_t uiPartIdx) const
{
// Returns pdf-value for a specific particle and algorithm index in the values array or 0.0 if out of bound
#warning This implementation has to be extended to strict checking
Int_t i = getValuePositionByIndex(uiAlgIdx, uiPartIdx);
return (i < 0 ? -1.0f : aValues[i]);
}
// -----------------------------------------------------------------------------
HCategory* HPidCandidate::buildPidCandidateCategory()
{
// Static function for making the category for the specified class name.
HCategory *pCat;
static char* sCatName="HPidCandidate";
HEvent *pEvent;
if((gHades == NULL) || ((pEvent = gHades->getCurrentEvent()) == NULL))
{
::Error("buildPidCandidateCategory", "Cannot access current event");
return NULL;
}
if((pCat = pEvent->getCategory(catPidCandidate)) != NULL)
{
((HLinearCategory*)pCat)->setDynamicObjects(kTRUE);
return pCat;
}
if((pCat = new HLinearCategory(sCatName, 1000)) == NULL)
{
::Error("HPidCandidate::buildPidCandidateCategory",
"Cannot create new category");
return NULL;
}
((HLinearCategory*)pCat)->setDynamicObjects(kTRUE);
//This category stores a variable amount of data. Within one DST the size of the
//array is fixed (nAlgs times nParticles) but it is NOT known at compiletime!
//Therefor we declare this category to be dynamic in size. This implies that the
//Clear() function of the category is called with option "C" which calls the Clear()
//function of all HPidCandidates in the TClonesArray
pEvent->addCategory(catPidCandidate, pCat, "Pid");
return pCat;
}
// -----------------------------------------------------------------------------
Int_t HPidCandidate::calcBayesVector(Float_t fOut[],const Int_t aAlgs[], Int_t iAlgs)
{
// Calculate Bayes values for the all particles and the algorithms
// with ids from array aAlgs of size iAlgs. If iAlgs==0 all available algorithms
// are used - in this case aAlgs may be NULL. The output values are stored
// in fOut array, which size should be suitable to contain all values.
// fOut must not be NULL. The function returns the number of filled elements
// in fOut array
if(fOut == NULL)
{
Error("calcBayesVector", "fOut == NULL");
return 0;
}
Int_t iRelInt;
if((iRelInt = getAlgorithmIndexById(algRelInt)) < 0)
{
Error("calcBayesVector", "no algRelInt in the container");
return 0;
}
//Float_t *fRelInt = getValuesVectorByIndex(iRelInt);
Int_t i;
Int_t iMax = getNParticles();
if((i = calcMergedPDFVector(fOut, aAlgs, iAlgs)) <= 0)
return i;
Float_t fSum = 0.0f;
// calc products of joined PDFs with relative intensities
for(i = 0; i < iMax; i++)
{
if(fOut[i] < 0.0)
continue;
if(getValueByIndex(iRelInt,i) < 0.0)
{
setValueByIndex(iRelInt,i,0.0);
Error("HPidCandidate::calcBayesVector()","Negatiev relint value detected and resetted!");
}
fOut[i] *= getValueByIndex(iRelInt,i) ;
fSum += fOut[i];
}
// renormalize
if((fSum > 0.0f) && (fSum != 1.0f))
{
fSum = 1.0f / fSum;
for(i = 0; i < iMax; i++)
{
if(fOut[i] <= 0.0f)
continue;
fOut[i] *= fSum;
}
}
return iMax;
}
// -----------------------------------------------------------------------------
#define FILL_ARRAY() \
if(iAlg0 > 0) aAlg[i++] = iAlg0; \
if(iAlg1 > 0) aAlg[i++] = iAlg1; \
if(iAlg2 > 0) aAlg[i++] = iAlg2; \
if(iAlg3 > 0) aAlg[i++] = iAlg3; \
if(iAlg4 > 0) aAlg[i++] = iAlg4; \
if(iAlg5 > 0) aAlg[i++] = iAlg5; \
if(iAlg6 > 0) aAlg[i++] = iAlg6; \
if(iAlg7 > 0) aAlg[i++] = iAlg7; \
if(iAlg8 > 0) aAlg[i++] = iAlg8; \
if(iAlg9 > 0) aAlg[i++] = iAlg9
// -----------------------------------------------------------------------------
Int_t HPidCandidate::calcBayesVectorFromAlgSelection(Float_t fOut[], Int_t iAlg0,
Int_t iAlg1, Int_t iAlg2, Int_t iAlg3,
Int_t iAlg4, Int_t iAlg5, Int_t iAlg6,
Int_t iAlg7, Int_t iAlg8, Int_t iAlg9)
{
// Calculate Bayes values for the all particles and the algorithms
// given as the arguments. If all iAlg? == 0 all available algorithms
// are used. For more info see the descr. of the previous method, which
// is called internally.
Int_t aAlg[10];
Int_t i = 0;
FILL_ARRAY();
return calcBayesVector(fOut, aAlg, i);
}
// -----------------------------------------------------------------------------
Float_t HPidCandidate::getBayesValue(Short_t nPID,
const Int_t aAlgs[], Int_t iAlgs)
{
// Return the Bayes value for the give particle species nType.
// For commends to the eAlgs and iAlgs see calcBayesVect descr.
// In case of any error -1 is returned
Int_t iIdx;
if((iIdx = getParticleIndexById(nPID)) < 0)
{
Error("getBayesVect", "Particle %d not in the container", nPID);
return -1.0f;
}
Float_t *fArr;
if((fArr = new Float_t[getNParticles()]) == NULL)
{
Error("getBayesVect", "Cannot create temp array");
return -1.0f;
}
Float_t fVal;
if(calcBayesVector(fArr, aAlgs, iAlgs) <= 0)
fVal = -1.0f;
else
fVal = fArr[iIdx];
delete [] fArr;
return fVal;
}
// -----------------------------------------------------------------------------
Float_t HPidCandidate::getBayesValueFromAlgSelection(Short_t nPID, Int_t iAlg0,
Int_t iAlg1, Int_t iAlg2, Int_t iAlg3,
Int_t iAlg4, Int_t iAlg5, Int_t iAlg6,
Int_t iAlg7, Int_t iAlg8, Int_t iAlg9)
{
// Return the Bayes value for the give particle species nPID and the given
// set of algorithms. For more info see descr. of getBayesVect and calcBayesVect
// methods.
Int_t aAlg[10];
Int_t i = 0;
FILL_ARRAY();
return getBayesValue(nPID, aAlg, i);
}
// -----------------------------------------------------------------------------
Int_t HPidCandidate::calcMergedPDFVector(Float_t fOut[],
const Int_t aAlgs[], Int_t iAlgs) const
{
// Calculate merged propability density for the all particles and the algorithms
// with ids from array aAlgs of size iAlgs. If iAlgs==0 all available algorithms
// are used - in this case aAlgs may be NULL. The output values are stored
// in fOut array, which size should be suitable to contain all values.
// fOut must not be NULL. The function returns the number of filled elements
// in fOut array
if(fOut == NULL)
{
Error("calcMergedPDFVector", "fOut == NULL");
return 0;
}
UInt_t iMax = getNParticles();
UInt_t i;
Int_t a, c, k;
Float_t pdf_factor=0.0;
// clear the output
for(i = 0; i < iMax; i++)
fOut[i] = -1.0f;
if(iAlgs <= 0)
{
c = 0;
// loop over all algorithms and choose the PDF vectors
for(k = 0; k < (Int_t)getNAlgorithms(); k++)
{
if(((a = getAlgorithmIdByIndex(k)) <= LAST_COMMON_ALG)
|| (a >= CL_ALOGRITHM_OFFSET))
{
continue;
}
#warning This takes long and can be done much more efficiently
//cout << "Algor ID is: " << a << endl;
// calc the products - changed by Tassilo - check this later!
/*
af = getValuesVectorByIndex(k);
for(i = 0; i < iMax; i++)
{
if(af[i] >= 0.0f)
{
if(fOut[i] < 0.0f)
fOut[i] = af[i];
else
fOut[i] *= af[i];
}
}
*/
for(i = 0; i < iMax; i++)
{
pdf_factor=getValueByIndex(k,i);
if(pdf_factor >= 0.0f) // do not consider negative probability densities!! They indicate void statements
{
if(fOut[i] < 0.0f)
fOut[i] = pdf_factor;
else
fOut[i] *= pdf_factor;
}
}
c++;
}
if(c <= 0)
{
Error("calcMergedPDFVector", "No PDF vector found");
goto lab_Error;
}
}
else
{
for(c = 0; c < iAlgs; c++)
{
if((k = getAlgorithmIndexById(aAlgs[c])) < 0)
{
Error("calcMergedPDFVector", "No values for algorithm %d", aAlgs[c]);
goto lab_Error;
}
// calc the products - changed by Tassilo check this!
/*
af = getValuesVectorByIndex(k);
for(i = 0; i < iMax; i++)
{
if(af[i] >= 0.0f)
{
if(fOut[i] < 0.0f)
fOut[i] = af[i];
else
fOut[i] *= af[i];
}
}
*/
for(i = 0; i < iMax; i++)
{
pdf_factor=getValueByIndex(k,i);
if(pdf_factor >= 0.0f) // do not consider negative probability densities!! They indicate void statements
{
if(fOut[i] < 0.0f)
fOut[i] = pdf_factor;
else
fOut[i] *= pdf_factor;
}
}
}
}
return iMax;
lab_Error:
for(i = 0; i < iMax; i++)
fOut[i] = -1.0f;
return 0;
}
// -----------------------------------------------------------------------------
Int_t HPidCandidate::calcMergedPDFVectorFromAlgSelection(Float_t fOut[], Int_t iAlg0,
Int_t iAlg1, Int_t iAlg2, Int_t iAlg3,
Int_t iAlg4, Int_t iAlg5, Int_t iAlg6,
Int_t iAlg7, Int_t iAlg8, Int_t iAlg9) const
{
// Calculate merged propability for the all particles and the algorithms
// given as the arguments. If all iAlg? == 0 all available algorithms
// are used. For more info see the descr. of the previous method, which
// is called internally.
Int_t aAlg[10];
Int_t i = 0;
FILL_ARRAY();
return calcMergedPDFVector(fOut, aAlg, i);
}
// -----------------------------------------------------------------------------
Float_t HPidCandidate::getMergedPDFValue(Short_t nPID,
const Int_t aAlgs[], Int_t iAlgs) const
{
// Return the merged propability value for the give particle species nPID.
// For commends to the eAlgs and iAlgs see calcMergedVect descr.
// In case of any error -1 is returned
Int_t iIdx;
if((iIdx = getParticleIndexById(nPID)) < 0)
{
Error("getMergedPDFValue", "Particle %d not in the container", nPID);
return -1.0f;
}
Float_t *fArr;
if((fArr = new Float_t[getNParticles()]) == NULL)
{
Error("getMergedPDFValue", "Cannot create temp array");
return -1.0f;
}
Float_t fVal;
if(calcMergedPDFVector(fArr, aAlgs, iAlgs) <= 0)
fVal = -1.0f;
else
fVal = fArr[iIdx];
delete [] fArr;
return fVal;
}
// -----------------------------------------------------------------------------
Float_t HPidCandidate::getMergedPDFValueFromAlgSelection(Short_t nPID, Int_t iAlg0,
Int_t iAlg1, Int_t iAlg2, Int_t iAlg3,
Int_t iAlg4, Int_t iAlg5, Int_t iAlg6,
Int_t iAlg7, Int_t iAlg8, Int_t iAlg9) const
{
// Return the merged propability value for the give particle species nPID.
// and the set of algorithms. For more info see descr. of getMergedPDFValue
// and calcMergedVect methods.
Int_t aAlg[10];
Int_t i = 0;
FILL_ARRAY();
cout << "Calling fobidden function!" <<endl ;
return getMergedPDFValue(nPID, aAlg, i);
}
ROOT page - Class index - Class Hierarchy - Top of the page
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.