8 #include "G4ParticleTable.hh" 9 #include "G4DecayTable.hh" 10 #include "G4PhaseSpaceDecayChannel.hh" 11 #include "G4ProcessManager.hh" 12 #include "G4ParticleDefinition.hh" 13 #include "G4SystemOfUnits.hh" 22 #ifdef G4MULTITHREADED 23 G4Mutex CustomParticleFactory::customParticleFactoryMutex = G4MUTEX_INITIALIZER;
35 #ifdef G4MULTITHREADED 36 G4MUTEXLOCK(&customParticleFactoryMutex);
42 std::ifstream configFile(filePath.c_str());
46 <<
"CustomParticleFactory: Reading Custom Particle and G4DecayTable from \n" 49 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
50 while(getline(configFile, line)){
51 line.erase(0, line.find_first_not_of(
" \t"));
52 if (line.length()==0 || line.at(0) ==
'#') {
continue; }
54 if (
ToLower(line).find(
"block") < line.npos &&
55 ToLower(line).find(
"mass") < line.npos) {
56 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Retrieving mass table.";
59 if(line.find(
"DECAY")<line.npos) {
63 std::stringstream lineStream(line);
64 lineStream >> tmpString >> pdgId >>
width;
67 <<
"CustomParticleFactory: entry to G4DecayTable: pdgID, width " 68 << pdgId <<
", " <<
width;
69 G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgId);
70 if (!aParticle || width == 0.0) {
continue; }
71 G4DecayTable* aDecayTable =
getDecayTable(&configFile, pdgId);
72 aParticle->SetDecayTable(aDecayTable);
73 aParticle->SetPDGStable(
false);
75 G4ParticleDefinition *aAntiParticle = theParticleTable->FindAntiParticle(pdgId);
76 if(aAntiParticle && aAntiParticle->GetPDGEncoding() !=
pdgId){
78 aAntiParticle->SetPDGStable(
false);
79 aAntiParticle->SetPDGLifeTime(1.0/(width*CLHEP::GeV)*6.582122
e-22*
CLHEP::MeV*CLHEP::s);
83 #ifdef G4MULTITHREADED 84 G4MUTEXUNLOCK(&customParticleFactoryMutex);
93 <<
"Pdg code too low " << pdgCode <<
" "<<
std::abs(pdgCode)/1000000;
98 G4String pType=
"custom";
100 G4double spectatormass = 0.0;
101 G4ParticleDefinition* spectator =
nullptr;
111 if (name.compare(0,4,
"~HIP") == 0)
113 if ((name.compare(0,7,
"~HIPbar") == 0)) {
115 charge=CLHEP::eplus*atoi(str.c_str())/3.;
118 charge=-CLHEP::eplus*atoi(str.c_str())/3.;
121 if (name.compare(0,9,
"anti_~HIP") == 0)
123 if ((name.compare(0,12,
"anti_~HIPbar") == 0)) {
125 charge=-CLHEP::eplus*atoi(str.c_str())/3.;
128 charge=CLHEP::eplus*atoi(str.c_str())/3.;
140 double lifetime = -1;
156 G4DecayTable *decaytable =
nullptr;
157 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
160 parity, conjugation, isospin, isospinZ,
161 gParity, pType, lepton, baryon, pdgCode,
162 stable, lifetime, decaytable);
164 if(pType ==
"rhadron" && name!=
"~g"){
165 G4String cloudname = name+
"cloud";
166 G4String cloudtype = pType+
"cloud";
167 spectator = theParticleTable->FindParticle(1000021);
168 spectatormass = spectator->GetPDGMass();
169 G4double cloudmass = massGeV - spectatormass;
171 cloudname, cloudmass, 0.0, 0,
175 true, -1.0,
nullptr );
180 <<
"CustomParticleFactory: " <<name<<
" being assigned spectator" 181 << spectator->GetParticleName() <<
" and cloud " <<cloudname <<
"\n" 182 <<
" Masses: "<<mass<<
" Gev, " 183 <<spectatormass/CLHEP::GeV<<
" GeV and "<<cloudmass/CLHEP::GeV<<
" GeV.";
184 }
else if(pType ==
"mesonino" || pType ==
"sbaryon") {
186 if(pdgCode < 0 ) sign=-1;
188 G4String cloudname = name+
"cloud";
189 G4String cloudtype = pType+
"cloud";
191 spectator = theParticleTable->FindParticle(1000006*sign);
195 spectator = theParticleTable->FindParticle(1000005*sign);
198 edm::LogError(
"SimG4CoreCustomPhysics")<<
"CustomParticleFactory: Cannot find spectator parton";
201 if(spectator) { spectatormass = spectator->GetPDGMass(); }
202 G4double cloudmass = massGeV - spectatormass;
204 cloudname, cloudmass, 0.0, 0 ,
208 true, -1.0,
nullptr);
213 <<
"CustomParticleFactory: " <<name<<
" being assigned spectator" 214 << spectator->GetParticleName() <<
" and cloud " <<cloudname <<
"\n" 215 <<
" Masses: "<<mass<<
" Gev, " 216 <<spectatormass/CLHEP::GeV<<
" GeV and "<<cloudmass/CLHEP::GeV<<
" GeV.";
231 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
234 while (getline(*configFile,line)) {
235 line.erase(0, line.find_first_not_of(
" \t"));
236 if (line.length()==0 || line.at(0) ==
'#')
continue;
237 if (
ToLower(line).find(
"block") < line.npos) {
239 <<
"CustomParticleFactory: Finished the Mass Table ";
242 std::stringstream sstr(line);
243 sstr >> pdgId >> mass >> tmp >>
name;
246 if(theParticleTable->FindParticle(pdgId)) {
continue; }
249 <<
"CustomParticleFactory: Calling addCustomParticle for pdgId: " << pdgId
250 <<
", mass " << mass <<
" GeV " << name
256 int pdgIdPartner = pdgId%100;
257 G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgIdPartner);
261 <<
"CustomParticleFactory: Found partner particle for " <<
" pdgId= " << pdgId
262 <<
", pdgIdPartner= " << pdgIdPartner <<
" " << aParticle->GetParticleName();
267 !CustomPDGParser::s_isstopHadron(pdgId) &&
274 int sign = aParticle->GetAntiPDGEncoding()/pdgIdPartner;
276 <<
"CustomParticleFactory: For " << aParticle->GetParticleName()
277 <<
" pdg= " << pdgIdPartner
278 <<
", GetAntiPDGEncoding() " << aParticle->GetAntiPDGEncoding()
279 <<
" sign= " <<
sign;
283 <<
"CustomParticleFactory: sign= "<<sign<<
" a: " 284 <<aParticle->GetAntiPDGEncoding()<<
" b: "<<pdgIdPartner;
285 aParticle->DumpTable();
287 if(sign==-1 && pdgId!=25 && pdgId!=35 && pdgId!=36 && pdgId!=37 && pdgId!=1000039){
289 if(!theParticleTable->FindParticle(-pdgId)) {
291 <<
"CustomParticleFactory: Calling addCustomParticle for antiparticle with pdgId: " 292 << -pdgId <<
", mass " << mass <<
" GeV, name " <<
tmp;
294 theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
297 else theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);
300 if(pdgId==1000039) theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);
301 if(pdgId==1000024 || pdgId==1000037 || pdgId==37) {
303 if(!theParticleTable->FindParticle(-pdgId)) {
305 <<
"CustomParticleFactory: Calling addCustomParticle for antiparticle (2) with pdgId: " 306 << -pdgId <<
", mass " << mass <<
" GeV, name " <<
tmp;
308 theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
321 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
323 std::string parentName = theParticleTable->FindParticle(pdgId)->GetParticleName();
324 G4DecayTable *decaytable=
new G4DecayTable();
326 while(getline(*configFile,line)) {
328 line.erase(0, line.find_first_not_of(
" \t"));
329 if (line.length()==0)
continue;
330 if (line.at(0) ==
'#' &&
331 ToLower(line).find(
"br") < line.npos &&
332 ToLower(line).find(
"nda") < line.npos)
continue;
333 if (line.at(0) ==
'#' ||
ToLower(line).find(
"block") < line.npos) {
334 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Finished the Decay Table ";
338 std::stringstream sstr(line);
339 sstr >> br >> nDaughters;
341 <<
"CustomParticleFactory: Branching Ratio: " << br <<
", Number of Daughters: " << nDaughters;
342 if (nDaughters > 4) {
344 <<
"CustomParticleFactory: Number of daughters is too large (max = 4): " << nDaughters
345 <<
" for pdgId: " <<
pdgId;
350 <<
"CustomParticleFactory: Branching ratio is " << br
351 <<
" for pdgId: " <<
pdgId;
355 for(
int i=0;
i<nDaughters; ++
i) {
357 LogDebug(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: Daughter ID " << pdg[
i];
358 const G4ParticleDefinition*
part = theParticleTable->FindParticle(pdg[
i]);
361 <<
"CustomParticleFactory: particle with PDG code"<<pdg[
i] <<
" not found!";
364 name[
i] = part->GetParticleName();
367 G4PhaseSpaceDecayChannel *aDecayChannel =
new G4PhaseSpaceDecayChannel(parentName, br, nDaughters,
368 name[0],name[1],name[2],name[3]);
369 decaytable->Insert(aDecayChannel);
370 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: inserted decay channel " 371 <<
" for pdgID= " << pdgId <<
" " << parentName
372 <<
" BR= " << br <<
" Daughters: " << name[0]
373 <<
" " << name[1]<<
" " << name[2]<<
" " << name[3];
381 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
383 std::string parentName = theParticleTable->FindParticle(-pdgId)->GetParticleName();
384 G4DecayTable *decaytable=
new G4DecayTable();
386 for(
int i=0;
i<theDecayTable->entries(); ++
i){
387 G4VDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(
i);
388 int nd =
std::min(4, theDecayChannel->GetNumberOfDaughters());
389 for(
int j=0; j<nd; ++j){
390 int id = theDecayChannel->GetDaughter(j)->GetAntiPDGEncoding();
391 const G4ParticleDefinition*
part = theParticleTable->FindParticle(
id);
394 <<
"CustomParticleFactory: antiparticle with PDG code"<<
id <<
" not found!";
397 name[j] = part->GetParticleName();
399 G4PhaseSpaceDecayChannel *aDecayChannel =
400 new G4PhaseSpaceDecayChannel(parentName,
401 theDecayChannel->GetBR(), nd,
402 name[0],name[1],name[2],name[3]);
403 decaytable->Insert(aDecayChannel);
404 edm::LogInfo(
"SimG4CoreCustomPhysics") <<
"CustomParticleFactory: inserted decay channel " 405 <<
" for pdgID= " << -pdgId <<
" " << parentName
406 <<
" BR= " << theDecayChannel->GetBR()
407 <<
" Daughters: " << name[0]
408 <<
" " << name[1]<<
" " << name[2]<<
" " << name[3];
416 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)
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)
std::string ToLower(std::string str)
void SetSpectator(G4ParticleDefinition *theSpectator)
static double s_spin(int pdg)
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)
static bool s_isRHadron(int pdg)
std::vector< std::vector< double > > tmp
const std::vector< G4ParticleDefinition * > & GetCustomParticles()
static bool s_issbottomHadron(int pdg)
static bool s_isstopHadron(int pdg)