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 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
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
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
00209
00210
00211
00212
00213
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
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
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 }