CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/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     spectator = theParticleTable->FindParticle(1000006*sign);
00138     spectatormass = spectator->GetPDGMass();
00139     G4double cloudmass = mass-spectatormass/GeV;
00140     CustomParticle *tmpParticle  = new CustomParticle(
00141                                                       cloudname,           cloudmass * GeV ,        0.0*MeV,  0 ,
00142                                                       0,              +1,             0,
00143                                                       0,              0,             0,
00144                                                       cloudtype,               0,            +1, 0,
00145                                                       true,            -1.0,          NULL );
00146     particle->SetCloud(tmpParticle);
00147     particle->SetSpectator(spectator);
00148 
00149     edm::LogInfo("CustomPhysics")<<name<<" being assigned "
00150                     <<particle->GetCloud()->GetParticleName()
00151                     <<" and "<<particle->GetSpectator()->GetParticleName()<<std::endl;
00152     edm::LogInfo("CustomPhysics")<<"Masses: "
00153                     <<particle->GetPDGMass()/GeV<<" Gev, "
00154                     <<particle->GetCloud()->GetPDGMass()/GeV<<" GeV and "
00155                     <<particle->GetSpectator()->GetPDGMass()/GeV<<" GeV."
00156                     <<std::endl;
00157   }
00158   else{
00159     particle->SetCloud(0);
00160     particle->SetSpectator(0);
00161   } 
00162   m_particles.insert(particle);
00163 }
00164 
00165 void  CustomParticleFactory::getMassTable(std::ifstream *configFile) {
00166 
00167   int pdgId;
00168   double mass;
00169   std::string name, tmp;
00170   std::string line;
00171   // This should be compatible IMO to SLHA 
00172   while(getline(*configFile,line))
00173     {
00174     if(tmp.find("Blo")<tmp.npos) break;
00175     std::stringstream sstr(line);
00176     sstr >>pdgId>>mass>>tmp>>name;
00177 
00178      addCustomParticle(pdgId, fabs(mass), name);
00180     int pdgIdPartner = pdgId%100;
00181     G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00182     G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgIdPartner);
00183     //Add antiparticles for SUSY particles only, not for rHadrons.
00184     if(aParticle && !CustomPDGParser::s_isRHadron(pdgId) && !CustomPDGParser::s_isstopHadron(pdgId)&& pdgId!=1000006 && pdgId!=-1000006  && pdgId!=25 && pdgId!=35 && pdgId!=36 && pdgId!=37){ 
00185     int sign = aParticle->GetAntiPDGEncoding()/pdgIdPartner;   
00186       if(abs(sign)!=1) {
00187         std::cout<<"sgn: "<<sign<<" a "
00188                  <<aParticle->GetAntiPDGEncoding()
00189                  <<" b "<<pdgIdPartner
00190                  <<std::endl;
00191         aParticle->DumpTable();
00192       }
00193       if(sign==-1 && pdgId!=25 && pdgId!=35 && pdgId!=36 && pdgId!=37 && pdgId!=1000039){
00194           tmp = "anti_"+name;
00195           addCustomParticle(-pdgId, mass, tmp);
00196           theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
00197         }
00198         else theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);      
00199     }
00200 
00201     if(pdgId==1000039) theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);      
00202     if(pdgId==1000024 || pdgId==1000037 || pdgId==37) {
00203       tmp = "anti_"+name;
00204       addCustomParticle(-pdgId, mass, tmp);
00205       theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
00206     }
00207 
00208 /*    getline(*configFile,tmp);
00209     char text[100];
00210     configFile->get(text,3);
00211     tmp.clear();
00212     tmp.append(text);
00213     if(tmp.find("Bl")<tmp.npos) break;*/
00214   }
00215 }
00216 
00217 G4DecayTable*  CustomParticleFactory::getDecayTable(std::ifstream *configFile, int pdgId) {
00218 
00219   double br;
00220   int nDaughters;
00221   std::vector<int> pdg(4);
00222   std::string tmp;
00223   std::vector<std::string> name(4);
00224 
00225   G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00226 
00227   std::string parentName = theParticleTable->FindParticle(pdgId)->GetParticleName();
00228   G4DecayTable *decaytable= new G4DecayTable();
00229 
00230   getline(*configFile,tmp);
00231 
00232   while(!configFile->eof()){
00233     pdg.clear();
00234     name.clear();
00235     (*configFile)>>br>>nDaughters;
00236     for(int i=0;i<nDaughters;i++) (*configFile)>>pdg[i];
00237     getline(*configFile,tmp);
00238     for(int i=0;i<nDaughters;i++){
00239       if(!theParticleTable->FindParticle(pdg[i])){
00240         //std::cout<<pdg[i]<<" CustomParticleFactory::getDecayTable():  not found in the table!"<<std::endl;
00241         continue;
00242       }
00243       name[i] =  theParticleTable->FindParticle(pdg[i])->GetParticleName();
00244     }
00246     G4PhaseSpaceDecayChannel *aDecayChannel = new G4PhaseSpaceDecayChannel(parentName, br, nDaughters,
00247                                                                            name[0],name[1],name[2],name[3]);    
00248     decaytable->Insert(aDecayChannel);
00249   
00251 
00252     char text[200];
00253     configFile->get(text,2);
00254     tmp.clear();
00255     tmp.append(text);
00256     if(tmp.find("#")<tmp.npos) break;  
00257   }
00258 
00259   return decaytable;
00260 }
00261 
00262 G4DecayTable*  CustomParticleFactory::getAntiDecayTable(int pdgId,  G4DecayTable *theDecayTable) {
00263 
00264     std::vector<std::string> name(4);
00265   G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
00266 
00267   std::string parentName = theParticleTable->FindParticle(-pdgId)->GetParticleName();
00268   G4DecayTable *decaytable= new G4DecayTable();
00269 
00270   for(int i=0;i<theDecayTable->entries();i++){
00271     //G4PhaseSpaceDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(i); 
00272     G4VDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(i); 
00273     for(int j=0;j<theDecayChannel->GetNumberOfDaughters();j++){
00274       int id = theDecayChannel->GetDaughter(j)->GetAntiPDGEncoding();
00275       std::string nameTmp = theParticleTable->FindParticle(id)->GetParticleName();
00276       name[j] = nameTmp;
00277     }
00278     G4PhaseSpaceDecayChannel *aDecayChannel = 
00279       new G4PhaseSpaceDecayChannel(parentName, 
00280                                    theDecayChannel->GetBR(),
00281                                    theDecayChannel->GetNumberOfDaughters(),
00282                                    name[0],name[1],name[2],name[3]);  
00283     decaytable->Insert(aDecayChannel);
00284   }
00285   return decaytable;
00286 }