CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CustomParticleFactory.cc
Go to the documentation of this file.
1 #include <fstream>
2 #include <iomanip>
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 #include <sstream>
7 #include <set>
8 #include <locale>
9 
13 
17 
18 #include <G4ParticleTable.hh>
19 #include "G4DecayTable.hh"
20 #include <G4PhaseSpaceDecayChannel.hh>
21 #include "G4ProcessManager.hh"
22 
23 using namespace CLHEP;
24 
26 std::set<G4ParticleDefinition *> CustomParticleFactory::m_particles;
27 
28 bool CustomParticleFactory::isCustomParticle(G4ParticleDefinition *particle)
29 {
30  return (m_particles.find(particle)!=m_particles.end());
31 }
32 
34  if(loaded) return;
35  loaded = true;
36 
37  std::ifstream configFile(filePath.c_str());
38 
40  edm::LogInfo("CustomPhysics") << "Reading Custom Particle and G4DecayTable from " << filePath;
41  // This should be compatible IMO to SLHA
42  G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
43  while(getline(configFile,line)){
44  line.erase(0, line.find_first_not_of(" \t")); // Remove leading whitespace.
45  if (line.length()==0 || line.at(0) == '#') continue; // Skip blank lines and comments.
46  if (ToLower(line).find("block") < line.npos && // The mass table begins with a line containing "BLOCK MASS".
47  ToLower(line).find("mass") < line.npos) {
48  edm::LogInfo("CustomPhysics") << " Retrieving mass table.";
49  getMassTable(&configFile);
50  }
51  if(line.find("DECAY")<line.npos){
52  int pdgId;
53  double width;
54  std::string tmpString;
55  std::stringstream lineStream(line);
56  lineStream >> tmpString >> pdgId >> width; // assume SLHA format, e.g.: DECAY 1000021 5.50675438E+00 # gluino decays
57  edm::LogInfo("CustomPhysics") << "G4DecayTable: pdgID, width " << pdgId << ", " << width;
58  G4DecayTable* aDecayTable = getDecayTable(&configFile, pdgId);
59  G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgId);
60  G4ParticleDefinition *aAntiParticle = theParticleTable->FindAntiParticle(pdgId);
61  if (!aParticle) continue;
62  aParticle->SetDecayTable(aDecayTable);
63  aParticle->SetPDGStable(false);
64  aParticle->SetPDGLifeTime(1.0/(width*GeV)*6.582122e-22*MeV*s);
65  if(aAntiParticle && aAntiParticle->GetPDGEncoding()!=pdgId){
66  aAntiParticle->SetDecayTable(getAntiDecayTable(pdgId,aDecayTable));
67  aAntiParticle->SetPDGStable(false);
68  aAntiParticle->SetPDGLifeTime(1.0/(width*GeV)*6.582122e-22*MeV*s);
69  }
70  }
71  }
72 }
73 
74 
75 void CustomParticleFactory::addCustomParticle(int pdgCode, double mass, const std::string & name){
76 
77  if(abs(pdgCode)%100 <14 && abs(pdgCode) / 1000000 == 0){
78  edm::LogError("") << "Pdg code too low " << pdgCode << " "<<abs(pdgCode) / 1000000;
79  return;
80  }
81 
82 
84  G4String pType="custom";
85  G4String pSubType="";
86  G4double spectatormass;
87  G4ParticleDefinition* spectator;
89  if(CustomPDGParser::s_isRHadron(pdgCode)) pType = "rhadron";
90  if(CustomPDGParser::s_isSLepton(pdgCode)) pType = "sLepton";
91  if(CustomPDGParser::s_isMesonino(pdgCode)) pType = "mesonino";
92  if(CustomPDGParser::s_isSbaryon(pdgCode)) pType = "sbaryon";
93 
94  double massGeV =mass*GeV;
95  double width = 0.0*MeV;
96  double charge = eplus* CustomPDGParser::s_charge(pdgCode);
97  if (name.compare(0,4,"~HIP") == 0)
98  {
99 
100  if ((name.compare(0,7,"~HIPbar") == 0)) {std::string str = name.substr (7); charge=eplus*atoi(str.c_str())/3.;}
101  else {std::string str = name.substr (4); charge=eplus*atoi(str.c_str())*-1./3.; }
102  }
103  if (name.compare(0,9,"anti_~HIP") == 0)
104  {
105 
106  if ((name.compare(0,12,"anti_~HIPbar") == 0)) {std::string str = name.substr (12); charge=eplus*atoi(str.c_str())*-1./3.;}
107  else {std::string str = name.substr (9); charge=eplus*atoi(str.c_str())*1./3.; }
108  }
109  int spin = (int)CustomPDGParser::s_spin(pdgCode)-1;
110  int parity = +1;
111  int conjugation = 0;
112  int isospin = 0;
113  int isospinZ = 0;
114  int gParity = 0;
115  int lepton = 0; //FIXME:
116  int baryon = 1; //FIXME:
117  bool stable = true;
118  double lifetime = -1;
119 
120  if(CustomPDGParser::s_isDphoton(pdgCode)){
121  pType = "darkpho";
122  spin = 2;
123  parity = -1;
124  conjugation = -1;
125  isospin = 0;
126  isospinZ = 0;
127  gParity = 0;
128  lepton = 0;
129  baryon =0;
130  stable = true;
131  lifetime = -1;
132  }
133 
134  G4DecayTable *decaytable = NULL;
135  G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
136 
137  CustomParticle *particle = new CustomParticle(name, massGeV, width, charge, spin,
138  parity, conjugation, isospin, isospinZ,
139  gParity, pType, lepton, baryon, pdgCode,
140  stable, lifetime, decaytable);
141 
142  if(pType == "rhadron" && name!="~g"){
143  G4String cloudname = name+"cloud";
144  G4String cloudtype = pType+"cloud";
145  spectator = theParticleTable->FindParticle(1000021);
146  spectatormass = spectator->GetPDGMass();
147  G4double cloudmass = mass-spectatormass/GeV;
148  CustomParticle *tmpParticle = new CustomParticle(
149  cloudname, cloudmass * GeV , 0.0*MeV, 0 ,
150  0, +1, 0,
151  0, 0, 0,
152  cloudtype, 0, +1, 0,
153  true, -1.0, NULL );
154  particle->SetCloud(tmpParticle);
155  particle->SetSpectator(spectator);
156 
157  edm::LogInfo("CustomPhysics")<<name<<" being assigned "
158  <<particle->GetCloud()->GetParticleName()
159  <<" and "<<particle->GetSpectator()->GetParticleName();
160  edm::LogInfo("CustomPhysics")<<"Masses: "
161  <<particle->GetPDGMass()/GeV<<" Gev, "
162  <<particle->GetCloud()->GetPDGMass()/GeV<<" GeV and "
163  <<particle->GetSpectator()->GetPDGMass()/GeV<<" GeV.";
164  } else if(pType == "mesonino" || pType == "sbaryon") {
165  int sign=1;
166  if(pdgCode < 0 ) sign=-1;
167 
168  G4String cloudname = name+"cloud";
169  G4String cloudtype = pType+"cloud";
170  if(CustomPDGParser::s_isstopHadron(pdgCode)) {
171  spectator = theParticleTable->FindParticle(1000006*sign);
172  }
173  else {
174  if (CustomPDGParser::s_issbottomHadron(pdgCode)) {
175  spectator = theParticleTable->FindParticle(1000005*sign);
176  } else {
177  spectator = 0;
178  edm::LogError("CustomPhysics")<< " Cannot find spectator parton";
179  }
180  }
181  spectatormass = spectator->GetPDGMass();
182  G4double cloudmass = mass-spectatormass/GeV;
183  CustomParticle *tmpParticle = new CustomParticle(
184  cloudname, cloudmass * GeV , 0.0*MeV, 0 ,
185  0, +1, 0,
186  0, 0, 0,
187  cloudtype, 0, +1, 0,
188  true, -1.0, NULL );
189  particle->SetCloud(tmpParticle);
190  particle->SetSpectator(spectator);
191 
192  edm::LogInfo("CustomPhysics")<<name<<" being assigned "
193  <<particle->GetCloud()->GetParticleName()
194  <<" and "<<particle->GetSpectator()->GetParticleName();
195  edm::LogInfo("CustomPhysics")<<"Masses: "
196  <<particle->GetPDGMass()/GeV<<" Gev, "
197  <<particle->GetCloud()->GetPDGMass()/GeV<<" GeV and "
198  <<particle->GetSpectator()->GetPDGMass()/GeV<<" GeV.";
199  }
200  else{
201  particle->SetCloud(0);
202  particle->SetSpectator(0);
203  }
204  m_particles.insert(particle);
205 }
206 
208 
209  int pdgId;
210  double mass;
213  // This should be compatible IMO to SLHA
214  while (getline(*configFile,line)) {
215  line.erase(0, line.find_first_not_of(" \t")); // remove leading whitespace
216  if (line.length()==0 || line.at(0) == '#') continue; // skip blank lines and comments
217  if (ToLower(line).find("block") < line.npos) {
218  edm::LogInfo("CustomPhysics") << " Finished the Mass Table ";
219  break;
220  }
221  std::stringstream sstr(line);
222  sstr >> pdgId >> mass >> tmp >> name; // Assume SLHA format, e.g.: 1000001 5.68441109E+02 # ~d_L
223 
224  edm::LogInfo("CustomPhysics") << "Calling addCustomParticle for pdgId: " << pdgId
225  << ", mass " << mass << ", name " << name;
226  addCustomParticle(pdgId, fabs(mass), name);
228  int pdgIdPartner = pdgId%100;
229  G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
230  G4ParticleDefinition *aParticle = theParticleTable->FindParticle(pdgIdPartner);
231  //Add antiparticles for SUSY particles only, not for rHadrons.
232  edm::LogInfo("CustomPhysics") << "Found aParticle = " << aParticle
233  << ", pdgId = " << pdgId
234  << ", pdgIdPartner = " << pdgIdPartner
235  << ", CustomPDGParser::s_isRHadron(pdgId) = " << CustomPDGParser::s_isRHadron(pdgId)
236  << ", CustomPDGParser::s_isstopHadron(pdgId) = " << CustomPDGParser::s_isstopHadron(pdgId);
237 
238  if (aParticle &&
239  !CustomPDGParser::s_isRHadron(pdgId) &&
240  !CustomPDGParser::s_isstopHadron(pdgId) &&
241  pdgId!=1000006 &&
242  pdgId!=-1000006 &&
243  pdgId!=25 &&
244  pdgId!=35 &&
245  pdgId!=36 &&
246  pdgId!=37){
247  int sign = aParticle->GetAntiPDGEncoding()/pdgIdPartner;
248  edm::LogInfo("CustomPhysics") << "Found sign = " << sign
249  << ", aParticle->GetAntiPDGEncoding() " << aParticle->GetAntiPDGEncoding()
250  << ", pdgIdPartner = " << pdgIdPartner;
251  if(abs(sign)!=1) {
252  edm::LogInfo("CustomPhysics")<<"sgn: "<<sign<<" a "
253  <<aParticle->GetAntiPDGEncoding()
254  <<" b "<<pdgIdPartner;
255  aParticle->DumpTable();
256  }
257  if(sign==-1 && pdgId!=25 && pdgId!=35 && pdgId!=36 && pdgId!=37 && pdgId!=1000039){
258  tmp = "anti_"+name;
259  edm::LogInfo("CustomPhysics") << "Calling addCustomParticle for antiparticle with pdgId: " << -pdgId
260  << ", mass " << mass << ", name " << tmp;
261  addCustomParticle(-pdgId, mass, tmp);
262  theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
263  }
264  else theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId);
265  }
266 
267  if(pdgId==1000039) theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(pdgId); // gravitino
268  if(pdgId==1000024 || pdgId==1000037 || pdgId==37) {
269  tmp = "anti_"+name;
270  edm::LogInfo("CustomPhysics") << "Calling addCustomParticle for antiparticle (2) with pdgId: " << -pdgId
271  << ", mass " << mass << ", name " << tmp;
272  addCustomParticle(-pdgId, mass, tmp);
273  theParticleTable->FindParticle(pdgId)->SetAntiPDGEncoding(-pdgId);
274  }
275 
276  }
277 }
278 
279 G4DecayTable* CustomParticleFactory::getDecayTable(std::ifstream *configFile, int pdgId) {
280 
281  double br;
282  int nDaughters;
283  std::vector<int> pdg(4);
285  std::vector<std::string> name(4);
286 
287  G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
288 
289  std::string parentName = theParticleTable->FindParticle(pdgId)->GetParticleName();
290  G4DecayTable *decaytable= new G4DecayTable();
291 
292  while(getline(*configFile,line)) {
293 
294  line.erase(0, line.find_first_not_of(" \t")); // remove leading whitespace
295  if (line.length()==0) continue; // skip blank lines
296  if (line.at(0) == '#' &&
297  ToLower(line).find("br") < line.npos &&
298  ToLower(line).find("nda") < line.npos) continue; // skip a comment of the form: # BR NDA ID1 ID2
299  if (line.at(0) == '#') { // other comments signal the end of the decay block
300  edm::LogInfo("CustomPhysics") << " Finished the Decay Table ";
301  break;
302  }
303 
304  pdg.clear();
305  name.clear();
306 
307  std::stringstream sstr(line);
308  sstr >> br >> nDaughters; // assume SLHA format, e.g.: 1.49435135E-01 2 -15 16 # BR(H+ -> tau+ nu_tau)
309  edm::LogInfo("CustomPhysics") << " Branching Ratio: " << br << ", Number of Daughters: " << nDaughters;
310  if (nDaughters > 4) {
311  edm::LogError("CustomPhysics") << "Number of daughters is too large (max = 4): " << nDaughters << " for pdgId: " << pdgId;
312  break;
313  }
314  for(int i=0; i<nDaughters; i++) {
315  sstr >> pdg[i];
316  edm::LogInfo("CustomPhysics") << " Daughter ID " << pdg[i];
317  }
318  for (int i=0;i<nDaughters;i++) {
319  if (!theParticleTable->FindParticle(pdg[i])) {
320  edm::LogWarning("CustomPhysics")<<pdg[i]<<" CustomParticleFactory::getDecayTable(): not found in the table!";
321  continue;
322  }
323  name[i] = theParticleTable->FindParticle(pdg[i])->GetParticleName();
324  }
326  G4PhaseSpaceDecayChannel *aDecayChannel = new G4PhaseSpaceDecayChannel(parentName, br, nDaughters,
327  name[0],name[1],name[2],name[3]);
328  decaytable->Insert(aDecayChannel);
329 
330  }
331 
332  return decaytable;
333 }
334 
335 G4DecayTable* CustomParticleFactory::getAntiDecayTable(int pdgId, G4DecayTable *theDecayTable) {
336 
337  std::vector<std::string> name(4);
338  G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
339 
340  std::string parentName = theParticleTable->FindParticle(-pdgId)->GetParticleName();
341  G4DecayTable *decaytable= new G4DecayTable();
342 
343  for(int i=0;i<theDecayTable->entries();i++){
344  //G4PhaseSpaceDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(i);
345  G4VDecayChannel *theDecayChannel = theDecayTable->GetDecayChannel(i);
346  for(int j=0;j<theDecayChannel->GetNumberOfDaughters();j++){
347  int id = theDecayChannel->GetDaughter(j)->GetAntiPDGEncoding();
348  std::string nameTmp = theParticleTable->FindParticle(id)->GetParticleName();
349  name[j] = nameTmp;
350  }
351  G4PhaseSpaceDecayChannel *aDecayChannel =
352  new G4PhaseSpaceDecayChannel(parentName,
353  theDecayChannel->GetBR(),
354  theDecayChannel->GetNumberOfDaughters(),
355  name[0],name[1],name[2],name[3]);
356  decaytable->Insert(aDecayChannel);
357  }
358  return decaytable;
359 }
360 
361 
363  std::locale loc;
364  for (std::string::size_type i=0; i<str.length(); ++i)
365  str.at(i) = std::tolower(str.at(i),loc);
366  return str;
367 }
368 
int i
Definition: DBlmapReader.cc:9
const double GeV
Definition: MathUtil.h:16
static bool s_isDphoton(int pdg)
static std::set< G4ParticleDefinition * > m_particles
static double s_charge(int pdg)
static const int stable
Definition: TopGenEvent.h:11
static bool s_isSbaryon(int pdg)
void SetCloud(G4ParticleDefinition *theCloud)
G4ParticleDefinition * GetCloud()
#define NULL
Definition: scimark2.h:8
uint16_t size_type
double charge(const std::vector< uint8_t > &Ampls)
static void loadCustomParticles(const std::string &filePath)
const double MeV
static bool s_isMesonino(int pdg)
static bool s_isSLepton(int pdg)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
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
Definition: MVATrainer.cc:100
static bool s_issbottomHadron(int pdg)
static bool isCustomParticle(G4ParticleDefinition *particle)
static bool s_isstopHadron(int pdg)
float spin(float ph)