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
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
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;
00095 int baryon = 1;
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
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
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
00223
00224
00225
00226
00227
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
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
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 }