Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/particles/management/src/G4ParticleDefinition.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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