// @(#)$Id: hpidparticle.cc,v 1.19 2006/12/08 15:36:59 christ Exp $
//*-- Author : Marcin Jaskula 30/11/2002
// Modified : Marcin Jaskula 11/11/2002
// fExpMass added
// Modified : Marcin Jaskula 01/12/2002
// new methods getIndex(), getPidParticle()
// new interface in getPidCandidate()
// Modified : Marcin Jaskula 25/02/2003
// new methods getTrackCand() and getKickTrack()
// Modified : Marcin Jaskula 24/06/2003
// fillMultiUsed method added
//_HADES_CLASS_DESCRIPTION
////////////////////////////////////////////////////////////////////////////////////////////////
// This class has been redesigned also in the course of adaption to multiple tracking methods
// Documentation is provided at the individual function bodies and in the header file
//
// Tassilo Christ 05/07/2006
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// //
// HPidParticle //
// //
// Identified particle, output of HPidParticleFiller - last stage of PID //
// analysis. //
// //
// fMassExp member defines the mass calulated from experimental parameters //
// momentum and beta. The value of this memeber may have two artifical values://
// -1 (kMassExpInTLV) - means that fMassExp was used to build TLorentzVector //
// -2 (kMassExpNoPhy) - the experimental beta was not physical one. //
// //
// Proper values of both masses: experimental and ideal can be got by methods://
// getMassExp(), getMassIdeal() which returns propper mass independently //
// on the mass used to make TLorentzVector //
// //
////////////////////////////////////////////////////////////////////////////////
using namespace std;
#include "hpidhitdata.h"
#include "hpidparticle.h"
#include "hpidcandidate.h"
#include "hpidtrackcand.h"
#include "hpidphysicsconstants.h"
#include "hades.h"
#include "hevent.h"
#include "hlinearcategory.h"
#include "hpidfl.h"
#include <TError.h>
#include <iostream>
#include "piddef.h"
// -----------------------------------------------------------------------------
ClassImp(HPidParticle)
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// This constructor takes as minimum input an index to the HPidCandidate-instance from which the
// particle is made, an index indicating the type of momentum reconstruction, a vector with particle Ids
// for which weights where computed and a vector with these weights. The rest of the
// variables is optional. If useMassIdeal is kTRUE, then the ideal mass of the species which is
// assigned to the particle is used to fill the TLorentzVector. If userDefSpecies is set, then
// the contents of the probability vector are stored but ignored and the assigned PID is taken from this
// variable. In this case userWeight has to be set. Then the probability value for the assigned species is
// set to the user-defined value.
//
//////////////////////////////////////////////////////////////////////////////////////////////////
HPidParticle::HPidParticle(HPidCandidate* pCandidate,Float_t* VectorOfWeights,
Bool_t useMassIdeal, Int_t userDefSpecies, Float_t userWeight):
itsHitData(*(pCandidate->getTrackCandidate()->getHitData())),
itsTrackData(*(pCandidate->getTrackCandidate()->getTrackData()))
{
setDefault();
//Allocation of dynamically managed memory
//How many particles are we considering?
nPossibleSpecies = pCandidate->getNParticles();
//Each species is stored as a possible PID together with its weight
possibleSpecies.Set(nPossibleSpecies,pCandidate->getParticleIds()->GetArray());
assignedWeights.Set(nPossibleSpecies,VectorOfWeights);
//Store index to hit collection and used momentum reconstruction
nPidCandidateIndex = HPidFL::getCategory(catPidCandidate)->getIndex(pCandidate);
setMomAlg(pCandidate->getMomAlg());
//Set species and weight -> See documentation of this function
setPidParams(0.0,userDefSpecies, userWeight);
//Get hit/tracking information
const HPidHitData* pHitData = getHitData();
const HPidTrackData* pTrackData = getTrackData();
Double_t tMomentum = pTrackData->fMomenta[getMomAlg()];
Double_t tMass = -1.0;
//Values are given in degree
Double_t tTheta;
Double_t tPhi;
//if not rk ->use MDC variables
if(getMomAlg()!=ALG_RUNGEKUTTA)
{
tTheta = pHitData->fMdcTheta;
tPhi = pHitData->fMdcPhi;
}
//else use RK variables
else
{
tTheta = pTrackData->fRKTheta;
tPhi = pTrackData->fRKPhi;
}
if(useMassIdeal) //we use the ideal mass of the particle species that was assigned to this particle above in setPidParams()
{
tMass=HPidPhysicsConstants::mass(getPid());
kUsesIdealMass=kTRUE;
}
else //we trust in the momentum reconstruction
{
tMass = TMath::Sqrt(pTrackData->fMassSquared[momAlgIndex]);
}
SetXYZM(tMomentum * TMath::Sin(TMath::DegToRad()*tTheta) * //P-x
TMath::Cos(TMath::DegToRad()*tPhi),
tMomentum * TMath::Sin(TMath::DegToRad()*tTheta) * //P-y
TMath::Sin(TMath::DegToRad()*tPhi),
tMomentum * TMath::Cos(TMath::DegToRad()*tTheta), //P-z
tMass); //Mass
}
HPidParticle::HPidParticle(const HPidParticle& source):
TLorentzVector(source),
itsHitData(*(source.getHitData())),
itsTrackData(*(source.getTrackData()))
{
setDefault();
kUsesIdealMass = source.kUsesIdealMass;
nPossibleSpecies=source.nPossibleSpecies;
momAlgIndex=source.momAlgIndex;
nPidCandidateIndex=source.nPidCandidateIndex;
possibleSpecies=source.possibleSpecies;
assignedWeights=source.assignedWeights;
nAssignedPID=source.nAssignedPID;
fTestVal=source.fTestVal;
fWeight=source.fWeight;
fMomRescal=source.fMomRescal;
}
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// This function is used to set either (A) a user speciefied particle ID and a corresponding weight
// computed by any external method for this particle or (B) determine the decision from the PID supplied values.
// In case (A) the user specifies a pid he whishes to be assigned to this particle. The probabilities are
// stored, but not USED to decide about the species then!
// If the user omits the values for userDefSpecies and userWeight (B), then the assignment is done
// according to the maximum weight in the assignedWeights TArrayF.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
void HPidParticle::setPidParams(Float_t fTV, Int_t userDefSpecies, Float_t userWeight)//OK
{
if(userDefSpecies!=-99) //The user defines a species by hand
{
nAssignedPID=userDefSpecies;
if(userWeight!=-99.0)
{
fWeight=userWeight;
}
else
{
::Error("HPidParticle::SetPidParams()","User defined a species for this particle by hand, but no weight");
exit(-1);
}
}
else //The user leaves it to the computed weights to decide about the assigned species
{
//Determine the biggest weight from the list of probabilities
Float_t currentMaxWeight=0.0;
for(Int_t i=0;i<nPossibleSpecies;i++)
{
if(assignedWeights[i]>currentMaxWeight)
{
currentMaxWeight=assignedWeights[i];
nAssignedPID=possibleSpecies[i];
fWeight = currentMaxWeight;
}
}
//If there was NO particle with weight bigger than 0.0 the PID decision cannot be used - we assign "artifical" as PID
if(currentMaxWeight==0.0){
if( getTrackData()->nPolarity[momAlgIndex]<0){
nAssignedPID =HPidPhysicsConstants::artificialNeg();
}
else if (getTrackData()->nPolarity[momAlgIndex]>0){
nAssignedPID =HPidPhysicsConstants::artificialPos();
}
}
//fTV=currentMaxWeight;
}
//setTestVal(fTV);
}
// -----------------------------------------------------------------------------
Float_t HPidParticle::getWeightForPID(Short_t pid) const //OK
{
Int_t i = getSpeciesIndex(pid);
if(i>-1) return assignedWeights[i];
return -1.0;
}
Int_t HPidParticle::getSpeciesIndex(Short_t pid) const //OK
{
for(Int_t i=0;i<nPossibleSpecies;i++)
{if(possibleSpecies[i]==pid) return i;}
return -1;
}
void HPidParticle::setDefault(void) //OK
{
momAlgIndex=-1;
nPossibleSpecies=0;
nAssignedPID=-99;
nPidCandidateIndex = -1;
possibleSpecies.Set(0);
assignedWeights.Set(0);
fTestVal = 0.0f;
fWeight = 0.0f;
fMomRescal = 1.0f;
kUsesIdealMass=kTRUE;
SetXYZT(0.0, 0.0, 0.0, 0.0);
}
// -----------------------------------------------------------------------------
void HPidParticle::Clear(Option_t *opt) //OK
{
// Clear all variables and frees dynamic memory!
possibleSpecies.Set(0);
assignedWeights.Set(0);
//itsTrackData.Clear();
//itsHitData.Clear();
}
// -----------------------------------------------------------------------------
void HPidParticle::print(void) const
{
// Print info about the particle
printf("Particle : %d "%s"n", getPid(), HPidPhysicsConstants::pid(getPid()));
printf("4Momentum : (%8.4f, %8.4f, %8.4f, %8.4f)nMom. mag.: %8.4f MeV/cn",
X(), Y(), Z(), T(), P());
printf("Theta/Phi : %8.4f %8.4fn", thetaDeg(), phiDeg());
//printf("Sect./Sys : %d %dn", sector(), nSystem);
printf("R, Z, Pull: %8.4f %8.4f %8.4fn", getR(), getZ(), getTrackData()->fPull);
printf("Beta calc : %8.4f Exp: %8.4fn", Beta(), getBetaExp());
printf("Mass ideal: %8.4f Exp: %8.4fn", getMassIdeal(), getMassExp());
printf("TestVal : %8.4fn", fTestVal);
printf("Weight : %8.4fn", fWeight);
}
// -----------------------------------------------------------------------------
HPidCandidate* HPidParticle::getPidCandidate(HCategory *pCat) const //OK
{
// Returns HPidCandidate object corresponding to nPidCandidateIndex (if exists)
// Works when pCat is set or gHades->getCurrentEvent() is accessible
if(nPidCandidateIndex < 0)
return NULL;
return HPidFL::getPidCandidate(nPidCandidateIndex, pCat);
}
// -----------------------------------------------------------------------------
HCategory* HPidParticle::buildPidParticleCategory(void) //OK
{
// Static function for making the category HPidParticle
HCategory *pCat;
HEvent *pEvent;
if((gHades == NULL) || ((pEvent = gHades->getCurrentEvent()) == NULL))
{
::Error("HPidParticle::buildPidParticleCategory",
"Cannot access current event");
return NULL;
}
if((pCat = pEvent->getCategory(catPidPart)) != NULL)
{
((HLinearCategory*)pCat)->setDynamicObjects(kTRUE);
return pCat;
}
if((pCat = new HLinearCategory("HPidParticle", 1000)) == NULL)
{
::Error("HPidParticle::buildPidParticleCategory",
"Cannot create new category");
return NULL;
}
((HLinearCategory*)pCat)->setDynamicObjects(kTRUE);
pEvent->addCategory(catPidPart, pCat, "Pid");
return pCat;
}
// -----------------------------------------------------------------------------
Int_t HPidParticle::getMostProbablePID(void) const //OK
{
Float_t currentMax=0.0;
Int_t pid=-99;
for(Int_t j =0;j<nPossibleSpecies;j++)
{
if(assignedWeights[j]>currentMax)
{
currentMax=assignedWeights[j];
pid=possibleSpecies[j];
}
}
if( !(currentMax>0.0)){ //no decision. Make artificial IDs
if( getTrackData()->nPolarity[momAlgIndex]<0){
pid =HPidPhysicsConstants::artificialNeg();
}
else if (getTrackData()->nPolarity[momAlgIndex]>0){
pid =HPidPhysicsConstants::artificialPos();
}
}
return pid;
}
// -----------------------------------------------------------------------------
Int_t HPidParticle::getIndex(HCategory *pCat) //OK
{
// Return index of the HPidParticle in the pCat or catPidPart if pCat == NULL
if((pCat == NULL) && ((pCat = HPidFL::getCategory(
catPidPart, kFALSE)) == NULL))
{
Error("getIndex", "Cannot get category");
return -2;
}
return pCat->getIndex(this);
}
// -----------------------------------------------------------------------------
HPidTrackCand* HPidParticle::getTrackCand(void) const //OK
{
// This method returns HPidTrackCand object from the corresponding
// HPidCandidate (when nPidCandidateIndex >= 0) or directly from catPidTrackCand
// when nPidCandidateIndex <= -1000
// (interface for HPidParticleFillerFromTrack)
if(nPidCandidateIndex >= 0)
{
HPidCandidate *pCand;
if((pCand = getPidCandidate()) == NULL)
{
Error("HPidParticle::getTrackCand()", "Cannot get HPidCandidate");
return NULL;
}
if(pCand->getTrackCandIndex() < 0)
{
Error("HPidParticle::getTrackCand()","Track Candidate Index for PidCandidate is %d",pCand->getTrackCandIndex());
return NULL;
}
return pCand->getTrackCandidate();
}
if(nPidCandidateIndex <= kTrackCandOffset)
return HPidFL::getTrackCand(kTrackCandOffset - nPidCandidateIndex);
return NULL;
}
// -----------------------------------------------------------------------------
TLorentzVector HPidParticle::getRescaledVector(void) const //OK
{
TLorentzVector v = *this;
if(fMomRescal != 1.0f)
{
TVector3 v3 = v.Vect();
v3.SetMag(fMomRescal * v3.Mag());
v.SetVectM(v3, M());
}
return v;
}
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.