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;
35 #ifdef G4MULTITHREADED
36 G4MUTEXLOCK(&customParticleFactoryMutex);
48 <<
"CustomParticleFactory: Reading Custom Particle and G4DecayTable from \n"
51 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
53 line.erase(0, line.find_first_not_of(
" \t"));
54 if (line.length() == 0 || line.at(0) ==
'#') {
58 if (
ToLower(line).find(
"block") < line.npos &&
ToLower(line).find(
"mass") < line.npos) {
59 edm::LogVerbatim(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Retrieving mass table.";
62 if (line.find(
"DECAY") < line.npos) {
66 std::stringstream lineStream(line);
67 lineStream >> tmpString >> pdgId >> width;
70 <<
"CustomParticleFactory: entry to G4DecayTable: pdgID, width " << pdgId <<
", " << width;
71 G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgId);
72 if (
nullptr == aParticle || width == 0.0) {
76 aParticle->SetDecayTable(aDecayTable);
77 aParticle->SetPDGStable(
false);
78 aParticle->SetPDGLifeTime(1.0 / (width * CLHEP::GeV) * 6.582122
e-22 * CLHEP::MeV *
CLHEP::s);
79 G4ParticleDefinition *aAntiParticle = theParticleTable->FindAntiParticle(pdgId);
80 if (
nullptr != aAntiParticle && aAntiParticle->GetPDGEncoding() != pdgId) {
82 aAntiParticle->SetPDGStable(
false);
83 aAntiParticle->SetPDGLifeTime(1.0 / (width * CLHEP::GeV) * 6.582122
e-22 * CLHEP::MeV * CLHEP::s);
87 #ifdef G4MULTITHREADED
88 G4MUTEXUNLOCK(&customParticleFactoryMutex);
95 <<
"Pdg code too low " << pdgCode <<
" " <<
std::abs(pdgCode) / 1000000;
108 G4String pType =
"custom";
109 G4String pSubType =
"";
110 G4double spectatormass = 0.0;
111 G4ParticleDefinition *spectator =
nullptr;
126 double massGeV = mass * CLHEP::GeV;
129 if (name.compare(0, 4,
"~HIP") == 0) {
130 if ((name.compare(0, 7,
"~HIPbar") == 0)) {
132 charge = CLHEP::eplus * atoi(str.c_str()) / 3.;
135 charge = -CLHEP::eplus * atoi(str.c_str()) / 3.;
138 if (name.compare(0, 9,
"anti_~HIP") == 0) {
139 if ((name.compare(0, 12,
"anti_~HIPbar") == 0)) {
141 charge = -CLHEP::eplus * atoi(str.c_str()) / 3.;
144 charge = CLHEP::eplus * atoi(str.c_str()) / 3.;
156 double lifetime = -1;
172 G4DecayTable *decaytable =
nullptr;
173 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
193 if (pType ==
"rhadron" && name !=
"~g") {
194 G4String cloudname = name +
"cloud";
195 G4String cloudtype = pType +
"cloud";
196 spectator = theParticleTable->FindParticle(1000021);
197 spectatormass = spectator->GetPDGMass();
198 G4double cloudmass = massGeV - spectatormass;
200 new CustomParticle(cloudname, cloudmass, 0.0, 0, 0, +1, 0, 0, 0, 0, cloudtype, 0, +1, 0,
true, -1.0,
nullptr);
205 <<
"CustomParticleFactory: " << name <<
" being assigned spectator" << spectator->GetParticleName()
206 <<
" and cloud " << cloudname <<
"\n"
207 <<
" Masses: " << mass <<
" Gev, " << spectatormass / CLHEP::GeV <<
" GeV and "
208 << cloudmass / CLHEP::GeV <<
" GeV.";
209 }
else if (pType ==
"mesonino" || pType ==
"sbaryon") {
214 G4String cloudname = name +
"cloud";
215 G4String cloudtype = pType +
"cloud";
217 spectator = theParticleTable->FindParticle(1000006 * sign);
220 spectator = theParticleTable->FindParticle(1000005 * sign);
223 edm::LogError(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Cannot find spectator parton";
226 if (
nullptr != spectator) {
227 spectatormass = spectator->GetPDGMass();
229 G4double cloudmass = massGeV - spectatormass;
231 new CustomParticle(cloudname, cloudmass, 0.0, 0, 0, +1, 0, 0, 0, 0, cloudtype, 0, +1, 0,
true, -1.0,
nullptr);
235 if (
nullptr != spectator)
237 <<
"CustomParticleFactory: " << name <<
" being assigned spectator" << spectator->GetParticleName()
238 <<
" and cloud " << cloudname <<
"\n"
239 <<
" Masses: " << mass <<
" Gev, " << spectatormass / CLHEP::GeV <<
" GeV and "
240 << cloudmass / CLHEP::GeV <<
" GeV.";
253 G4ParticleTable *theParticleTable = G4ParticleTable::GetParticleTable();
256 while (getline(*configFile, line)) {
257 line.erase(0, line.find_first_not_of(
" \t"));
258 if (line.length() == 0 || line.at(0) ==
'#')
260 if (
ToLower(line).find(
"block") < line.npos) {
261 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Finished the Mass Table ";
264 std::stringstream sstr(line);
265 sstr >> pdgId >> mass >> tmp >>
name;
268 if (theParticleTable->FindParticle(pdgId)) {
273 <<
"CustomParticleFactory: Calling addCustomParticle for pdgId: " << pdgId <<
", mass " << mass <<
" GeV "
280 int pdgIdPartner = pdgId % 100;
281 G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgIdPartner);
283 if (
nullptr != aParticle) {
285 <<
"CustomParticleFactory: Found partner particle for "
286 <<
" pdgId= " << pdgId <<
", pdgIdPartner= " << pdgIdPartner <<
" " << aParticle->GetParticleName();
290 !CustomPDGParser::s_isSIMP(pdgId) && pdgId != 1000006 && pdgId != -1000006 && pdgId != 25 && pdgId != 35 &&
291 pdgId != 36 && pdgId != 37) {
292 int sign = aParticle->GetAntiPDGEncoding() / pdgIdPartner;
294 <<
"CustomParticleFactory: For " << aParticle->GetParticleName() <<
" pdg= " << pdgIdPartner
295 <<
", GetAntiPDGEncoding() " << aParticle->GetAntiPDGEncoding() <<
" sign= " <<
sign;
299 <<
"CustomParticleFactory: sign= " << sign <<
" a: " << aParticle->GetAntiPDGEncoding()
300 <<
" b: " << pdgIdPartner;
301 aParticle->DumpTable();
303 if (sign == -1 && pdgId != 25 && pdgId != 35 && pdgId != 36 && pdgId != 37 && pdgId != 1000039) {
304 tmp =
"anti_" +
name;
305 if (
nullptr != 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);
318 if (pdgId == 1000024 || pdgId == 1000037 || pdgId == 37) {
319 tmp =
"anti_" +
name;
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::LogVerbatim(
"CustomPhysics") <<
"Calling addCustomParticle for antiparticle with pdgId: " << -pdgId
331 <<
", mass " << mass <<
", name " <<
tmp;
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)
353 if (line.at(0) ==
'#' &&
ToLower(line).find(
"br") < line.npos &&
ToLower(line).find(
"nda") < line.npos)
355 if (line.at(0) ==
'#' ||
ToLower(line).find(
"block") < line.npos) {
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!";
385 name[
i] = part->GetParticleName();
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] <<
" "
394 << name[1] <<
" " << name[2] <<
" " << name[3];
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 G4ParticleDefinition *
part = theParticleTable->FindParticle(
id);
412 if (
nullptr == part) {
414 <<
"CustomParticleFactory: antiparticle with PDG code" <<
id <<
" not found!";
417 name[
j] = part->GetParticleName();
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);
Log< level::Info, true > LogVerbatim
static bool s_isDphoton(int pdg)
static double s_charge(int pdg)
static bool s_isSbaryon(int pdg)
string filePath
DQM Environment
static bool s_isgluinoHadron(int pdg)
void SetCloud(G4ParticleDefinition *theCloud)
Log< level::Error, false > LogError
void loadCustomParticles(const std::string &filePath)
static std::vector< G4ParticleDefinition * > m_particles
static bool s_isMesonino(int pdg)
static bool s_isSIMP(int pdg)
static bool s_isSLepton(int pdg)
Abs< T >::type abs(const T &t)
std::string ToLower(std::string str)
void SetSpectator(G4ParticleDefinition *theSpectator)
static double s_spin(int pdg)
static CMSAntiSIMP * Definition(double mass)
Log< level::Info, false > LogInfo
void getMassTable(std::ifstream *configFile)
G4DecayTable * getDecayTable(std::ifstream *configFile, int pdgId)
void addCustomParticle(int pdgCode, double mass, const std::string &name)
G4DecayTable * getAntiDecayTable(int pdgId, G4DecayTable *theDecayTable)
const std::vector< G4ParticleDefinition * > & getCustomParticles()
static bool s_issbottomHadron(int pdg)
static bool s_isstopHadron(int pdg)
Log< level::Warning, false > LogWarning
static CMSSIMP * Definition(double mass)