Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4ParticleDefinition.cc
Go to the documentation of this file.
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// G4ParticleDefinition class implementation
27//
28// Authors: G.Cosmo, 2 December 1995 - Design, based on object model
29// M.Asai, 29 January 1996 - First implementation
30// History:
31// - 1996-2003, H.Kurashige - Revisions
32// - 11.03.2003, H.Kurashige - Restructuring for Cuts per Region
33// - 25.01.2013, G.Cosmo, A.Dotti - Introduced thread-safety for MT
34// - 15.06.2017, K.L.Genser - Added support for MuonicAtom
35// --------------------------------------------------------------------
36
39#include "G4SystemOfUnits.hh"
40#include "G4ParticleTable.hh"
41#include "G4IonTable.hh"
42#include "G4DecayTable.hh"
43#include "G4PDGCodeChecker.hh"
44#include "G4StateManager.hh"
45#include "G4UnitsTable.hh"
46#include "G4Threading.hh"
47
48// This new field helps to use the class G4PDefManager.
49//
50G4PDefManager G4ParticleDefinition::subInstanceManager;
51
52// This macro changes the references to fields that are now encapsulated
53// in the class G4PDefData.
54//
55#define G4MT_pmanager ((subInstanceManager.offset()[g4particleDefinitionInstanceID]).theProcessManager)
56#define G4MT_tmanager ((subInstanceManager.offset()[g4particleDefinitionInstanceID]).theTrackingManager)
57
58// --------------------------------------------------------------------
60 const G4String& aName,
61 G4double mass,
62 G4double width,
63 G4double charge,
64 G4int iSpin,
65 G4int iParity,
66 G4int iConjugation,
67 G4int iIsospin,
68 G4int iIsospin3,
69 G4int gParity,
70 const G4String& pType,
71 G4int lepton,
72 G4int baryon,
74 G4bool stable,
75 G4double lifetime,
76 G4DecayTable* decaytable,
77 G4bool shortlived,
78 const G4String& subType,
79 G4int anti_encoding,
80 G4double magneticMoment)
81
82 : theParticleName(aName),
83 thePDGMass(mass),
84 thePDGWidth(width),
85 thePDGCharge(charge),
86 thePDGiSpin(iSpin),
87 thePDGSpin(iSpin*0.5),
88 thePDGiParity(iParity),
89 thePDGiConjugation(iConjugation),
90 thePDGiGParity(gParity),
91 thePDGiIsospin(iIsospin),
92 thePDGiIsospin3(iIsospin3),
93 thePDGIsospin(iIsospin*0.5),
94 thePDGIsospin3(iIsospin3*0.5),
95 thePDGMagneticMoment(magneticMoment),
96 theLeptonNumber(lepton),
97 theBaryonNumber(baryon),
98 theParticleType(pType),
99 theParticleSubType(subType),
100 thePDGEncoding(encoding),
101 theAntiPDGEncoding(-1*encoding),
102 fShortLivedFlag(shortlived),
103 thePDGStable(stable),
104 thePDGLifeTime(lifetime),
105 theDecayTable(decaytable)
106{
107 static const G4String nucleus("nucleus");
108 static const G4String muAtom("MuonicAtom");
109
110 g4particleDefinitionInstanceID = -1;
111 theProcessManagerShadow = 0;
112
113 theParticleTable = G4ParticleTable::GetParticleTable();
114
115 //set verboseLevel equal to ParticleTable
116 verboseLevel = theParticleTable->GetVerboseLevel();
117
118 if (anti_encoding !=0) theAntiPDGEncoding = anti_encoding;
119
120 // check quark contents
121 if (this->FillQuarkContents() != thePDGEncoding)
122 {
123#ifdef G4VERBOSE
124 if (verboseLevel>0)
125 {
126 // Using G4cout expecting that it is available
127 // in construction of static objects
128 G4cout << "Particle " << aName
129 << " has a strange PDGEncoding " << G4endl;
130 }
131#endif
132 G4Exception( "G4ParticleDefintion::G4ParticleDefintion",
133 "PART102", JustWarning,
134 "Strange PDGEncoding ");
135 }
136
137 // check initialization is in Pre_Init state except for ions
138 G4ApplicationState currentState
140
141 if ( !fShortLivedFlag && (theParticleType!=nucleus)
142 && (theParticleType!=muAtom) && (currentState!=G4State_PreInit))
143 {
144#ifdef G4VERBOSE
145 if (GetVerboseLevel()>0)
146 {
147 G4cout << "G4ParticleDefinition (other than ions and shortlived)"
148 << " should be created in Pre_Init state - "
149 << aName << G4endl;
150 }
151#endif
152 G4Exception("G4ParticleDefintion::G4ParticleDefinition()",
153 "PART101", JustWarning,
154 "G4ParticleDefinition should be created in PreInit state");
155 }
156
157
158 if (theParticleTable->GetIonTable()->IsIon(this))
159 {
162 }
163
164 if (theParticleTable->GetIonTable()->IsAntiIon(this))
165 {
166 SetAtomicNumber( std::abs(G4int(GetPDGCharge()/eplus)) );
167 SetAtomicMass( std::abs(GetBaryonNumber()) );
168 }
169
170 // check name and register this particle into ParticleTable
171 theParticleTable->Insert(this);
172}
173
174// --------------------------------------------------------------------
176{
177 G4Exception("G4ParticleDefinition::G4ParticleDefinition()",
178 "PART001", FatalException,
179 "Illegal call of default constructor for G4ParticleDefinition!");
180}
181
182// --------------------------------------------------------------------
184{
185 if (G4ParticleTable::GetParticleTable()->GetReadiness())
186 {
188 G4ApplicationState currentState = pStateManager->GetCurrentState();
189 if (currentState != G4State_PreInit)
190 {
191 G4String msg = "Request of deletion for ";
192 msg += GetParticleName();
193 msg += " has No effects because readyToUse is true.";
194 G4Exception("G4ParticleDefinition::~G4ParticleDefinition()",
195 "PART117", JustWarning, msg);
196 return ;
197 }
198 else
199 {
200#ifdef G4VERBOSE
201 if (verboseLevel>0)
202 {
203 G4cout << GetParticleName() << " will be deleted..." << G4endl;
204 }
205#endif
206 }
207 }
208 delete theDecayTable;
209}
210
211// --------------------------------------------------------------------
213{
214 return (this->theParticleName == right.theParticleName);
215}
216
217// --------------------------------------------------------------------
219{
220 return (this->theParticleName != right.theParticleName);
221}
222
223// --------------------------------------------------------------------
225{
226 // Returns the private data instance manager
227 return subInstanceManager;
228}
229
230// --------------------------------------------------------------------
232{
233 // Clears memory allocated by sub-instance manager
234 subInstanceManager.FreeSlave();
235}
236
237// --------------------------------------------------------------------
239{
240 if(g4particleDefinitionInstanceID<0) return nullptr;
241 return G4MT_pmanager;
242}
243
244// --------------------------------------------------------------------
246{
247 if(g4particleDefinitionInstanceID<0) return nullptr;
248 return G4MT_tmanager;
249}
250
251// --------------------------------------------------------------------
253{
254 // Calculate quark and anti-quark contents
255 // Returned value is the PDG encoding for this particle.
256 // It means error if the return value is different from
257 // this->thePDGEncoding
258
259 G4int flavor;
260 for (flavor= 0; flavor<NumberOfQuarkFlavor; ++flavor)
261 {
262 theQuarkContent[flavor] = 0;
263 theAntiQuarkContent[flavor] = 0;
264 }
265
266 G4PDGCodeChecker checker;
267 checker.SetVerboseLevel(verboseLevel);
268
269 G4int temp = checker.CheckPDGCode(thePDGEncoding, theParticleType);
270
271 if ( temp != 0)
272 {
273 for (flavor= 0; flavor<NumberOfQuarkFlavor; ++flavor)
274 {
275 theQuarkContent[flavor] = checker.GetQuarkContent(flavor);
276 theAntiQuarkContent[flavor] = checker.GetAntiQuarkContent(flavor);
277 }
278 if ((theParticleType == "meson")||(theParticleType == "baryon"))
279 {
280 // check charge
281 if ( !checker.CheckCharge(thePDGCharge) )
282 {
283 temp = 0;
284 G4Exception( "G4ParticleDefintion::G4ParticleDefintion",
285 "PART103", JustWarning,
286 "Inconsistent charge against PDG code ");
287#ifdef G4VERBOSE
288 if (verboseLevel>0)
289 {
290 G4cout << "G4ParticleDefinition::FillQuarkContents : "
291 << " illegal charge (" << thePDGCharge/eplus
292 << " PDG code=" << thePDGEncoding << G4endl;
293 }
294#endif
295 }
296 // check spin
297 if (checker.GetSpin() != thePDGiSpin)
298 {
299 temp = 0;
300 G4Exception( "G4ParticleDefintion::G4ParticleDefintion",
301 "PART104", JustWarning,
302 "Inconsistent spin against PDG code ");
303#ifdef G4VERBOSE
304 if (verboseLevel>0)
305 {
306 G4cout << "G4ParticleDefinition::FillQuarkContents : "
307 << " illegal SPIN (" << thePDGiSpin << "/2"
308 << " PDG code=" << thePDGEncoding <<G4endl;
309 }
310#endif
311 }
312 }
313 }
314 return temp;
315}
316
317// --------------------------------------------------------------------
319{
320 G4cout << G4endl;
321 G4cout << "--- G4ParticleDefinition ---" << G4endl;
322 G4cout << " Particle Name : " << theParticleName << G4endl;
323 G4cout << " PDG particle code : " << thePDGEncoding;
324 G4cout << " [PDG anti-particle code: " << this->GetAntiPDGEncoding() << "]"<< G4endl;
325 G4cout << " Mass [GeV/c2] : " << thePDGMass/GeV ;
326 G4cout << " Width : " << thePDGWidth/GeV << G4endl;
327 G4cout << " Lifetime [nsec] : " << thePDGLifeTime/ns << G4endl;
328 G4cout << " Charge [e]: " << thePDGCharge/eplus << G4endl;
329 G4cout << " Spin : " << thePDGiSpin << "/2" << G4endl;
330 G4cout << " Parity : " << thePDGiParity << G4endl;
331 G4cout << " Charge conjugation : " << thePDGiConjugation << G4endl;
332 G4cout << " Isospin : (I,Iz): (" << thePDGiIsospin <<"/2";
333 G4cout << " , " << thePDGiIsospin3 << "/2 ) " << G4endl;
334 G4cout << " GParity : " << thePDGiGParity << G4endl;
335 if (thePDGMagneticMoment != 0.0)
336 {
337 G4cout << " MagneticMoment [MeV/T] : "
338 << thePDGMagneticMoment/MeV*tesla << G4endl;
339 }
340 G4cout << " Quark contents (d,u,s,c,b,t) : " << theQuarkContent[0];
341 G4cout << ", " << theQuarkContent[1];
342 G4cout << ", " << theQuarkContent[2];
343 G4cout << ", " << theQuarkContent[3];
344 G4cout << ", " << theQuarkContent[4];
345 G4cout << ", " << theQuarkContent[5] << G4endl;
346 G4cout << " AntiQuark contents : " << theAntiQuarkContent[0];
347 G4cout << ", " << theAntiQuarkContent[1];
348 G4cout << ", " << theAntiQuarkContent[2];
349 G4cout << ", " << theAntiQuarkContent[3];
350 G4cout << ", " << theAntiQuarkContent[4];
351 G4cout << ", " << theAntiQuarkContent[5] << G4endl;
352 G4cout << " Lepton number : " << theLeptonNumber;
353 G4cout << " Baryon number : " << theBaryonNumber << G4endl;
354 G4cout << " Particle type : " << theParticleType ;
355 G4cout << " [" << theParticleSubType << "]" << G4endl;
356
357 if ( (theParticleTable->GetIonTable()->IsIon(this))
358 || (theParticleTable->GetIonTable()->IsAntiIon(this)) )
359 {
360 G4cout << " Atomic Number : " << GetAtomicNumber();
361 G4cout << " Atomic Mass : " << GetAtomicMass() << G4endl;
362 }
363 if ( fShortLivedFlag )
364 {
365 G4cout << " ShortLived : ON" << G4endl;
366 }
367
368 if ( IsGeneralIon() )
369 {
370 G4double lftm = GetIonLifeTime();
371 if(lftm<-1000.)
372 { G4cout << " Stable : No data found -- unknown" << G4endl; }
373 else if(lftm<0.)
374 { G4cout << " Stable : stable" << G4endl; }
375 else
376 {
377 G4cout << " Stable : unstable -- lifetime = " << G4BestUnit(lftm,"Time")
378 << "\n Decay table should be consulted to G4RadioactiveDecayProcess."
379 << G4endl;
380 }
381 }
382 else
383 {
384 if ( thePDGStable )
385 {
386 G4cout << " Stable : stable" << G4endl;
387 }
388 else
389 {
390 if( theDecayTable != nullptr )
391 {
392 theDecayTable->DumpInfo();
393 }
394 else
395 {
396 G4cout << "Decay Table is not defined !!" <<G4endl;
397 }
398 }
399 }
400}
401
402// --------------------------------------------------------------------
404{
405 if (theParticleName=="gamma"
406 || theParticleName=="e-"
407 || theParticleName=="e+"
408 || theParticleName=="proton")
409 {
410 fApplyCutsFlag = flg;
411 }
412 else
413 {
414 G4cout
415 << "G4ParticleDefinition::SetApplyCutsFlag() for " << theParticleName
416 << G4endl;
417 G4cout
418 << "becomes obsolete. Production threshold is applied only for "
419 << "gamma, e- ,e+ and proton." << G4endl;
420 }
421}
422
423// --------------------------------------------------------------------
425{
426 G4Exception("G4ParticleDefinition::G4ParticleDefinition",
427 "PART114", JustWarning,
428 "CalculateAnomaly() method will be removed in future releases");
429
430 // gives the anomaly of magnetic moment for spin 1/2 particles
431 if (thePDGiSpin==1)
432 {
433 G4double muB = 0.5*CLHEP::eplus*CLHEP::hbar_Planck
434 / (thePDGMass/CLHEP::c_squared);
435 return 0.5*std::fabs(thePDGMagneticMoment/muB
436 - 2.*thePDGCharge/CLHEP::eplus);
437 }
438 else
439 {
440 return 0.0;
441 }
442}
443
444// --------------------------------------------------------------------
446{
447 if(id<0)
448 {
449 g4particleDefinitionInstanceID = subInstanceManager.CreateSubInstance();
450 G4MT_pmanager = nullptr;
451 }
452 else
453 {
455 { g4particleDefinitionInstanceID = id; }
456 else
457 {
459 ed << "ParticleDefinitionID should not be set for the particles <"
460 << theParticleName << ">.";
461 G4Exception("G4ParticleDefintion::SetParticleDefinitionID",
462 "PART10114", FatalException, ed);
463 }
464 }
465}
466
467// --------------------------------------------------------------------
469{
470 if(g4particleDefinitionInstanceID<0 && !isGeneralIon)
471 {
473 {
475 ed << "ProcessManager is being set to " << theParticleName
476 << " without proper initialization of TLS pointer vector.\n"
477 << "This operation is thread-unsafe.";
478 G4Exception("G4ParticleDefintion::SetProcessManager",
479 "PART10116", JustWarning, ed);
480 }
482 }
483 G4MT_pmanager = aProcessManager;
484}
485
486// --------------------------------------------------------------------
488{
489 if(g4particleDefinitionInstanceID<0 && !isGeneralIon)
490 {
492 {
494 ed << "TrackingManager is being set to " << theParticleName
495 << " without proper initialization of TLS pointer vector.\n"
496 << "This operation is thread-unsafe.";
497 G4Exception("G4ParticleDefintion::SetTrackingManager",
498 "PART10118", JustWarning, ed);
499 }
501 }
502 G4MT_tmanager = aTrackingManager;
503}
G4ApplicationState
@ G4State_PreInit
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
#define G4MT_tmanager
#define G4MT_pmanager
#define G4BestUnit(a, b)
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
void DumpInfo() const
static G4bool IsIon(const G4ParticleDefinition *)
Definition: G4IonTable.cc:1302
static G4bool IsAntiIon(const G4ParticleDefinition *)
Definition: G4IonTable.cc:1328
G4int GetSpin() const
G4int CheckPDGCode(G4int code, const G4String &type)
G4int GetQuarkContent(G4int flavor) const
G4bool CheckCharge(G4double charge) const
G4int GetAntiQuarkContent(G4int flavor) const
void SetVerboseLevel(G4int verbose)
G4int CreateSubInstance()
G4ProcessManager * GetProcessManager() const
G4VTrackingManager * GetTrackingManager() const
G4int GetAtomicNumber() const
static const G4PDefManager & GetSubInstanceManager()
G4bool IsGeneralIon() const
G4int theAntiQuarkContent[NumberOfQuarkFlavor]
G4int GetVerboseLevel() const
void SetParticleDefinitionID(G4int id=-1)
void SetTrackingManager(G4VTrackingManager *aTrackingManager)
G4int GetAtomicMass() const
G4double GetPDGCharge() const
G4bool operator==(const G4ParticleDefinition &right) const
G4int theQuarkContent[NumberOfQuarkFlavor]
void SetAtomicMass(G4int)
G4double GetIonLifeTime() const
G4bool operator!=(const G4ParticleDefinition &right) const
G4double CalculateAnomaly() const
const G4String & GetParticleName() const
void SetProcessManager(G4ProcessManager *aProcessManager)
void SetAtomicNumber(G4int)
G4IonTable * GetIonTable() const
G4int GetVerboseLevel() const
static G4ParticleTable * GetParticleTable()
G4ParticleDefinition * Insert(G4ParticleDefinition *particle)
const G4ApplicationState & GetCurrentState() const
static G4StateManager * GetStateManager()
G4int G4GetThreadId()
Definition: G4Threading.cc:122
#define ns(x)
Definition: xmltok.c:1649