#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);
      
   } 
}
Last update: Thu Jan 17 09:02:05 2008
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.