#include "TPythia6.h"
#include "TPythia6Decayer.h"
#include "TPDGCode.h"
#include "TLorentzVector.h"
#include "TClonesArray.h"
ClassImp(TPythia6Decayer)
TPythia6Decayer* TPythia6Decayer::fgInstance = 0;
TPythia6Decayer* TPythia6Decayer::Instance()
{
if (!fgInstance) fgInstance = new TPythia6Decayer;
return fgInstance;
}
TPythia6Decayer::TPythia6Decayer()
: fBraPart(501)
{
fBraPart.Reset(1);
}
void TPythia6Decayer::Init()
{
static Bool_t init = kFALSE;
if (init) return;
init = kTRUE;
ForceDecay();
}
void TPythia6Decayer::Decay(Int_t idpart, TLorentzVector* p)
{
if (!p) return;
TPythia6::Instance()->Py1ent(0, idpart, p->Energy(), p->Theta(), p->Phi());
TPythia6::Instance()->GetPrimaries();
}
Int_t TPythia6Decayer::ImportParticles(TClonesArray *particles)
{
return TPythia6::Instance()->ImportParticles(particles,"All");
}
void TPythia6Decayer::SetForceDecay(Int_t type)
{
if (type > kMaxDecay) {
Warning("SetForceDecay", "Invalid decay mode: %d", type);
return;
}
fDecay = EDecayType(type);
}
void TPythia6Decayer::ForceDecay()
{
EDecayType decay=fDecay;
TPythia6::Instance()->SetMSTJ(21,2);
if (decay == kNoDecayHeavy) return;
Int_t products[3];
Int_t mult[3];
switch (decay) {
case kHardMuons:
products[0] = 13;
products[1] = 443;
products[2] = 100443;
mult[0] = 1;
mult[1] = 1;
mult[2] = 1;
ForceParticleDecay( 511, products, mult, 3);
ForceParticleDecay( 521, products, mult, 3);
ForceParticleDecay( 531, products, mult, 3);
ForceParticleDecay( 5122, products, mult, 3);
ForceParticleDecay( 5132, products, mult, 3);
ForceParticleDecay( 5232, products, mult, 3);
ForceParticleDecay( 5332, products, mult, 3);
ForceParticleDecay( 100443, 443, 1);
ForceParticleDecay( 443, 13, 2);
ForceParticleDecay( 411,13,1);
ForceParticleDecay( 421,13,1);
ForceParticleDecay( 431,13,1);
ForceParticleDecay( 4122,13,1);
ForceParticleDecay( 4132,13,1);
ForceParticleDecay( 4232,13,1);
ForceParticleDecay( 4332,13,1);
break;
case kSemiMuonic:
ForceParticleDecay( 411,13,1);
ForceParticleDecay( 421,13,1);
ForceParticleDecay( 431,13,1);
ForceParticleDecay( 4122,13,1);
ForceParticleDecay( 4132,13,1);
ForceParticleDecay( 4232,13,1);
ForceParticleDecay( 4332,13,1);
ForceParticleDecay( 511,13,1);
ForceParticleDecay( 521,13,1);
ForceParticleDecay( 531,13,1);
ForceParticleDecay( 5122,13,1);
ForceParticleDecay( 5132,13,1);
ForceParticleDecay( 5232,13,1);
ForceParticleDecay( 5332,13,1);
break;
case kDiMuon:
ForceParticleDecay( 113,13,2);
ForceParticleDecay( 221,13,2);
ForceParticleDecay( 223,13,2);
ForceParticleDecay( 333,13,2);
ForceParticleDecay( 443,13,2);
ForceParticleDecay(100443,13,2);
ForceParticleDecay( 553,13,2);
ForceParticleDecay(100553,13,2);
ForceParticleDecay(200553,13,2);
break;
case kSemiElectronic:
ForceParticleDecay( 411,11,1);
ForceParticleDecay( 421,11,1);
ForceParticleDecay( 431,11,1);
ForceParticleDecay( 4122,11,1);
ForceParticleDecay( 4132,11,1);
ForceParticleDecay( 4232,11,1);
ForceParticleDecay( 4332,11,1);
ForceParticleDecay( 511,11,1);
ForceParticleDecay( 521,11,1);
ForceParticleDecay( 531,11,1);
ForceParticleDecay( 5122,11,1);
ForceParticleDecay( 5132,11,1);
ForceParticleDecay( 5232,11,1);
ForceParticleDecay( 5332,11,1);
break;
case kDiElectron:
ForceParticleDecay( 113,11,2);
ForceParticleDecay( 333,11,2);
ForceParticleDecay( 221,11,2);
ForceParticleDecay( 223,11,2);
ForceParticleDecay( 443,11,2);
ForceParticleDecay(100443,11,2);
ForceParticleDecay( 553,11,2);
ForceParticleDecay(100553,11,2);
ForceParticleDecay(200553,11,2);
break;
case kBJpsiDiMuon:
products[0] = 443;
products[1] = 100443;
mult[0] = 1;
mult[1] = 1;
ForceParticleDecay( 511, products, mult, 2);
ForceParticleDecay( 521, products, mult, 2);
ForceParticleDecay( 531, products, mult, 2);
ForceParticleDecay( 5122, products, mult, 2);
ForceParticleDecay( 100443, 443, 1);
ForceParticleDecay( 443,13,2);
break;
case kBPsiPrimeDiMuon:
ForceParticleDecay( 511,100443,1);
ForceParticleDecay( 521,100443,1);
ForceParticleDecay( 531,100443,1);
ForceParticleDecay( 5122,100443,1);
ForceParticleDecay(100443,13,2);
break;
case kBJpsiDiElectron:
ForceParticleDecay( 511,443,1);
ForceParticleDecay( 521,443,1);
ForceParticleDecay( 531,443,1);
ForceParticleDecay( 5122,443,1);
ForceParticleDecay( 443,11,2);
break;
case kBJpsi:
ForceParticleDecay( 511,443,1);
ForceParticleDecay( 521,443,1);
ForceParticleDecay( 531,443,1);
ForceParticleDecay( 5122,443,1);
break;
case kBPsiPrimeDiElectron:
ForceParticleDecay( 511,100443,1);
ForceParticleDecay( 521,100443,1);
ForceParticleDecay( 531,100443,1);
ForceParticleDecay( 5122,100443,1);
ForceParticleDecay(100443,11,2);
break;
case kPiToMu:
ForceParticleDecay(211,13,1);
break;
case kKaToMu:
ForceParticleDecay(321,13,1);
break;
case kWToMuon:
ForceParticleDecay( 24, 13,1);
break;
case kWToCharm:
ForceParticleDecay( 24, 4,1);
break;
case kWToCharmToMuon:
ForceParticleDecay( 24, 4,1);
ForceParticleDecay( 411,13,1);
ForceParticleDecay( 421,13,1);
ForceParticleDecay( 431,13,1);
ForceParticleDecay( 4122,13,1);
ForceParticleDecay( 4132,13,1);
ForceParticleDecay( 4232,13,1);
ForceParticleDecay( 4332,13,1);
break;
case kZDiMuon:
ForceParticleDecay( 23, 13,2);
break;
case kHadronicD:
ForceHadronicD();
break;
case kPhiKK:
ForceParticleDecay(333,321,2);
break;
case kOmega:
ForceOmega();
case kAll:
break;
case kNoDecay:
TPythia6::Instance()->SetMSTJ(21,0);
break;
case kNoDecayHeavy: break;
case kMaxDecay: break;
}
}
Float_t TPythia6Decayer::GetPartialBranchingRatio(Int_t ipart)
{
Int_t kc = TPythia6::Instance()->Pycomp(TMath::Abs(ipart));
return fBraPart[kc];
}
Float_t TPythia6Decayer::GetLifetime(Int_t kf)
{
Int_t kc=TPythia6::Instance()->Pycomp(TMath::Abs(kf));
return TPythia6::Instance()->GetPMAS(kc,4) * 3.3333e-12;
}
void TPythia6Decayer::ReadDecayTable()
{
if (fDecayTableFile.IsNull()) {
Warning("ReadDecayTable", "No file set");
return;
}
Int_t lun = 15;
TPythia6::Instance()->OpenFortranFile(lun,
const_cast<char*>(fDecayTableFile.Data()));
TPythia6::Instance()->Pyupda(3,lun);
TPythia6::Instance()->CloseFortranFile(lun);
}
#if 0
void PrintPDG(TParticlePDG* pdg)
{
TParticlePDG* anti = pdg->AntiParticle();
const char* antiName = (anti ? anti->GetName() : "");
Int_t color = 0;
switch (TMath::Abs(pdg->PdgCode())) {
case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
color = 1; break;
case 21:
color = 2; break;
case 1103:
case 2101: case 2103: case 2203:
case 3101: case 3103: case 3201: case 3203: case 3303:
case 4101: case 4103: case 4201: case 4203: case 4301: case 4303: case 4403:
case 5101: case 5103: case 5201: case 5203: case 5301: case 5303: case 5401:
case 5403: case 5503:
color = -1; break;
case 1000001: case 1000002: case 1000003: case 1000004: case 1000005:
case 1000006:
color = 1; break;
case 1000021:
color = 2; break;
case 2000001: case 2000002: case 2000003: case 2000004: case 2000005:
case 2000006:
color = 1; break;
case 3000331: case 3100021: case 3200111: case 3100113: case 3200113:
case 3300113: case 3400113:
color = 2; break;
case 4000001: case 4000002:
color = 1; break;
case 9900443: case 9900441: case 9910441: case 9900553: case 9900551:
case 9910551:
color = 2; break;
}
std::cout << std::right
<< " " << std::setw(9) << pdg->PdgCode()
<< " " << std::left << std::setw(16) << pdg->GetName()
<< " " << std::setw(16) << antiName
<< std::right
<< std::setw(3) << Int_t(pdg->Charge())
<< std::setw(3) << color
<< std::setw(3) << (anti ? 1 : 0)
<< std::fixed << std::setprecision(5)
<< std::setw(12) << pdg->Mass()
<< std::setw(12) << pdg->Width()
<< std::setw(12) << 0
<< std::scientific
<< " " << std::setw(13) << pdg->Lifetime()
<< std::setw(3) << 0
<< std::setw(3) << pdg->Stable()
<< std::endl;
}
void MakeDecayList()
{
TDatabasePDG* pdgDB = TDatabasePDG::Instance();
pdgDB->ReadPDGTable();
const THashList* pdgs = pdgDB->ParticleList();
TParticlePDG* pdg = 0;
TIter nextPDG(pdgs);
while ((pdg = static_cast<TParticlePDG*>(nextPDG()))) {
PrintPDG(pdg);
TObjArray* decays = pdg->DecayList();
TDecayChannel* decay = 0;
TIter nextDecay(decays);
while ((decay = static_cast<TDecayChannel*>(nextDecay()))) {
}
}
}
#endif
void TPythia6Decayer::WriteDecayTable()
{
if (fDecayTableFile.IsNull()) {
Warning("ReadDecayTable", "No file set");
return;
}
Int_t lun = 15;
TPythia6::Instance()->OpenFortranFile(lun,
const_cast<char*>(fDecayTableFile.Data()));
TPythia6::Instance()->Pyupda(1,lun);
TPythia6::Instance()->CloseFortranFile(lun);
}
Int_t TPythia6Decayer::CountProducts(Int_t channel, Int_t particle)
{
Int_t np = 0;
for (Int_t i = 1; i <= 5; i++)
if (TMath::Abs(TPythia6::Instance()->GetKFDP(channel,i)) == particle) np++;
return np;
}
void TPythia6Decayer::ForceHadronicD()
{
const Int_t kNHadrons = 4;
Int_t channel;
Int_t hadron[kNHadrons] = {411, 421, 431, 4112};
Int_t iKstar0 = 313;
Int_t iKstarbar0 = -313;
Int_t products[2] = {kKPlus, kPiMinus}, mult[2] = {1, 1};
ForceParticleDecay(iKstar0, products, mult, 2);
Int_t iPhi = 333;
ForceParticleDecay(iPhi,kKPlus,2);
Int_t decayP1[kNHadrons][3] = {
{kKMinus, kPiPlus, kPiPlus},
{kKMinus, kPiPlus, 0 },
{kKPlus , iKstarbar0, 0 },
{-1 , -1 , -1 }
};
Int_t decayP2[kNHadrons][3] = {
{iKstarbar0, kPiPlus, 0 },
{-1 , -1 , -1 },
{iPhi , kPiPlus, 0 },
{-1 , -1 , -1 }
};
TPythia6* pyth = TPythia6::Instance();
for (Int_t ihadron = 0; ihadron < kNHadrons; ihadron++) {
Int_t kc = pyth->Pycomp(hadron[ihadron]);
pyth->SetMDCY(kc,1,1);
Int_t ifirst = pyth->GetMDCY(kc,2);
Int_t ilast = ifirst + pyth->GetMDCY(kc,3)-1;
for (channel = ifirst; channel <= ilast; channel++) {
if ((pyth->GetKFDP(channel,1) == decayP1[ihadron][0] &&
pyth->GetKFDP(channel,2) == decayP1[ihadron][1] &&
pyth->GetKFDP(channel,3) == decayP1[ihadron][2] &&
pyth->GetKFDP(channel,4) == 0) ||
(pyth->GetKFDP(channel,1) == decayP2[ihadron][0] &&
pyth->GetKFDP(channel,2) == decayP2[ihadron][1] &&
pyth->GetKFDP(channel,3) == decayP2[ihadron][2] &&
pyth->GetKFDP(channel,4) == 0)) {
pyth->SetMDME(channel,1,1);
} else {
pyth->SetMDME(channel,1,0);
fBraPart[kc] -= pyth->GetBRAT(channel);
}
}
}
}
void TPythia6Decayer::ForceParticleDecay(Int_t particle, Int_t product, Int_t mult)
{
TPythia6* pyth = TPythia6::Instance();
Int_t kc = pyth->Pycomp(particle);
pyth->SetMDCY(kc,1,1);
Int_t ifirst = pyth->GetMDCY(kc,2);
Int_t ilast = ifirst + pyth->GetMDCY(kc,3)-1;
fBraPart[kc] = 1;
for (Int_t channel= ifirst; channel <= ilast; channel++) {
if (CountProducts(channel,product) >= mult) {
pyth->SetMDME(channel,1,1);
} else {
pyth->SetMDME(channel,1,0);
fBraPart[kc]-=pyth->GetBRAT(channel);
}
}
}
void TPythia6Decayer::ForceParticleDecay(Int_t particle, Int_t* products,
Int_t* mult, Int_t npart)
{
TPythia6* pyth = TPythia6::Instance();
Int_t kc = pyth->Pycomp(particle);
pyth->SetMDCY(kc,1,1);
Int_t ifirst = pyth->GetMDCY(kc,2);
Int_t ilast = ifirst+pyth->GetMDCY(kc,3)-1;
fBraPart[kc] = 1;
for (Int_t channel = ifirst; channel <= ilast; channel++) {
Int_t nprod = 0;
for (Int_t i = 0; i < npart; i++)
nprod += (CountProducts(channel, products[i]) >= mult[i]);
if (nprod)
pyth->SetMDME(channel,1,1);
else {
pyth->SetMDME(channel,1,0);
fBraPart[kc] -= pyth->GetBRAT(channel);
}
}
}
void TPythia6Decayer::ForceOmega()
{
TPythia6* pyth = TPythia6::Instance();
Int_t kc = pyth->Pycomp(3334);
pyth->SetMDCY(kc,1,1);
Int_t ifirst = pyth->GetMDCY(kc,2);
Int_t ilast = ifirst + pyth->GetMDCY(kc,3)-1;
for (Int_t channel = ifirst; channel <= ilast; channel++) {
if (pyth->GetKFDP(channel,1) == kLambda0 &&
pyth->GetKFDP(channel,2) == kKMinus &&
pyth->GetKFDP(channel,3) == 0)
pyth->SetMDME(channel,1,1);
else
pyth->SetMDME(channel,1,0);
}
}