8 #include "G4ParticleTable.hh"
9 #include "G4DecayTable.hh"
10 #include "G4PhaseSpaceDecayChannel.hh"
11 #include "G4ProcessManager.hh"
12 #include "G4ParticleDefinition.hh"
13 #include "G4SystemOfUnits.hh"
25 #ifdef G4MULTITHREADED
26 G4Mutex CustomParticleFactory::customParticleFactoryMutex = G4MUTEX_INITIALIZER;
37 #ifdef G4MULTITHREADED
38 G4MUTEXLOCK(&customParticleFactoryMutex);
46 std::ifstream configFile(
filePath.c_str());
49 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Reading Custom Particle and G4DecayTable from \n"
52 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
53 while (getline(configFile,
line)) {
54 line.erase(0,
line.find_first_not_of(
" \t"));
55 if (
line.length() == 0 ||
line.at(0) ==
'#') {
60 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Retrieving mass table.";
63 if (
line.find(
"DECAY") <
line.npos) {
67 std::stringstream lineStream(
line);
71 <<
"CustomParticleFactory: entry to G4DecayTable: pdgID, width " <<
pdgId <<
", " <<
width;
72 G4ParticleDefinition *aParticle = theParticleTable->FindParticle(
pdgId);
73 if (!aParticle ||
width == 0.0) {
77 aParticle->SetDecayTable(aDecayTable);
78 aParticle->SetPDGStable(
false);
80 G4ParticleDefinition *aAntiParticle = theParticleTable->FindAntiParticle(
pdgId);
81 if (aAntiParticle && aAntiParticle->GetPDGEncoding() !=
pdgId) {
83 aAntiParticle->SetPDGStable(
false);
88 #ifdef G4MULTITHREADED
89 G4MUTEXUNLOCK(&customParticleFactoryMutex);
96 <<
"Pdg code too low " << pdgCode <<
" " <<
std::abs(pdgCode) / 1000000;
109 G4String pType =
"custom";
110 G4String pSubType =
"";
111 G4double spectatormass = 0.0;
112 G4ParticleDefinition *spectator =
nullptr;
130 if (
name.compare(0, 4,
"~HIP") == 0) {
131 if ((
name.compare(0, 7,
"~HIPbar") == 0)) {
133 charge = CLHEP::eplus * atoi(
str.c_str()) / 3.;
136 charge = -CLHEP::eplus * atoi(
str.c_str()) / 3.;
139 if (
name.compare(0, 9,
"anti_~HIP") == 0) {
140 if ((
name.compare(0, 12,
"anti_~HIPbar") == 0)) {
142 charge = -CLHEP::eplus * atoi(
str.c_str()) / 3.;
145 charge = CLHEP::eplus * atoi(
str.c_str()) / 3.;
157 double lifetime = -1;
173 G4DecayTable *decaytable =
nullptr;
174 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
194 if (pType ==
"rhadron" &&
name !=
"~g") {
195 G4String cloudname =
name +
"cloud";
196 G4String cloudtype = pType +
"cloud";
197 spectator = theParticleTable->FindParticle(1000021);
198 spectatormass = spectator->GetPDGMass();
199 G4double cloudmass = massGeV - spectatormass;
201 new CustomParticle(cloudname, cloudmass, 0.0, 0, 0, +1, 0, 0, 0, 0, cloudtype, 0, +1, 0,
true, -1.0,
nullptr);
206 <<
"CustomParticleFactory: " <<
name <<
" being assigned spectator" << spectator->GetParticleName()
207 <<
" and cloud " << cloudname <<
"\n"
208 <<
" Masses: " <<
mass <<
" Gev, " << spectatormass /
CLHEP::GeV <<
" GeV and "
210 }
else if (pType ==
"mesonino" || pType ==
"sbaryon") {
215 G4String cloudname =
name +
"cloud";
216 G4String cloudtype = pType +
"cloud";
218 spectator = theParticleTable->FindParticle(1000006 *
sign);
221 spectator = theParticleTable->FindParticle(1000005 *
sign);
224 edm::LogError(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Cannot find spectator parton";
228 spectatormass = spectator->GetPDGMass();
230 G4double cloudmass = massGeV - spectatormass;
232 new CustomParticle(cloudname, cloudmass, 0.0, 0, 0, +1, 0, 0, 0, 0, cloudtype, 0, +1, 0,
true, -1.0,
nullptr);
238 <<
"CustomParticleFactory: " <<
name <<
" being assigned spectator" << spectator->GetParticleName()
239 <<
" and cloud " << cloudname <<
"\n"
240 <<
" Masses: " <<
mass <<
" Gev, " << spectatormass /
CLHEP::GeV <<
" GeV and "
254 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
257 while (getline(*configFile,
line)) {
258 line.erase(0,
line.find_first_not_of(
" \t"));
259 if (
line.length() == 0 ||
line.at(0) ==
'#')
262 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Finished the Mass Table ";
265 std::stringstream sstr(
line);
269 if (theParticleTable->FindParticle(
pdgId)) {
274 <<
"CustomParticleFactory: Calling addCustomParticle for pdgId: " <<
pdgId <<
", mass " <<
mass <<
" GeV "
281 int pdgIdPartner =
pdgId % 100;
282 G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgIdPartner);
286 <<
"CustomParticleFactory: Found partner particle for "
287 <<
" pdgId= " <<
pdgId <<
", pdgIdPartner= " << pdgIdPartner <<
" " << aParticle->GetParticleName();
293 int sign = aParticle->GetAntiPDGEncoding() / pdgIdPartner;
295 <<
"CustomParticleFactory: For " << aParticle->GetParticleName() <<
" pdg= " << pdgIdPartner
296 <<
", GetAntiPDGEncoding() " << aParticle->GetAntiPDGEncoding() <<
" sign= " <<
sign;
299 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: sign= " <<
sign
300 <<
" a: " << aParticle->GetAntiPDGEncoding() <<
" b: " << pdgIdPartner;
301 aParticle->DumpTable();
305 if (!theParticleTable->FindParticle(-
pdgId)) {
307 <<
"CustomParticleFactory: Calling addCustomParticle for antiparticle with pdgId: " << -
pdgId <<
", mass "
308 <<
mass <<
" GeV, name " <<
tmp;
310 theParticleTable->FindParticle(
pdgId)->SetAntiPDGEncoding(-
pdgId);
313 theParticleTable->FindParticle(
pdgId)->SetAntiPDGEncoding(
pdgId);
316 if (
pdgId == 1000039)
317 theParticleTable->FindParticle(
pdgId)->SetAntiPDGEncoding(
pdgId);
320 if (!theParticleTable->FindParticle(-
pdgId)) {
322 <<
"CustomParticleFactory: Calling addCustomParticle for antiparticle (2) with pdgId: " << -
pdgId
323 <<
", mass " <<
mass <<
" GeV, name " <<
tmp;
325 theParticleTable->FindParticle(
pdgId)->SetAntiPDGEncoding(-
pdgId);
328 if (
pdgId == 9000006) {
330 edm::LogInfo(
"CustomPhysics") <<
"Calling addCustomParticle for antiparticle with pdgId: " << -
pdgId <<
", mass "
333 theParticleTable->FindParticle(
pdgId)->SetAntiPDGEncoding(-
pdgId);
344 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
346 std::string parentName = theParticleTable->FindParticle(
pdgId)->GetParticleName();
347 G4DecayTable *decaytable =
new G4DecayTable();
349 while (getline(*configFile,
line)) {
350 line.erase(0,
line.find_first_not_of(
" \t"));
351 if (
line.length() == 0)
356 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Finished the Decay Table ";
360 std::stringstream sstr(
line);
361 sstr >>
br >> nDaughters;
362 LogDebug(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Branching Ratio: " <<
br
363 <<
", Number of Daughters: " << nDaughters;
364 if (nDaughters > 4) {
366 <<
"CustomParticleFactory: Number of daughters is too large (max = 4): " << nDaughters
367 <<
" for pdgId: " <<
pdgId;
372 <<
"CustomParticleFactory: Branching ratio is " <<
br <<
" for pdgId: " <<
pdgId;
376 for (
int i = 0;
i < nDaughters; ++
i) {
378 LogDebug(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Daughter ID " <<
pdg[
i];
379 const G4ParticleDefinition *
part = theParticleTable->FindParticle(
pdg[
i]);
382 <<
"CustomParticleFactory: particle with PDG code" <<
pdg[
i] <<
" not found!";
388 G4PhaseSpaceDecayChannel *aDecayChannel =
389 new G4PhaseSpaceDecayChannel(parentName,
br, nDaughters,
name[0],
name[1],
name[2],
name[3]);
390 decaytable->Insert(aDecayChannel);
392 <<
"CustomParticleFactory: inserted decay channel "
393 <<
" for pdgID= " <<
pdgId <<
" " << parentName <<
" BR= " <<
br <<
" Daughters: " <<
name[0] <<
" "
401 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
403 std::string parentName = theParticleTable->FindParticle(-
pdgId)->GetParticleName();
404 G4DecayTable *decaytable =
new G4DecayTable();
406 for (
int i = 0;
i < theDecayTable->entries(); ++
i) {
407 G4VDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(
i);
408 int nd =
std::min(4, theDecayChannel->GetNumberOfDaughters());
409 for (
int j = 0;
j < nd; ++
j) {
410 int id = theDecayChannel->GetDaughter(
j)->GetAntiPDGEncoding();
411 const G4ParticleDefinition *
part = theParticleTable->FindParticle(
id);
414 <<
"CustomParticleFactory: antiparticle with PDG code" <<
id <<
" not found!";
419 G4PhaseSpaceDecayChannel *aDecayChannel =
420 new G4PhaseSpaceDecayChannel(parentName, theDecayChannel->GetBR(), nd,
name[0],
name[1],
name[2],
name[3]);
421 decaytable->Insert(aDecayChannel);
423 <<
"CustomParticleFactory: inserted decay channel "
424 <<
" for pdgID= " << -
pdgId <<
" " << parentName <<
" BR= " << theDecayChannel->GetBR()
425 <<
" Daughters: " <<
name[0] <<
" " <<
name[1] <<
" " <<
name[2] <<
" " <<
name[3];
433 str.at(
i) = std::tolower(
str.at(
i), loc);