//*************************************************************************
//* =====================
//* FlavourGetter Class
//* =====================
//*
//* (Description)
//* A flavour of jets getting class
//* (Requires)
//* class ANLJetFinder
//* class ANLTrack
//* class JSFSIMDST, etc
//* (Provides)
//* class FlavourGetter
//* (Update Recored)
//* 2000/02/13 K.Ikematsu Original version
//* 2000/04/28 K.Ikemtasu Modified GetPrimaryHadronPID method
//* 2001/07/20 K.Ikemtasu Added GetPrimaryHadronSN method
//* 2001/07/20 K.Ikemtasu Added GetPartonID method
//* 2001/07/26 K.Ikematsu Added TTL4JFlavourGetter class
//* 2001/07/31 K.Ikematsu Supported to search generator particles
//* contributing to the EM cluster (gamma)
//* 2001/08/02 K.Ikematsu Added fPIDOffVT and fSNOffVT members
//* 2001/10/23 K.Ikematsu Moved TObjNum class to ANLTrack class
//* 2001/12/18 K.Ikematsu Added SetThetaCut method
//*
//* $Id: FlavourGetter.cxx,v 1.14 2001/12/18 14:45:47 ikematsu Exp $
//*************************************************************************
//
#include "FlavourGetter.h"
//_____________________________________________________________________
// -------------------
// FlavourGetter Class
// -------------------
//
ClassImp(FlavourGetter)
//_____________________________________________________________________
//*--
//* Setters
//*--
void FlavourGetter::SetDataArray(const ANLJet &jet) {
fPIDPriHad.Clear();
fSNPriHad.Clear();
fMSNPriHad.Clear();
fPIDOffVT.Clear();
fSNOffVT.Clear();
TIter next(&jet.GetParticlesInJet());
ANLTrack *tp;
while ((tp = (ANLTrack *)next())) {
SearchPrimaryHadron(*tp);
}
fPIDPriHad.SetOwner(); // SetOwner() method only enabled
fSNPriHad.SetOwner(); // after adding contents
fMSNPriHad.SetOwner();
fPIDOffVT.SetOwner();
fSNOffVT.SetOwner();
}
//_____________________________________________________________________
//*--
//* Getters
//*--
Int_t FlavourGetter::operator()(const ANLJet &jet) {
static const Double_t kOffVRatioCut = 0.1;
static const Double_t kBHadRatioCut = 0.9;
static const Double_t kCHadRatioCut = 0.85;
Int_t ntrkinjet = 0;
Int_t noffvtrkinjet = 0;
Int_t noffvtrkfrombhad = 0;
Int_t noffvtrkfromchad = 0;
SetDataArray(jet);
#if 0
TIter nextprihadpid(&fPIDPriHad);
TObjNum *prihadpidp;
while ((prihadpidp = (TObjNum *)nextprihadpid())) {
// fPIDPriHad : Not Yet contained primary hadron's PIDs contributing to
// the HDC cluster from neutral combined tracks.
Int_t prihadpid = TMath::Abs(prihadpidp->GetNum());
#ifdef __DEBUG__
cerr << "FlavourGetter::operator() : PID(pri had) = " << prihadpid << endl;
#endif
ntrkinjet++;
}
#else
ntrkinjet = fPIDPriHad.GetEntries();
#endif
TIter nextoffvtrkpid(&fPIDOffVT);
TObjNum *offvtrkpidp;
while ((offvtrkpidp = (TObjNum *)nextoffvtrkpid())) {
Int_t offvtrkpid = TMath::Abs(offvtrkpidp->GetNum());
#ifdef __DEBUG__
cerr << "FlavourGetter::operator() : PID(offv trk) = " << offvtrkpid << endl;
#endif
noffvtrkinjet++;
Int_t flavour = 0;
if ( offvtrkpid/1000 > 0 && offvtrkpid/10000 == 0 ) { // Meson-Baryon branch
flavour = offvtrkpid/1000;
} else {
flavour = (offvtrkpid/100)%10;
}
if ( flavour == 5 ) noffvtrkfrombhad++;
if ( flavour == 4 ) noffvtrkfromchad++;
}
Double_t offvratio = (Double_t)noffvtrkinjet/ntrkinjet;
Double_t bhadratio = (Double_t)noffvtrkfrombhad/noffvtrkinjet;
Double_t chadratio = (Double_t)noffvtrkfromchad/noffvtrkinjet;
#ifdef __DEBUG__
cerr << "R(OffVTrk,FromB,FromC) = ("
<< offvratio << ","
<< bhadratio << ","
<< chadratio << ")" << endl;
#endif
if ( offvratio >= kOffVRatioCut ) {
if ( bhadratio >= kBHadRatioCut ) return 3;
else if ( chadratio >= kCHadRatioCut ) return 2;
else return 0;
} else {
if ( bhadratio >= kBHadRatioCut || chadratio >= kCHadRatioCut ) return 0;
else return 1;
}
}
//_____________________________________________________________________
TObjArray & FlavourGetter::GetPrimaryHadronPID() { return fPIDPriHad; }
TObjArray & FlavourGetter::GetPrimaryHadronSN() { return fSNPriHad; }
TObjArray & FlavourGetter::GetPartonID() { return fMSNPriHad; }
TObjArray & FlavourGetter::GetOffVertexHadronPID() { return fPIDOffVT; }
TObjArray & FlavourGetter::GetOffVertexHadronSN() { return fSNOffVT; }
//_____________________________________________________________________
void FlavourGetter::SearchPrimaryHadron(const ANLTrack &t) {
JSFLTKCLTrack *ctp = t.GetLTKCLTrack();
#ifdef __DEBUG__
cerr << " Track type : " << ctp->GetType()
<< " , " << ctp->GetTypeName() << endl
<< " CDCEntries = " << ctp->GetCDCEntries() << endl
<< " EMGenEntries = " << ctp->GetEMGenEntries() << endl;
#endif
// Should be weighted in charged tracks in cheating !!!
// because 4-momentum is decided by charged track if there is.
Int_t ncdctrk = ctp->GetCDCEntries();
// If track charge in mixed CAL cluster = 0,
// Don't use CDCTrack pointer because of subtracted track-information !!
if ( ncdctrk > 0 && ctp->GetCharge() != 0 ) {
#ifdef __DEBUG__
cerr << "# of charged tracks = " << ncdctrk << endl;
#endif
for (Int_t i = 0; i < ncdctrk; i++ ) {
ScanThroughDecayChain(kECDC, ctp, i);
}
return; // If ncdctrk > 0 && nemgen > 0 such as electron candidate,
// should not scan generator particles in EMC cluster.
}
Int_t nemgen = ctp->GetEMGenEntries();
if ( nemgen > 0 ) {
#ifdef __DEBUG__
cerr << "# of neutral tracks in EMC = " << nemgen << endl;
#endif
for (Int_t i = 0; i < nemgen; i++ ) {
ScanThroughDecayChain(kEEMC, ctp, i);
}
return;
}
}
//_____________________________________________________________________
void FlavourGetter::ScanThroughDecayChain(EFlavourGetterDetectorID id,
JSFLTKCLTrack *ctp, Int_t i) {
#ifdef __DEBUG__
cerr << "i = " << i << endl;
#endif
Int_t gpid = 0;
Int_t gsn = 0;
Int_t gmsn = 0;
if (id == kEEMC) gmsn = ctp->GetEMGenAt(i)->GetSerial();
else if (id == kECDC) gmsn = ctp->GetCDCTrackAt(i)->GetGenID();
else {
cerr << "Unsupported detector type !!" << endl;
exit(1);
}
Double_t gdln = 0;
Int_t gpidoffvt = 0;
Int_t gsnoffvt = 0;
while ( gmsn >= 0 ) {
JSFGeneratorParticle *g = (JSFGeneratorParticle *)fGen->UncheckedAt(gmsn-1);
gpid = g->GetID();
gsn = g->GetSerial();
gmsn = g->GetMother();
gdln = g->GetDecayLength();
#ifdef __DEBUG__
cerr << "(PID, S.N, M.S.N, DLength) = ("
<< gpid << ","
<< gsn << ","
<< gmsn << ","
<< gdln << ")" << endl;
#endif
if ( gdln > 0 ) {
#ifdef __DEBUG__
cerr << "This generator particle has a finite decay length." << endl;
#endif
gpidoffvt = gpid;
gsnoffvt = gsn;
}
}
#ifdef __DEBUG__
cerr << "-- Search ended --" << endl;
if (TMath::Abs(gpidoffvt) == 310 || TMath::Abs(gpidoffvt) == 3122 ||
TMath::Abs(gpidoffvt) == 3112 || TMath::Abs(gpidoffvt) == 3222 ||
TMath::Abs(gpidoffvt) == 3322 || TMath::Abs(gpidoffvt) == 3334)
cerr << "This off-vertex generator particle is weak decaying hadron." << endl;
#endif
if ( TMath::Abs(gpidoffvt) > 0 &&
TMath::Abs(gpidoffvt) != 310 && TMath::Abs(gpidoffvt) != 3122 &&
TMath::Abs(gpidoffvt) != 3112 && TMath::Abs(gpidoffvt) != 3222 &&
TMath::Abs(gpidoffvt) != 3322 && TMath::Abs(gpidoffvt) != 3334 ) {
TObjNum *gpidoffvtp = new TObjNum(gpidoffvt);
TObjNum *gsnoffvtp = new TObjNum(gsnoffvt);
fPIDOffVT.Add(gpidoffvtp); // *gpidoffvtp, *gsnoffvtp and *gmsnoffvtp stays
fSNOffVT.Add(gsnoffvtp); // but (TObjArray *)obj->SetOwner() deletes its elements.
}
TObjNum *gpidp = new TObjNum(gpid);
TObjNum *gsnp = new TObjNum(gsn);
TObjNum *gmsnp = new TObjNum(gmsn);
fPIDPriHad.Add(gpidp); // *gpidp, *gsnp and *gmsnp stays
fSNPriHad.Add(gsnp); // but (TObjArray *)obj->SetOwner() deletes
fMSNPriHad.Add(gmsnp); // its elements.
}
//_____________________________________________________________________
// ------------------------
// TTL4JFlavourGetter Class
// ------------------------
//
ClassImp(TTL4JFlavourGetter)
//_____________________________________________________________________
//*--
//* Setters
//*--
void TTL4JFlavourGetter::SetThetaCut(Double_t theta) {
if ( theta != fThetaCut ) {
fThetaCut = theta;
}
}
//_____________________________________________________________________
//*--
//* Getters
//*--
Int_t TTL4JFlavourGetter::operator()(const ANLJet &jet) {
static const Double_t kCHadRatioCut = 0.8;
Int_t ntrkinjet = 0;
Int_t ntrkfromb = 0;
Int_t ntrkfromw = 0;
Int_t noffvtrkinjet = 0;
Int_t noffvtrkfromchad = 0;
SetDataArray(jet);
TIter nextptnid(&GetPartonID());
TObjNum *ptnidp;
while ((ptnidp = (TObjNum *)nextptnid())) {
// fMSNPriHad : Not Yet contained primary hadron's Mother S.N contributing to
// the HDC cluster from neutral combined tracks.
Int_t partonid = TMath::Abs(ptnidp->GetNum());
#ifdef __DEBUG__
cerr << "TTL4JFlavourGetter::operator() : MSN = " << partonid << endl;
#endif
ntrkinjet++;
if ( partonid == 3 ) ntrkfromb++;
else if ( partonid == 7 || partonid == 9 ) ntrkfromw++;
}
TIter nextoffvtrkpid(&GetOffVertexHadronPID());
TObjNum *offvtrkpidp;
while ((offvtrkpidp = (TObjNum *)nextoffvtrkpid())) {
Int_t offvtrkpid = TMath::Abs(offvtrkpidp->GetNum());
#ifdef __DEBUG__
cerr << "FlavourGetter::operator() : PID(offv trk) = " << offvtrkpid << endl;
#endif
noffvtrkinjet++;
Int_t flavour = 0;
if ( offvtrkpid/1000 > 0 && offvtrkpid/10000 == 0 ) { // Meson-Baryon branch
flavour = offvtrkpid/1000;
} else {
flavour = (offvtrkpid/100)%10;
}
if ( flavour == 4 ) noffvtrkfromchad++;
}
#ifdef __DEBUG__
cerr << "R(Fromb,FromW,FromD) = (" << (Double_t)ntrkfromb/ntrkinjet << ","
<< (Double_t)ntrkfromw/ntrkinjet << ","
<< (Double_t)noffvtrkfromchad/noffvtrkinjet << ")" << endl;
#endif
JSFSpringParton *spbbar = (JSFSpringParton *)fSpgen->UncheckedAt(2);
JSFSpringParton *spb = (JSFSpringParton *)fSpgen->UncheckedAt(4);
JSFSpringParton *spupbar = (JSFSpringParton *)fSpgen->UncheckedAt(6);
JSFSpringParton *spdn = (JSFSpringParton *)fSpgen->UncheckedAt(7);
JSFSpringParton *spup = (JSFSpringParton *)fSpgen->UncheckedAt(8);
JSFSpringParton *spdnbar = (JSFSpringParton *)fSpgen->UncheckedAt(9);
ANL4DVector qspbbar(spbbar->GetPV());
ANL4DVector qspb(spb->GetPV());
ANL4DVector qspupbar(spupbar->GetPV());
ANL4DVector qspdn(spdn->GetPV());
ANL4DVector qspup(spup->GetPV());
ANL4DVector qspdnbar(spdnbar->GetPV());
Double_t thetaspbbarj = qspbbar.GetTheta(jet);
Double_t thetaspbj = qspb.GetTheta(jet);
Double_t thetaspupbarj = qspupbar.GetTheta(jet);
Double_t thetaspdnj = qspdn.GetTheta(jet);
Double_t thetaspupj = qspup.GetTheta(jet);
Double_t thetaspdnbarj = qspdnbar.GetTheta(jet);
#ifdef __DEBUG__
if ( spdn->GetID() == 11 || spdn->GetID() == 13 || spdn->GetID() == 15 ) {
cerr << "W- decayed leptonically" << endl
<< "Th(bbar_j,b_j,up_j,dnbar_j) = ("
<< thetaspbbarj << ","
<< thetaspbj << ","
<< thetaspupj << ","
<< thetaspdnbarj << ")" << endl;
} else {
cerr << "W+ decayed leptonically" << endl
<< "Th(bbar_j,b_j,upbar_j,dn_j) = ("
<< thetaspbbarj << ","
<< thetaspbj << ","
<< thetaspupbarj << ","
<< thetaspdnj << ")" << endl;
}
#endif
if ( (Double_t)ntrkfromb/ntrkinjet >= (Double_t)ntrkfromw/ntrkinjet ) {
if ( TMath::Min(thetaspbbarj,thetaspbj) < fThetaCut ) {
if ( thetaspbbarj < thetaspbj ) return -3;
else return 3;
} else {
#ifdef __DEBUG__
cerr << "Th(bottom_j) = "
<< TMath::Min(thetaspbbarj,thetaspbj) << endl;
#endif
return 0;
}
} else {
if ( spdn->GetID() == 11 || spdn->GetID() == 13 || spdn->GetID() == 15 ) {
if ( (Double_t)noffvtrkfromchad/noffvtrkinjet >= kCHadRatioCut ) {
if ( thetaspupj < fThetaCut ) return 2;
else if ( thetaspdnbarj < fThetaCut ) return -1;
else {
#ifdef __DEBUG__
cerr << "Th(charm_j) = " << thetaspupj << endl;
#endif
return 0;
}
} else {
if ( TMath::Min(thetaspupj,thetaspdnbarj) < fThetaCut ) {
if ( thetaspupj < thetaspdnbarj ) return 1;
else return -1;
} else {
#ifdef __DEBUG__
cerr << "Th(light_j) = "
<< TMath::Min(thetaspupj,thetaspdnbarj) << endl;
#endif
return 0;
}
}
} else {
if ( (Double_t)noffvtrkfromchad/noffvtrkinjet >= kCHadRatioCut ) {
if ( thetaspupbarj < fThetaCut ) return -2;
else if ( thetaspdnj < fThetaCut ) return 1;
else {
#ifdef __DEBUG__
cerr << "Th(charm_j) = " << thetaspupbarj << endl;
#endif
return 0;
}
} else {
if ( TMath::Min(thetaspupbarj,thetaspdnj) < fThetaCut ) {
if ( thetaspupbarj < thetaspdnj ) return -1;
else return 1;
} else {
#ifdef __DEBUG__
cerr << "Th(light_j) = "
<< TMath::Min(thetaspupbarj,thetaspdnj) << endl;
#endif
return 0;
}
}
}
}
}
ROOT page - Home page - Class index - 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.