ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ParticleDefinition.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4ParticleDefinition.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 //
28 //
29 // --------------------------------------------------------------
30 // GEANT 4 class implementation file
31 //
32 // History: first implementation, based on object model of
33 // 2nd December 1995, G.Cosmo
34 // ---------------- G4ParticleDefinition -----------------
35 // first implementation by Makoto Asai, 29 January 1996
36 // revised by G.Cosmo, 29 February 1996
37 // revised by H.Kurashige, 19 April 1996
38 // Code uses operators (+=, *=, ++, -> etc.) correctly, P. Urban, 26/6/96
39 // revised by H.Kurashige, 4 July 1996
40 // revised by H.Kurashige, 16 Feb 1997
41 // revised by H.Kurashige, 10 Nov 1997
42 // remove new/delete G4ProcessManager by H.Kurashige 06 June 1998
43 // added Resonance flag and ApplyCuts flag H.Kurashige 27 June 1998
44 // modify FillQuarkContents() for quarks/diquarks H.Kurashige 30 June 1998
45 // modify encoding rule H.Kurashige 23 Oct. 98
46 // modify FillQuarkContents() for deltas 25 Nov.,98 H.Kurashige
47 //
48 // modify FillQuarkContents() to use G4PDGCodeChecker 17 Aug. 99 H.Kurashige
49 // modified for thread-safety for MT - G.Cosmo, A.Dotti - January 2013
50 // added support for MuonicAtom - K.L.Genser - June 2017
51 // --------------------------------------------------------------
52 
53 
54 #include "G4ParticleDefinition.hh"
55 #include "G4PhysicalConstants.hh"
56 #include "G4SystemOfUnits.hh"
57 #include "G4ParticleTable.hh"
58 #include "G4IonTable.hh"
59 #include "G4DecayTable.hh"
60 #include "G4PDGCodeChecker.hh"
61 #include "G4StateManager.hh"
62 #include "G4UnitsTable.hh"
63 
64 // This new field helps to use the class G4PDefManager.
65 //
67 
68 // This macro changes the references to fields that are now encapsulated
69 // in the class G4PDefData.
70 //
71 #define G4MT_pmanager ((subInstanceManager.offset()[g4particleDefinitionInstanceID]).theProcessManager)
72 
74  const G4String& aName,
75  G4double mass,
76  G4double width,
78  G4int iSpin,
79  G4int iParity,
80  G4int iConjugation,
81  G4int iIsospin,
82  G4int iIsospin3,
83  G4int gParity,
84  const G4String& pType,
85  G4int lepton,
86  G4int baryon,
88  G4bool stable,
89  G4double lifetime,
90  G4DecayTable *decaytable,
91  G4bool shortlived,
92  const G4String& subType,
93  G4int anti_encoding,
94  G4double magneticMoment)
95 
96  : theParticleName(aName),
97  thePDGMass(mass),
98  thePDGWidth(width),
99  thePDGCharge(charge),
100  thePDGiSpin(iSpin),
101  thePDGSpin(iSpin*0.5),
102  thePDGiParity(iParity),
103  thePDGiConjugation(iConjugation),
104  thePDGiGParity(gParity),
105  thePDGiIsospin(iIsospin),
106  thePDGiIsospin3(iIsospin3),
107  thePDGIsospin(iIsospin*0.5),
108  thePDGIsospin3(iIsospin3*0.5),
109  thePDGMagneticMoment(magneticMoment),
110  theLeptonNumber(lepton),
111  theBaryonNumber(baryon),
112  theParticleType(pType),
113  theParticleSubType(subType),
114  thePDGEncoding(encoding),
115  theAntiPDGEncoding(-1*encoding),
116  fShortLivedFlag(shortlived),
117  thePDGStable(stable),
118  thePDGLifeTime(lifetime),
119  theDecayTable(decaytable),
120  theAtomicNumber(0),
121  theAtomicMass(0),
122  verboseLevel(1),
123  fApplyCutsFlag(false),
124  isGeneralIon(false),
125  isMuonicAtom(false)
126 {
127  static const G4String nucleus("nucleus");
128  static const G4String muAtom("MuonicAtom");
129 
132 
134 
135  //set verboseLevel equal to ParticleTable
137 
138  if (anti_encoding !=0) theAntiPDGEncoding = anti_encoding;
139 
140  // check quark contents
141  if (this->FillQuarkContents() != thePDGEncoding) {
142 #ifdef G4VERBOSE
143  if (verboseLevel>0) {
144  // Using G4cout expecting that it is available in construction of static objects
145  G4cout << "Particle " << aName << " has a strange PDGEncoding " <<G4endl;
146  }
147 #endif
148  G4Exception( "G4ParticleDefintion::G4ParticleDefintion",
149  "PART102", JustWarning,
150  "Strange PDGEncoding ");
151  }
152 
153  // check initialization is in Pre_Init state except for ions
155 
156  if ( !fShortLivedFlag && (theParticleType!=nucleus) && (theParticleType!=muAtom) && (currentState!=G4State_PreInit)){
157 #ifdef G4VERBOSE
158  if (GetVerboseLevel()>0) {
159  G4cout << "G4ParticleDefintion (other than ions and shortlived) should be created in Pre_Init state "
160  << aName << G4endl;
161  }
162 #endif
163  G4Exception( "G4ParticleDefintion::G4ParticleDefintion",
164  "PART101", JustWarning,
165  "G4ParticleDefinition should be created in PreInit state");
166  }
167 
168 
169  if (theParticleTable->GetIonTable()->IsIon(this)) {
172  }
173 
174  if (theParticleTable->GetIonTable()->IsAntiIon(this)) {
177  }
178 
179  // check name and register this particle into ParticleTable
180  theParticleTable->Insert(this);
181 
182 }
183 
185 {
186  G4Exception("G4ParticleDefinition::G4ParticleDefinition()",
187  "PART001", FatalException,
188  "Illegal call of copy Constructor for G4ParticleDefinition ");
189 }
190 
192 {
193  G4Exception("G4ParticleDefinition::G4ParticleDefinition()",
194  "PART001", FatalException,
195  "Illegal call of default Constructor for G4ParticleDefinition ");
196 }
197 
198 
200 {
201  if (G4ParticleTable::GetParticleTable()->GetReadiness()) {
203  G4ApplicationState currentState = pStateManager->GetCurrentState();
204  if (currentState != G4State_PreInit) {
205  G4String msg = "Request of deletion for ";
206  msg += GetParticleName();
207  msg += " has No effects because readyToUse is true.";
208  G4Exception("G4ParticleDefinition::~G4ParticleDefinition()",
209  "PART117", JustWarning, msg);
210  return ;
211  } else {
212 #ifdef G4VERBOSE
213  if (verboseLevel>0){
215  << " will be deleted " << G4endl;
216  }
217 #endif
218  }
219  }
220 
221  if (theDecayTable!= 0) delete theDecayTable;
222 }
223 
224 
226 {
227  if (this != &right) {
228  }
229  return *this;
230 }
231 
233 {
234  return (this->theParticleName == right.theParticleName);
235 }
236 
238 {
239  return (this->theParticleName != right.theParticleName);
240 }
241 
242 
244  // Returns the private data instance manager.
245 {
246  return subInstanceManager;
247 }
248 
249 
251  // Clears memory allocated by sub-instance manager
252 {
254 }
255 
256 
258 {
259  if(g4particleDefinitionInstanceID<0) return 0;
260  return G4MT_pmanager;
261 }
262 
264  // calculate quark and anti-quark contents
265  // return value is PDG encoding for this particle.
266  // It means error if the return value is differnt from
267  // this->thePDGEncoding.
268 {
269  G4int flavor;
270  for (flavor= 0; flavor<NumberOfQuarkFlavor; flavor++){
271  theQuarkContent[flavor] = 0;
272  theAntiQuarkContent[flavor] = 0;
273  }
274 
275  G4PDGCodeChecker checker;
276  checker.SetVerboseLevel(verboseLevel);
277 
279 
280  if ( temp != 0) {
281  for (flavor= 0; flavor<NumberOfQuarkFlavor; flavor++){
282  theQuarkContent[flavor] = checker.GetQuarkContent(flavor);
283  theAntiQuarkContent[flavor] = checker.GetAntiQuarkContent(flavor);
284  }
285  if ((theParticleType == "meson")||(theParticleType == "baryon")) {
286  // check charge
287  if (!checker.CheckCharge(thePDGCharge) ){
288  temp = 0;
289  G4Exception( "G4ParticleDefintion::G4ParticleDefintion",
290  "PART103", JustWarning,
291  "Inconsistent charge against PDG code ");
292 #ifdef G4VERBOSE
293  if (verboseLevel>0) {
294  G4cout << "G4ParticleDefinition::FillQuarkContents : "
295  << " illegal charge (" << thePDGCharge/eplus
296  << " PDG code=" << thePDGEncoding <<G4endl;
297  }
298 #endif
299  }
300  // check spin
301  if (checker.GetSpin() != thePDGiSpin) {
302  temp=0;
303  G4Exception( "G4ParticleDefintion::G4ParticleDefintion",
304  "PART104", JustWarning,
305  "Inconsistent spin against PDG code ");
306 #ifdef G4VERBOSE
307  if (verboseLevel>0) {
308  G4cout << "G4ParticleDefinition::FillQuarkContents : "
309  << " illegal SPIN (" << thePDGiSpin << "/2"
310  << " PDG code=" << thePDGEncoding <<G4endl;
311  }
312 #endif
313  }
314  }
315  }
316  return temp;
317 }
318 
319 //-- No longer needed to access to G4IonTable.
320 //-- Method GetIonLifeTime() itself is kept for compatibility
321 //-- but moved to icc file as an inlined method.
322 //G4double G4ParticleDefinition::GetIonLifeTime() const
323 //{
324 // if(!isGeneralIon) return thePDGLifeTime;
325 //
326 // G4IonTable* ionTable = G4IonTable::GetIonTable();
327 // return ionTable->GetLifeTime(this);
328 //}
329 
331 {
332  G4cout << G4endl;
333  G4cout << "--- G4ParticleDefinition ---" << G4endl;
334  G4cout << " Particle Name : " << theParticleName << G4endl;
335  G4cout << " PDG particle code : " << thePDGEncoding;
336  G4cout << " [PDG anti-particle code: " << this->GetAntiPDGEncoding() << "]"<< G4endl;
337  G4cout << " Mass [GeV/c2] : " << thePDGMass/GeV ;
338  G4cout << " Width : " << thePDGWidth/GeV << G4endl;
339  G4cout << " Lifetime [nsec] : " << thePDGLifeTime/ns << G4endl;
340  G4cout << " Charge [e]: " << thePDGCharge/eplus << G4endl;
341  G4cout << " Spin : " << thePDGiSpin << "/2" << G4endl;
342  G4cout << " Parity : " << thePDGiParity << G4endl;
343  G4cout << " Charge conjugation : " << thePDGiConjugation << G4endl;
344  G4cout << " Isospin : (I,Iz): (" << thePDGiIsospin <<"/2";
345  G4cout << " , " << thePDGiIsospin3 << "/2 ) " << G4endl;
346  G4cout << " GParity : " << thePDGiGParity << G4endl;
347  if (thePDGMagneticMoment != 0.0) {
348  G4cout << " MagneticMoment [MeV/T] : " << thePDGMagneticMoment/MeV*tesla << G4endl;
349  }
350  G4cout << " Quark contents (d,u,s,c,b,t) : " << theQuarkContent[0];
351  G4cout << ", " << theQuarkContent[1];
352  G4cout << ", " << theQuarkContent[2];
353  G4cout << ", " << theQuarkContent[3];
354  G4cout << ", " << theQuarkContent[4];
355  G4cout << ", " << theQuarkContent[5] << G4endl;
356  G4cout << " AntiQuark contents : " << theAntiQuarkContent[0];
357  G4cout << ", " << theAntiQuarkContent[1];
358  G4cout << ", " << theAntiQuarkContent[2];
359  G4cout << ", " << theAntiQuarkContent[3];
360  G4cout << ", " << theAntiQuarkContent[4];
361  G4cout << ", " << theAntiQuarkContent[5] << G4endl;
362  G4cout << " Lepton number : " << theLeptonNumber;
363  G4cout << " Baryon number : " << theBaryonNumber << G4endl;
364  G4cout << " Particle type : " << theParticleType ;
365  G4cout << " [" << theParticleSubType << "]" << G4endl;
366 
367  if ( (theParticleTable->GetIonTable()->IsIon(this))
368  || (theParticleTable->GetIonTable()->IsAntiIon(this)) ) {
369  G4cout << " Atomic Number : " << GetAtomicNumber();
370  G4cout << " Atomic Mass : " << GetAtomicMass() << G4endl;
371  }
372  if ( fShortLivedFlag ){
373  G4cout << " ShortLived : ON" << G4endl;
374  }
375 
376  if ( IsGeneralIon() ) {
377  G4double lftm = GetIonLifeTime();
378  if(lftm<-1000.)
379  { G4cout << " Stable : No data found -- unknown" << G4endl; }
380  else if(lftm<0.)
381  { G4cout << " Stable : stable" << G4endl; }
382  else
383  {
384  G4cout << " Stable : unstable -- lifetime = " << G4BestUnit(lftm,"Time")
385  << "\n Decay table should be consulted to G4RadioactiveDecayProcess."
386  << G4endl;
387  }
388  }
389  else
390  {
391  if ( thePDGStable ){
392  G4cout << " Stable : stable" << G4endl;
393  } else {
394  if( theDecayTable != 0 ){
396  } else {
397  G4cout << "Decay Table is not defined !!" <<G4endl;
398  }
399  }
400  }
401 }
402 
404 {
405  if(theParticleName=="gamma"
406  || theParticleName=="e-"
407  || theParticleName=="e+"
408  || theParticleName=="proton")
409  { fApplyCutsFlag = flg; }
410  else
411  {
412  G4cout
413  << "G4ParticleDefinition::SetApplyCutsFlag() for " << theParticleName
414  << G4endl;
415  G4cout
416  << "becomes obsolete. Production threshold is applied only for "
417  << "gamma, e- ,e+ and proton." << G4endl;
418  }
419 }
420 
422 {
423  G4Exception( "G4ParticleDefintion::G4ParticleDefintion",
424  "PART114", JustWarning,
425  "CalculateAnomaly() method will be removed in next release");
426 
427  // gives the anomaly of magnetic moment for spin 1/2 particles
428  if (thePDGiSpin==1) {
430  return 0.5*std::fabs(thePDGMagneticMoment/muB - 2.*thePDGCharge/CLHEP::eplus);
431  } else {
432  return 0.0;
433  }
434 }
435 
437 {
438  if(id<0)
439  {
441  G4MT_pmanager = nullptr;
442  }
443  else
444  {
445  if( isGeneralIon || isMuonicAtom )
447  else
448  {
450  ed << "ParticleDefinitionID should not be set for the particles <"
451  << theParticleName << ">.";
452  G4Exception( "G4ParticleDefintion::SetParticleDefinitionID","PART10114",
453  FatalException,ed);
454  }
455  }
456 }
457 
458 #include "G4Threading.hh"
459 
461 {
463  {
464  if(G4Threading::G4GetThreadId() >= 0)
465  {
467  ed << "ProcessManager is being set to " << theParticleName
468  << " without proper initialization of TLS pointer vector.\n"
469  << "This operation is thread-unsafe.";
470  G4Exception( "G4ParticleDefintion::SetProcessManager","PART10116",
471  JustWarning,ed);
472  }
474  }
475  G4MT_pmanager = aProcessManager;
476 }