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(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;
00107 int baryon = 1;
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
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
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
00235
00236
00237
00238
00239
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
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
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 }