CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/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(abs(pdgCode)%100 <14 && 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     if (name.compare(0,4,"~HIP") == 0)
00089     {
00090 
00091        if ((name.compare(0,7,"~HIPbar") == 0))  {std::string str = name.substr (7); charge=eplus*atoi(str.c_str())/3.;}
00092        else {std::string str = name.substr (4); charge=eplus*atoi(str.c_str())*-1./3.;  }
00093     }
00094     if (name.compare(0,9,"anti_~HIP") == 0)
00095     {
00096 
00097        if ((name.compare(0,12,"anti_~HIPbar") == 0))  {std::string str = name.substr (12); charge=eplus*atoi(str.c_str())*-1./3.;}
00098        else {std::string str = name.substr (9); charge=eplus*atoi(str.c_str())*1./3.;  }
00099     }
00100   int spin =  (int)CustomPDGParser::s_spin(pdgCode)-1;
00101   int parity = +1;
00102   int conjugation = 0;
00103   int isospin = 0;
00104   int isospinZ = 0;
00105   int gParity = 0;
00106   int lepton = 0;  //FIXME:
00107   int baryon = 1;  //FIXME: 
00108   bool stable = true;
00109   double lifetime = -1;
00110  
00111   G4DecayTable *decaytable = NULL;
00112   G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00113 
00114   CustomParticle *particle  = new CustomParticle(name, massGeV, width, charge, spin, 
00115                                                  parity, conjugation, isospin, isospinZ,
00116                                                  gParity, pType, lepton, baryon, pdgCode,
00117                                                  stable, lifetime, decaytable);
00118  
00119   if(pType == "rhadron" && name!="~g"){  
00120     G4String cloudname = name+"cloud";
00121     G4String cloudtype = pType+"cloud";
00122     spectator = theParticleTable->FindParticle(1000021);
00123     spectatormass = spectator->GetPDGMass();
00124     G4double cloudmass = mass-spectatormass/GeV;
00125     CustomParticle *tmpParticle  = new CustomParticle(
00126                                                       cloudname,           cloudmass * GeV ,        0.0*MeV,  0 , 
00127                                                       0,              +1,             0,          
00128                                                       0,              0,             0,             
00129                                                       cloudtype,               0,            +1, 0,
00130                                                       true,            -1.0,          NULL );
00131     particle->SetCloud(tmpParticle);
00132     particle->SetSpectator(spectator);
00133     
00134     edm::LogInfo("CustomPhysics")<<name<<" being assigned "
00135                     <<particle->GetCloud()->GetParticleName()
00136                     <<" and "<<particle->GetSpectator()->GetParticleName()<<std::endl;
00137     edm::LogInfo("CustomPhysics")<<"Masses: "
00138                     <<particle->GetPDGMass()/GeV<<" Gev, "
00139                     <<particle->GetCloud()->GetPDGMass()/GeV<<" GeV and "
00140                     <<particle->GetSpectator()->GetPDGMass()/GeV<<" GeV."
00141                     <<std::endl;
00142   }else if(pType == "mesonino" || pType == "sbaryon")
00143   {
00144       int sign=1;
00145       if(pdgCode < 0 ) sign=-1;
00146 
00147     G4String cloudname = name+"cloud";
00148     G4String cloudtype = pType+"cloud";
00149     if(CustomPDGParser::s_isstopHadron(pdgCode))
00150     {
00151     spectator = theParticleTable->FindParticle(1000006*sign);
00152     }
00153     else 
00154     { 
00155       if(CustomPDGParser::s_issbottomHadron(pdgCode)) {
00156           spectator = theParticleTable->FindParticle(1000005*sign);
00157       } 
00158        else
00159       {
00160         spectator = 0;
00161         edm::LogError("CustomPhysics")<< " Cannot find spectator parton";
00162       }
00163      }
00164     spectatormass = spectator->GetPDGMass();
00165     G4double cloudmass = mass-spectatormass/GeV;
00166     CustomParticle *tmpParticle  = new CustomParticle(
00167                                                       cloudname,           cloudmass * GeV ,        0.0*MeV,  0 ,
00168                                                       0,              +1,             0,
00169                                                       0,              0,             0,
00170                                                       cloudtype,               0,            +1, 0,
00171                                                       true,            -1.0,          NULL );
00172     particle->SetCloud(tmpParticle);
00173     particle->SetSpectator(spectator);
00174 
00175     edm::LogInfo("CustomPhysics")<<name<<" being assigned "
00176                     <<particle->GetCloud()->GetParticleName()
00177                     <<" and "<<particle->GetSpectator()->GetParticleName()<<std::endl;
00178     edm::LogInfo("CustomPhysics")<<"Masses: "
00179                     <<particle->GetPDGMass()/GeV<<" Gev, "
00180                     <<particle->GetCloud()->GetPDGMass()/GeV<<" GeV and "
00181                     <<particle->GetSpectator()->GetPDGMass()/GeV<<" GeV."
00182                     <<std::endl;
00183   }
00184   else{
00185     particle->SetCloud(0);
00186     particle->SetSpectator(0);
00187   } 
00188   m_particles.insert(particle);
00189 }
00190 
00191 void  CustomParticleFactory::getMassTable(std::ifstream *configFile) {
00192 
00193   int pdgId;
00194   double mass;
00195   std::string name, tmp;
00196   std::string line;
00197   // This should be compatible IMO to SLHA 
00198   while(getline(*configFile,line))
00199     {
00200     if(tmp.find("Blo")<tmp.npos) break;
00201     std::stringstream sstr(line);
00202     sstr >>pdgId>>mass>>tmp>>name;
00203 
00204      addCustomParticle(pdgId, fabs(mass), name);
00206     int pdgIdPartner = pdgId%100;
00207     G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00208     G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgIdPartner);
00209     //Add antiparticles for SUSY particles only, not for rHadrons.
00210     if(aParticle && !CustomPDGParser::s_isRHadron(pdgId) && !CustomPDGParser::s_isstopHadron(pdgId)&& pdgId!=1000006 && pdgId!=-1000006  && pdgId!=25 && pdgId!=35 && pdgId!=36 && pdgId!=37){ 
00211     int sign = aParticle->GetAntiPDGEncoding()/pdgIdPartner;   
00212       if(abs(sign)!=1) {
00213         std::cout<<"sgn: "<<sign<<" a "
00214                  <<aParticle->GetAntiPDGEncoding()
00215                  <<" b "<<pdgIdPartner
00216                  <<std::endl;
00217         aParticle->DumpTable();
00218       }
00219       if(sign==-1 && pdgId!=25 && pdgId!=35 && pdgId!=36 && pdgId!=37 && pdgId!=1000039){
00220           tmp = "anti_"+name;
00221           addCustomParticle(-pdgId, mass, tmp);
00222           theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
00223         }
00224         else theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);      
00225     }
00226 
00227     if(pdgId==1000039) theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);      
00228     if(pdgId==1000024 || pdgId==1000037 || pdgId==37) {
00229       tmp = "anti_"+name;
00230       addCustomParticle(-pdgId, mass, tmp);
00231       theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
00232     }
00233 
00234 /*    getline(*configFile,tmp);
00235     char text[100];
00236     configFile->get(text,3);
00237     tmp.clear();
00238     tmp.append(text);
00239     if(tmp.find("Bl")<tmp.npos) break;*/
00240   }
00241 }
00242 
00243 G4DecayTable*  CustomParticleFactory::getDecayTable(std::ifstream *configFile, int pdgId) {
00244 
00245   double br;
00246   int nDaughters;
00247   std::vector<int> pdg(4);
00248   std::string tmp;
00249   std::vector<std::string> name(4);
00250 
00251   G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00252 
00253   std::string parentName = theParticleTable->FindParticle(pdgId)->GetParticleName();
00254   G4DecayTable *decaytable= new G4DecayTable();
00255 
00256   getline(*configFile,tmp);
00257 
00258   while(!configFile->eof()){
00259     pdg.clear();
00260     name.clear();
00261     (*configFile)>>br>>nDaughters;
00262     for(int i=0;i<nDaughters;i++) (*configFile)>>pdg[i];
00263     getline(*configFile,tmp);
00264     for(int i=0;i<nDaughters;i++){
00265       if(!theParticleTable->FindParticle(pdg[i])){
00266         //std::cout<<pdg[i]<<" CustomParticleFactory::getDecayTable():  not found in the table!"<<std::endl;
00267         continue;
00268       }
00269       name[i] =  theParticleTable->FindParticle(pdg[i])->GetParticleName();
00270     }
00272     G4PhaseSpaceDecayChannel *aDecayChannel = new G4PhaseSpaceDecayChannel(parentName, br, nDaughters,
00273                                                                            name[0],name[1],name[2],name[3]);    
00274     decaytable->Insert(aDecayChannel);
00275   
00277 
00278     char text[200];
00279     configFile->get(text,2);
00280     tmp.clear();
00281     tmp.append(text);
00282     if(tmp.find("#")<tmp.npos) break;  
00283   }
00284 
00285   return decaytable;
00286 }
00287 
00288 G4DecayTable*  CustomParticleFactory::getAntiDecayTable(int pdgId,  G4DecayTable *theDecayTable) {
00289 
00290     std::vector<std::string> name(4);
00291   G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00292 
00293   std::string parentName = theParticleTable->FindParticle(-pdgId)->GetParticleName();
00294   G4DecayTable *decaytable= new G4DecayTable();
00295 
00296   for(int i=0;i<theDecayTable->entries();i++){
00297     //G4PhaseSpaceDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(i); 
00298     G4VDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(i); 
00299     for(int j=0;j<theDecayChannel->GetNumberOfDaughters();j++){
00300       int id = theDecayChannel->GetDaughter(j)->GetAntiPDGEncoding();
00301       std::string nameTmp = theParticleTable->FindParticle(id)->GetParticleName();
00302       name[j] = nameTmp;
00303     }
00304     G4PhaseSpaceDecayChannel *aDecayChannel = 
00305       new G4PhaseSpaceDecayChannel(parentName, 
00306                                    theDecayChannel->GetBR(),
00307                                    theDecayChannel->GetNumberOfDaughters(),
00308                                    name[0],name[1],name[2],name[3]);  
00309     decaytable->Insert(aDecayChannel);
00310   }
00311   return decaytable;
00312 }