CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/SimG4Core/CustomPhysics/src/CustomParticleFactory.cc

Go to the documentation of this file.
00001 #include <fstream>
00002 #include <iomanip>
00003 #include <iostream>
00004 #include <string>
00005 #include <vector>
00006 #include <sstream>
00007 #include <set>
00008 
00009 #include "SimG4Core/CustomPhysics/interface/CustomPDGParser.h"
00010 #include "SimG4Core/CustomPhysics/interface/CustomParticle.h"
00011 #include "SimG4Core/CustomPhysics/interface/CustomParticleFactory.h"
00012 
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014 #include "FWCore/ParameterSet/interface/FileInPath.h"
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 
00017 #include <G4ParticleTable.hh>
00018 #include "G4DecayTable.hh"
00019 #include <G4PhaseSpaceDecayChannel.hh>
00020 #include "G4ProcessManager.hh"
00021 
00022 
00023 bool CustomParticleFactory::loaded = false;
00024 std::set<G4ParticleDefinition *> CustomParticleFactory::m_particles;
00025 
00026 bool CustomParticleFactory::isCustomParticle(G4ParticleDefinition *particle)
00027 {
00028   return (m_particles.find(particle)!=m_particles.end());
00029 }
00030 
00031 void CustomParticleFactory::loadCustomParticles(const std::string & filePath){
00032   if(loaded) return;
00033   loaded = true;
00034 
00035   std::ifstream configFile(filePath.c_str());
00036 
00037   std::string line;
00038   // This should be compatible IMO to SLHA 
00039   G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00040   while(getline(configFile,line)){
00041     if(line.find("PDG code")<line.npos) getMassTable(&configFile);
00042     if(line.find("DECAY")<line.npos){
00043     int pdgId;
00044     double width; 
00045     std::string tmpString;
00046     std::stringstream lineStream(line);
00047     lineStream>>tmpString>>pdgId>>width; 
00048     G4DecayTable* aDecayTable = getDecayTable(&configFile, pdgId);      
00049       G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgId);
00050       G4ParticleDefinition *aAntiParticle = theParticleTable->FindAntiParticle(pdgId);
00051       if(!aParticle) continue;    
00052       aParticle->SetDecayTable(aDecayTable); 
00053       aParticle->SetPDGStable(false);
00054       aParticle->SetPDGLifeTime(1.0/(width*GeV)*6.582122e-22*MeV*s);      
00055       if(aAntiParticle && aAntiParticle->GetPDGEncoding()!=pdgId){      
00056         //aAntiParticle->SetDecayTable(getAntiDecayTable(pdgId,aDecayTable));
00057         aAntiParticle->SetPDGStable(false);
00058         aParticle->SetPDGLifeTime(1.0/(width*GeV)*6.582122e-22*MeV*s);
00059       }         
00060     }
00061   }
00062 }
00063 
00064 
00065 void CustomParticleFactory::addCustomParticle(int pdgCode, double mass, const std::string & name){
00066   
00067   
00068   if(pdgCode%100 <25 && abs(pdgCode) / 1000000 == 0){
00069     edm::LogError("") << "Pdg code too low " << pdgCode << " "<<abs(pdgCode) / 1000000  << std::endl;
00070     return;
00071   }
00072   
00073   
00075   G4String pType="custom";
00076   G4String pSubType="";
00077   G4double spectatormass;
00078   G4ParticleDefinition* spectator; 
00080   if(CustomPDGParser::s_isRHadron(pdgCode)) pType = "rhadron";
00081   if(CustomPDGParser::s_isSLepton(pdgCode)) pType = "sLepton";
00082   if(CustomPDGParser::s_isMesonino(pdgCode)) pType = "mesonino";
00083   if(CustomPDGParser::s_isSbaryon(pdgCode)) pType = "sbaryon";
00084  
00085   double massGeV =mass*GeV;
00086   double width = 0.0*MeV;
00087   double charge = eplus* CustomPDGParser::s_charge(pdgCode);
00088   int spin =  (int)CustomPDGParser::s_spin(pdgCode)-1;
00089   int parity = +1;
00090   int conjugation = 0;
00091   int isospin = 0;
00092   int isospinZ = 0;
00093   int gParity = 0;
00094   int lepton = 0;  //FIXME:
00095   int baryon = 1;  //FIXME: 
00096   bool stable = true;
00097   double lifetime = -1;
00098  
00099   G4DecayTable *decaytable = NULL;
00100   G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00101 
00102   CustomParticle *particle  = new CustomParticle(name, massGeV, width, charge, spin, 
00103                                                  parity, conjugation, isospin, isospinZ,
00104                                                  gParity, pType, lepton, baryon, pdgCode,
00105                                                  stable, lifetime, decaytable);
00106  
00107   if(pType == "rhadron" && name!="~g"){  
00108     G4String cloudname = name+"cloud";
00109     G4String cloudtype = pType+"cloud";
00110     spectator = theParticleTable->FindParticle(1000021);
00111     spectatormass = spectator->GetPDGMass();
00112     G4double cloudmass = mass-spectatormass/GeV;
00113     CustomParticle *tmpParticle  = new CustomParticle(
00114                                                       cloudname,           cloudmass * GeV ,        0.0*MeV,  0 , 
00115                                                       0,              +1,             0,          
00116                                                       0,              0,             0,             
00117                                                       cloudtype,               0,            +1, 0,
00118                                                       true,            -1.0,          NULL );
00119     particle->SetCloud(tmpParticle);
00120     particle->SetSpectator(spectator);
00121     
00122     edm::LogInfo("CustomPhysics")<<name<<" being assigned "
00123                     <<particle->GetCloud()->GetParticleName()
00124                     <<" and "<<particle->GetSpectator()->GetParticleName()<<std::endl;
00125     edm::LogInfo("CustomPhysics")<<"Masses: "
00126                     <<particle->GetPDGMass()/GeV<<" Gev, "
00127                     <<particle->GetCloud()->GetPDGMass()/GeV<<" GeV and "
00128                     <<particle->GetSpectator()->GetPDGMass()/GeV<<" GeV."
00129                     <<std::endl;
00130   }else if(pType == "mesonino" || pType == "sbaryon")
00131   {
00132       int sign=1;
00133       if(pdgCode < 0 ) sign=-1;
00134 
00135     G4String cloudname = name+"cloud";
00136     G4String cloudtype = pType+"cloud";
00137     if(CustomPDGParser::s_isstopHadron(pdgCode))
00138     {
00139     spectator = theParticleTable->FindParticle(1000006*sign);
00140     }
00141     else 
00142     { 
00143       if(CustomPDGParser::s_issbottomHadron(pdgCode)) {
00144           spectator = theParticleTable->FindParticle(1000005*sign);
00145       } 
00146        else
00147       {
00148         spectator = 0;
00149         edm::LogError("CustomPhysics")<< " Cannot find spectator parton";
00150       }
00151      }
00152     spectatormass = spectator->GetPDGMass();
00153     G4double cloudmass = mass-spectatormass/GeV;
00154     CustomParticle *tmpParticle  = new CustomParticle(
00155                                                       cloudname,           cloudmass * GeV ,        0.0*MeV,  0 ,
00156                                                       0,              +1,             0,
00157                                                       0,              0,             0,
00158                                                       cloudtype,               0,            +1, 0,
00159                                                       true,            -1.0,          NULL );
00160     particle->SetCloud(tmpParticle);
00161     particle->SetSpectator(spectator);
00162 
00163     edm::LogInfo("CustomPhysics")<<name<<" being assigned "
00164                     <<particle->GetCloud()->GetParticleName()
00165                     <<" and "<<particle->GetSpectator()->GetParticleName()<<std::endl;
00166     edm::LogInfo("CustomPhysics")<<"Masses: "
00167                     <<particle->GetPDGMass()/GeV<<" Gev, "
00168                     <<particle->GetCloud()->GetPDGMass()/GeV<<" GeV and "
00169                     <<particle->GetSpectator()->GetPDGMass()/GeV<<" GeV."
00170                     <<std::endl;
00171   }
00172   else{
00173     particle->SetCloud(0);
00174     particle->SetSpectator(0);
00175   } 
00176   m_particles.insert(particle);
00177 }
00178 
00179 void  CustomParticleFactory::getMassTable(std::ifstream *configFile) {
00180 
00181   int pdgId;
00182   double mass;
00183   std::string name, tmp;
00184   std::string line;
00185   // This should be compatible IMO to SLHA 
00186   while(getline(*configFile,line))
00187     {
00188     if(tmp.find("Blo")<tmp.npos) break;
00189     std::stringstream sstr(line);
00190     sstr >>pdgId>>mass>>tmp>>name;
00191 
00192      addCustomParticle(pdgId, fabs(mass), name);
00194     int pdgIdPartner = pdgId%100;
00195     G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00196     G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgIdPartner);
00197     //Add antiparticles for SUSY particles only, not for rHadrons.
00198     if(aParticle && !CustomPDGParser::s_isRHadron(pdgId) && !CustomPDGParser::s_isstopHadron(pdgId)&& pdgId!=1000006 && pdgId!=-1000006  && pdgId!=25 && pdgId!=35 && pdgId!=36 && pdgId!=37){ 
00199     int sign = aParticle->GetAntiPDGEncoding()/pdgIdPartner;   
00200       if(abs(sign)!=1) {
00201         std::cout<<"sgn: "<<sign<<" a "
00202                  <<aParticle->GetAntiPDGEncoding()
00203                  <<" b "<<pdgIdPartner
00204                  <<std::endl;
00205         aParticle->DumpTable();
00206       }
00207       if(sign==-1 && pdgId!=25 && pdgId!=35 && pdgId!=36 && pdgId!=37 && pdgId!=1000039){
00208           tmp = "anti_"+name;
00209           addCustomParticle(-pdgId, mass, tmp);
00210           theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
00211         }
00212         else theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);      
00213     }
00214 
00215     if(pdgId==1000039) theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);      
00216     if(pdgId==1000024 || pdgId==1000037 || pdgId==37) {
00217       tmp = "anti_"+name;
00218       addCustomParticle(-pdgId, mass, tmp);
00219       theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
00220     }
00221 
00222 /*    getline(*configFile,tmp);
00223     char text[100];
00224     configFile->get(text,3);
00225     tmp.clear();
00226     tmp.append(text);
00227     if(tmp.find("Bl")<tmp.npos) break;*/
00228   }
00229 }
00230 
00231 G4DecayTable*  CustomParticleFactory::getDecayTable(std::ifstream *configFile, int pdgId) {
00232 
00233   double br;
00234   int nDaughters;
00235   std::vector<int> pdg(4);
00236   std::string tmp;
00237   std::vector<std::string> name(4);
00238 
00239   G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00240 
00241   std::string parentName = theParticleTable->FindParticle(pdgId)->GetParticleName();
00242   G4DecayTable *decaytable= new G4DecayTable();
00243 
00244   getline(*configFile,tmp);
00245 
00246   while(!configFile->eof()){
00247     pdg.clear();
00248     name.clear();
00249     (*configFile)>>br>>nDaughters;
00250     for(int i=0;i<nDaughters;i++) (*configFile)>>pdg[i];
00251     getline(*configFile,tmp);
00252     for(int i=0;i<nDaughters;i++){
00253       if(!theParticleTable->FindParticle(pdg[i])){
00254         //std::cout<<pdg[i]<<" CustomParticleFactory::getDecayTable():  not found in the table!"<<std::endl;
00255         continue;
00256       }
00257       name[i] =  theParticleTable->FindParticle(pdg[i])->GetParticleName();
00258     }
00260     G4PhaseSpaceDecayChannel *aDecayChannel = new G4PhaseSpaceDecayChannel(parentName, br, nDaughters,
00261                                                                            name[0],name[1],name[2],name[3]);    
00262     decaytable->Insert(aDecayChannel);
00263   
00265 
00266     char text[200];
00267     configFile->get(text,2);
00268     tmp.clear();
00269     tmp.append(text);
00270     if(tmp.find("#")<tmp.npos) break;  
00271   }
00272 
00273   return decaytable;
00274 }
00275 
00276 G4DecayTable*  CustomParticleFactory::getAntiDecayTable(int pdgId,  G4DecayTable *theDecayTable) {
00277 
00278     std::vector<std::string> name(4);
00279   G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00280 
00281   std::string parentName = theParticleTable->FindParticle(-pdgId)->GetParticleName();
00282   G4DecayTable *decaytable= new G4DecayTable();
00283 
00284   for(int i=0;i<theDecayTable->entries();i++){
00285     //G4PhaseSpaceDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(i); 
00286     G4VDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(i); 
00287     for(int j=0;j<theDecayChannel->GetNumberOfDaughters();j++){
00288       int id = theDecayChannel->GetDaughter(j)->GetAntiPDGEncoding();
00289       std::string nameTmp = theParticleTable->FindParticle(id)->GetParticleName();
00290       name[j] = nameTmp;
00291     }
00292     G4PhaseSpaceDecayChannel *aDecayChannel = 
00293       new G4PhaseSpaceDecayChannel(parentName, 
00294                                    theDecayChannel->GetBR(),
00295                                    theDecayChannel->GetNumberOfDaughters(),
00296                                    name[0],name[1],name[2],name[3]);  
00297     decaytable->Insert(aDecayChannel);
00298   }
00299   return decaytable;
00300 }