18 #include <G4ParticleTable.hh> 19 #include "G4DecayTable.hh" 20 #include <G4PhaseSpaceDecayChannel.hh> 21 #include "G4ProcessManager.hh" 23 using namespace CLHEP;
32 std::ifstream configFile(filePath.c_str());
36 <<
"CustomParticleFactory: Reading Custom Particle and G4DecayTable from \n" 39 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
40 while(getline(configFile,line)){
41 line.erase(0, line.find_first_not_of(
" \t"));
42 if (line.length()==0 || line.at(0) ==
'#')
continue;
43 if (ToLower(line).find(
"block") < line.npos &&
44 ToLower(line).find(
"mass") < line.npos) {
45 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Retrieving mass table.";
46 getMassTable(&configFile);
48 if(line.find(
"DECAY")<line.npos){
52 std::stringstream lineStream(line);
53 lineStream >> tmpString >> pdgId >>
width;
56 <<
"CustomParticleFactory: entry to G4DecayTable: pdgID, width " << pdgId <<
", " <<
width;
57 G4DecayTable* aDecayTable = getDecayTable(&configFile, pdgId);
58 G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgId);
59 G4ParticleDefinition *aAntiParticle = theParticleTable->FindAntiParticle(pdgId);
60 if (!aParticle)
continue;
61 aParticle->SetDecayTable(aDecayTable);
62 aParticle->SetPDGStable(
false);
63 aParticle->SetPDGLifeTime(1.0/(width*
GeV)*6.582122
e-22*
MeV*
s);
64 if(aAntiParticle && aAntiParticle->GetPDGEncoding()!=
pdgId){
65 aAntiParticle->SetDecayTable(getAntiDecayTable(pdgId,aDecayTable));
66 aAntiParticle->SetPDGStable(
false);
67 aAntiParticle->SetPDGLifeTime(1.0/(width*GeV)*6.582122
e-22*
MeV*s);
75 if(
abs(pdgCode)%100 <14 &&
abs(pdgCode) / 1000000 == 0){
76 edm::LogError(
"") <<
"Pdg code too low " << pdgCode <<
" "<<
abs(pdgCode) / 1000000;
81 G4String pType=
"custom";
83 G4double spectatormass = 0.0;
84 G4ParticleDefinition* spectator =
nullptr;
91 double massGeV =mass*
GeV;
94 if (name.compare(0,4,
"~HIP") == 0)
96 if ((name.compare(0,7,
"~HIPbar") == 0)) {
98 charge=eplus*atoi(str.c_str())/3.;
101 charge=eplus*atoi(str.c_str())*-1./3.;
104 if (name.compare(0,9,
"anti_~HIP") == 0)
106 if ((name.compare(0,12,
"anti_~HIPbar") == 0)) {
108 charge=eplus*atoi(str.c_str())*-1./3.;
111 charge=eplus*atoi(str.c_str())*1./3.;
123 double lifetime = -1;
139 G4DecayTable *decaytable =
nullptr;
140 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
143 parity, conjugation, isospin, isospinZ,
144 gParity, pType, lepton, baryon, pdgCode,
145 stable, lifetime, decaytable);
147 if(pType ==
"rhadron" && name!=
"~g"){
148 G4String cloudname = name+
"cloud";
149 G4String cloudtype = pType+
"cloud";
150 spectator = theParticleTable->FindParticle(1000021);
151 spectatormass = spectator->GetPDGMass();
152 G4double cloudmass = mass-spectatormass/
GeV;
154 cloudname, cloudmass * GeV , 0.0*
MeV, 0 ,
158 true, -1.0,
nullptr );
163 <<
"CustomParticleFactory: " <<name<<
" being assigned " 164 <<particle->
GetCloud()->GetParticleName()
165 <<
" and "<<particle->
GetSpectator()->GetParticleName() <<
"\n" 166 <<
" Masses: "<<particle->GetPDGMass()/GeV<<
" Gev, " 167 <<particle->
GetCloud()->GetPDGMass()/GeV<<
" GeV and " 169 }
else if(pType ==
"mesonino" || pType ==
"sbaryon") {
171 if(pdgCode < 0 ) sign=-1;
173 G4String cloudname = name+
"cloud";
174 G4String cloudtype = pType+
"cloud";
176 spectator = theParticleTable->FindParticle(1000006*sign);
180 spectator = theParticleTable->FindParticle(1000005*sign);
183 edm::LogError(
"SimG4CoreCustomPhysics")<<
"CustomParticleFactory: Cannot find spectator parton";
186 if(spectator) spectatormass = spectator->GetPDGMass();
187 G4double cloudmass = mass-spectatormass/
GeV;
189 cloudname, cloudmass * GeV , 0.0*
MeV, 0 ,
193 true, -1.0,
nullptr );
198 <<
"CustomParticleFactory: "<<name<<
" being assigned " 199 <<particle->
GetCloud()->GetParticleName()
200 <<
" and "<<particle->
GetSpectator()->GetParticleName() <<
"\n" 202 <<particle->GetPDGMass()/GeV<<
" Gev, " 203 <<particle->
GetCloud()->GetPDGMass()/GeV<<
" GeV and " 210 m_particles.push_back(particle);
220 while (getline(*configFile,line)) {
221 line.erase(0, line.find_first_not_of(
" \t"));
222 if (line.length()==0 || line.at(0) ==
'#')
continue;
223 if (ToLower(line).find(
"block") < line.npos) {
225 <<
"CustomParticleFactory: Finished the Mass Table ";
228 std::stringstream sstr(line);
229 sstr >> pdgId >> mass >> tmp >>
name;
232 <<
"CustomParticleFactory: Calling addCustomParticle for pdgId: " << pdgId
233 <<
", mass " << mass <<
", name " <<
name;
234 addCustomParticle(pdgId, fabs(mass), name);
236 int pdgIdPartner = pdgId%100;
237 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
238 G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgIdPartner);
241 <<
"CustomParticleFactory: Found aParticle = " << aParticle
242 <<
", pdgId = " << pdgId
243 <<
", pdgIdPartner = " << pdgIdPartner
249 !CustomPDGParser::s_isstopHadron(pdgId) &&
256 int sign = aParticle->GetAntiPDGEncoding()/pdgIdPartner;
258 <<
"CustomParticleFactory: Found sign = " << sign
259 <<
", aParticle->GetAntiPDGEncoding() " << aParticle->GetAntiPDGEncoding()
260 <<
", pdgIdPartner = " << pdgIdPartner;
263 <<
"CustomParticleFactory: sgn= "<<sign<<
" a " 264 <<aParticle->GetAntiPDGEncoding()<<
" b "<<pdgIdPartner;
265 aParticle->DumpTable();
267 if(sign==-1 && pdgId!=25 && pdgId!=35 && pdgId!=36 && pdgId!=37 && pdgId!=1000039){
270 <<
"CustomParticleFactory: Calling addCustomParticle for antiparticle with pdgId: " 271 << -pdgId <<
", mass " << mass <<
", name " <<
tmp;
272 addCustomParticle(-pdgId, mass, tmp);
273 theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
275 else theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);
278 if(pdgId==1000039) theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);
279 if(pdgId==1000024 || pdgId==1000037 || pdgId==37) {
282 <<
"CustomParticleFactory: Calling addCustomParticle for antiparticle (2) with pdgId: " 283 << -pdgId <<
", mass " << mass <<
", name " <<
tmp;
284 addCustomParticle(-pdgId, mass, tmp);
285 theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
294 std::vector<int> pdg(4);
296 std::vector<std::string>
name(4);
298 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
300 std::string parentName = theParticleTable->FindParticle(pdgId)->GetParticleName();
301 G4DecayTable *decaytable=
new G4DecayTable();
303 while(getline(*configFile,line)) {
305 line.erase(0, line.find_first_not_of(
" \t"));
306 if (line.length()==0)
continue;
307 if (line.at(0) ==
'#' &&
308 ToLower(line).find(
"br") < line.npos &&
309 ToLower(line).find(
"nda") < line.npos)
continue;
310 if (line.at(0) ==
'#') {
311 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Finished the Decay Table ";
318 std::stringstream sstr(line);
319 sstr >> br >> nDaughters;
321 <<
"CustomParticleFactory: Branching Ratio: " << br <<
", Number of Daughters: " << nDaughters;
322 if (nDaughters > 4) {
324 <<
"CustomParticleFactory: Number of daughters is too large (max = 4): " << nDaughters
325 <<
" for pdgId: " <<
pdgId;
328 for(
int i=0;
i<nDaughters;
i++) {
330 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Daughter ID " << pdg[
i];
331 const G4ParticleDefinition*
part = theParticleTable->FindParticle(pdg[
i]);
334 <<
"CustomParticleFactory: particle with PDG code"<<pdg[
i] <<
" not found!";
337 name[
i] = part->GetParticleName();
340 G4PhaseSpaceDecayChannel *aDecayChannel =
new G4PhaseSpaceDecayChannel(parentName, br, nDaughters,
341 name[0],name[1],name[2],name[3]);
342 decaytable->Insert(aDecayChannel);
349 std::vector<std::string>
name(4);
350 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
352 std::string parentName = theParticleTable->FindParticle(-pdgId)->GetParticleName();
353 G4DecayTable *decaytable=
new G4DecayTable();
355 for(
int i=0;
i<theDecayTable->entries();
i++){
356 G4VDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(
i);
357 int nd =
std::min(4, theDecayChannel->GetNumberOfDaughters());
358 for(
int j=0; j<nd; ++j){
359 int id = theDecayChannel->GetDaughter(j)->GetAntiPDGEncoding();
360 const G4ParticleDefinition*
part = theParticleTable->FindParticle(
id);
363 <<
"CustomParticleFactory: antiparticle with PDG code"<<
id <<
" not found!";
366 name[
i] = part->GetParticleName();
368 G4PhaseSpaceDecayChannel *aDecayChannel =
369 new G4PhaseSpaceDecayChannel(parentName,
370 theDecayChannel->GetBR(), nd,
371 name[0],name[1],name[2],name[3]);
372 decaytable->Insert(aDecayChannel);
380 str.at(
i) = std::tolower(str.at(
i),
loc);
static bool s_isDphoton(int pdg)
static double s_charge(int pdg)
static bool s_isSbaryon(int pdg)
void SetCloud(G4ParticleDefinition *theCloud)
G4ParticleDefinition * GetCloud()
static void loadCustomParticles(const std::string &filePath)
static std::vector< G4ParticleDefinition * > m_particles
static bool s_isMesonino(int pdg)
static bool s_isSLepton(int pdg)
Abs< T >::type abs(const T &t)
static std::string ToLower(std::string str)
void SetSpectator(G4ParticleDefinition *theSpectator)
static double s_spin(int pdg)
G4ParticleDefinition * GetSpectator()
static void getMassTable(std::ifstream *configFile)
static G4DecayTable * getDecayTable(std::ifstream *configFile, int pdgId)
static void addCustomParticle(int pdgCode, double mass, const std::string &name)
static G4DecayTable * getAntiDecayTable(int pdgId, G4DecayTable *theDecayTable)
static bool s_isRHadron(int pdg)
std::vector< std::vector< double > > tmp
static const std::vector< G4ParticleDefinition * > & GetCustomParticles()
static bool s_issbottomHadron(int pdg)
static bool s_isstopHadron(int pdg)