Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ParticleTable.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// G4ParticleTable class implementation
27//
28// Authors: G.Cosmo, 2 December 1995 - Design, based on object model
29// H.Kurashige, 27 June 1996 - First implementation
30// History:
31// - 14 Nov 1997, H.Kurashige - Added messenger
32// - 24 Sep 1998, H.Kurashige - Added dictionary for encoding
33// - 28 Oct 1999, H.Kurashige - Migration to STL maps
34// - 15 Sep 2017, K.L.Genser - Added support for MuonicAtom
35// --------------------------------------------------------------------
36
37#include "G4ParticleTable.hh"
38
39#include "G4IonTable.hh"
41#include "G4StateManager.hh"
42#include "G4UImessenger.hh"
43#include "G4ios.hh"
44#include "globals.hh"
45
46// These fields should be thread local or thread private. For a singleton
47// class, we can change any member field as static without any problem
48// because there is only one instance. Then we are allowed to add
49// "G4ThreadLocal"
50//
54 nullptr;
55
56// These shadow pointers are used by each worker thread to copy the content
57// from the master thread
58//
62
63// Static class variable: pointer to single instance of class
64//
66
67#ifdef G4MULTITHREADED
68// Lock for particle table accesses.
69//
70G4Mutex& G4ParticleTable::particleTableMutex()
71{
72 static G4Mutex _instance = G4MUTEX_INITIALIZER;
73 return _instance;
74}
75G4int& G4ParticleTable::lockCount()
76{
77 static G4int _instance = 0;
78 return _instance;
79}
80#endif
81
83{
84 if (fgParticleTable == nullptr) {
85 static G4ParticleTable theParticleTable;
86 fgParticleTable = &theParticleTable;
87 }
88
89 // Here we initialize all thread private data members.
90 //
92
93 return fgParticleTable;
94}
95
96G4ParticleTable::G4ParticleTable()
97{
99
100 // Set up the shadow pointer used by worker threads
101 //
102 if (fDictionaryShadow == nullptr) {
104 }
105
107
108 // Set up the shadow pointer used by worker threads
109 //
110 if (fIteratorShadow == nullptr) {
112 }
113
115 // Set up the shadow pointer used by worker threads
116 //
117 if (fEncodingDictionaryShadow == nullptr) {
119 }
120
121 // Ion Table
122 //
123 fIonTable = new G4IonTable();
124 fParticleMessenger = nullptr;
125}
126
127// This method is similar to the constructor. It is used by each worker
128// thread to achieve the partial effect as that of the master thread.
129// Here we initialize all thread private data members
131{
132 // The iterator for the shadow particle table is not sharable.
133 //
134#ifdef G4MULTITHREADED
135 G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
136 G4ParticleTable::lockCount()++;
137#endif
138 if (fDictionary == nullptr) {
140 }
141 else {
142 fDictionary->clear();
143 }
144
145 if (fEncodingDictionary == nullptr) {
147 }
148 else {
149 fEncodingDictionary->clear();
150 }
151
152 fIteratorShadow->reset(false);
153 while ((*fIteratorShadow)()) // Loop checking, 09.08.2015, K.Kurashige
154 {
156 fDictionary->insert(std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle));
157 G4int code = particle->GetPDGEncoding();
158 if (code != 0) {
159 fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code, particle));
160 }
161 }
163
164#ifdef G4MULTITHREADED
165 G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
166#endif
167
169}
170
172{
173 readyToUse = false;
174
175 // remove all items from G4ParticleTable
177
178 // delete Ion Table
179 delete fIonTable;
180 fIonTable = nullptr;
181
182 // delete dictionary for encoding
183 if (fEncodingDictionary != nullptr) {
184 fEncodingDictionary->clear();
185 delete fEncodingDictionary;
186 fEncodingDictionary = nullptr;
187 }
188
189 if (fDictionary != nullptr) {
190 delete fIterator;
191 fIterator = nullptr;
192
193 fDictionary->clear();
194 delete fDictionary;
195 fDictionary = nullptr;
196 }
197
198 delete fParticleMessenger;
199 fParticleMessenger = nullptr;
200
201 fgParticleTable = nullptr;
202
203 G4ParticleDefinition::Clean(); // Delete sub-instance static data
204}
205
207{
208 // delete Ion Table in worker thread
210
211 // delete dictionary for encoding
212 if (fEncodingDictionary != nullptr) {
213 fEncodingDictionary->clear();
214 delete fEncodingDictionary;
215 fEncodingDictionary = nullptr;
216 }
217
218 if (fDictionary != nullptr) {
219 delete fIterator;
220 fIterator = nullptr;
221
222 fDictionary->clear();
223 delete fDictionary;
224 fDictionary = nullptr;
225 }
226}
227
229{
230 if (fParticleMessenger == nullptr) {
231 // UI messenger
233 }
234 return fParticleMessenger;
235}
236
238{
239 // set readyToUse false
240 readyToUse = false;
241
242#ifdef G4VERBOSE
243 if (verboseLevel > 1) {
244 G4cout << "G4ParticleTable::DeleteAllParticles() " << G4endl;
245 }
246#endif
247
248 // delete all particles
250 piter->reset(false);
251 while ((*piter)()) // Loop checking, 09.08.2015, K.Kurashige
252 {
253#ifdef G4VERBOSE
254 if (verboseLevel > 2) {
255 G4cout << "Delete " << (piter->value())->GetParticleName() << " " << (piter->value())
256 << G4endl;
257 }
258#endif
259 delete (piter->value());
260 }
262}
263
265{
266 if (readyToUse) {
267 G4Exception("G4ParticleTable::RemoveAllParticle()", "PART115", JustWarning,
268 "No effects because readyToUse is true.");
269 return;
270 }
271
272#ifdef G4VERBOSE
273 if (verboseLevel > 1) {
274 G4cout << "G4ParticleTable::RemoveAllParticles() " << G4endl;
275 }
276#endif
277
278 // remove all contents in Ion Table
279 if (fIonTable != nullptr) {
280 fIonTable->clear();
281 }
282
283 // clear dictionary
284 if (fDictionary != nullptr) {
285 fDictionary->clear();
286 }
287}
288
290{
291 // check particle name
292 if ((particle == nullptr) || (GetKey(particle).empty())) {
293 G4Exception("G4ParticleTable::Insert()", "PART121", FatalException,
294 "Particle witnout name can not be registered.");
295#ifdef G4VERBOSE
296 if (verboseLevel > 1) {
297 G4cout << "The particle[Addr:" << particle << "] has no name " << G4endl;
298 }
299#endif
300 return nullptr;
301 }
302
303 if (contains(particle)) {
304#ifdef G4VERBOSE
305 if (verboseLevel > 2) {
306 FindParticle(particle)->DumpTable();
307 }
308#endif
309 G4String msg = "The particle ";
310 msg += particle->GetParticleName();
311 msg += " has already been registered in the Particle Table ";
312 G4Exception("G4ParticleTable::Insert()", "PART122", FatalException, msg);
313
314 return particle;
315 }
316
318
319 // insert into Dictionary
320 pdic->insert(std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle));
321#ifdef G4MULTITHREADED
323 fDictionary->insert(std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle));
324 }
325#endif
326
328
329 // insert into EncodingDictionary
330 G4int code = particle->GetPDGEncoding();
331 if (code != 0) {
332 pedic->insert(std::pair<G4int, G4ParticleDefinition*>(code, particle));
333#ifdef G4MULTITHREADED
335 fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code, particle));
336 }
337#endif
338 }
339
340 // insert it in IonTable if "nucleus"
341 if (fIonTable->IsIon(particle)) {
342 fIonTable->Insert(particle);
343 }
344
345 // set Verbose Level same as ParticleTable
346 particle->SetVerboseLevel(verboseLevel);
347
348#ifdef G4VERBOSE
349 if (verboseLevel > 3) {
350 G4cout << "The particle " << particle->GetParticleName() << " is inserted in the ParticleTable "
351 << G4endl;
352 }
353#endif
354 return particle;
355}
356
358{
359 if (particle == nullptr) return nullptr;
360#ifdef G4MULTITHREADED
363 ed << "Request of removing " << particle->GetParticleName()
364 << " is ignored as it is invoked from a worker thread.";
365 G4Exception("G4ParticleTable::Remove()", "PART10117", JustWarning, ed);
366 return nullptr;
367 }
368#endif
369 if (readyToUse) {
371 G4ApplicationState currentState = pStateManager->GetCurrentState();
372 if (currentState != G4State_PreInit) {
373 G4String msg = "Request of removing ";
374 msg += particle->GetParticleName();
375 msg += " has No effects other than Pre_Init";
376 G4Exception("G4ParticleTable::Remove()", "PART117", JustWarning, msg);
377 return nullptr;
378 }
379
380#ifdef G4VERBOSE
381 if (verboseLevel > 0) {
382 G4cout << particle->GetParticleName() << " will be removed from the ParticleTable " << G4endl;
383 }
384#endif
385 }
386
387 auto it = fDictionaryShadow->find(GetKey(particle));
388 if (it != fDictionaryShadow->end()) {
389 fDictionaryShadow->erase(it);
390 // remove from EncodingDictionary
391 G4int code = particle->GetPDGEncoding();
392 if (code != 0) {
394 }
395 }
396 else {
397 return nullptr;
398 }
399
400 // remove it from IonTable if "nucleus"
401 if (fIonTable->IsIon(particle)) {
402 fIonTable->Remove(particle);
403 }
404
405#ifdef G4VERBOSE
406 if (verboseLevel > 3) {
407 G4cout << "The particle " << particle->GetParticleName()
408 << " is removed from the ParticleTable " << G4endl;
409 }
410#endif
411
412 return particle;
413}
414
416{
417 CheckReadiness();
418 if ((index >= 0) && (index < entries())) {
420 piter->reset(false);
421 G4int counter = 0;
422 while ((*piter)()) // Loop checking, 09.08.2015, K.Kurashige
423 {
424 if (counter == index) return piter->value();
425 ++counter;
426 }
427 }
428#ifdef G4VERBOSE
429 if (verboseLevel > 1) {
430 G4cout << " G4ParticleTable::GetParticle"
431 << " invalid index (=" << index << ")" << G4endl;
432 }
433#endif
434 return nullptr;
435}
436
438{
439 G4ParticleDefinition* aParticle = GetParticle(index);
440 if (aParticle != nullptr) {
441 return aParticle->GetParticleName();
442 }
443
444 return noName;
445}
446
448{
449 auto it = fDictionary->find(particle_name);
450 if (it != fDictionary->end()) {
451 return (*it).second;
452 }
453
454#ifdef G4MULTITHREADED
455 G4ParticleDefinition* ptcl = nullptr;
457 G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
458 auto its = fDictionaryShadow->find(particle_name);
459 if (its != fDictionaryShadow->end()) {
460 fDictionary->insert(*its);
461 ptcl = (*its).second;
462 G4int code = ptcl->GetPDGEncoding();
463 if (code != 0)
464 fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code, ptcl));
465 }
466 G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
467 }
468 return ptcl;
469#else
470 return nullptr;
471#endif
472}
473
475{
476 if (name != selectedName) {
477 const G4ParticleDefinition* part = FindParticle(name);
478 if (part != nullptr) {
479#ifdef G4MULTITHREADED
480 G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
481#endif
482 selectedParticle = part;
483 selectedName = name;
484#ifdef G4MULTITHREADED
485 G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
486#endif
487 }
488 }
489}
490
492{
493 CheckReadiness();
494 G4String key = GetKey(particle);
495 return FindParticle(key);
496}
497
499{
500 CheckReadiness();
501 // check aPDGEncoding is valid
502 if (aPDGEncoding == 0) {
503#ifdef G4VERBOSE
504 if (verboseLevel > 1) {
505 G4cout << "PDGEncoding [" << aPDGEncoding << "] is not valid " << G4endl;
506 }
507#endif
508 return nullptr;
509 }
510
512 G4ParticleDefinition* particle = nullptr;
513
514 if (pedic != nullptr) {
515 auto it = pedic->find(aPDGEncoding);
516 if (it != pedic->end()) {
517 particle = (*it).second;
518 }
519 }
520
521#ifdef G4MULTITHREADED
522 if (particle == nullptr && G4Threading::IsWorkerThread()) {
523 G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
524 auto its = fEncodingDictionaryShadow->find(aPDGEncoding);
525 if (its != fEncodingDictionaryShadow->end()) {
526 particle = (*its).second;
527 fEncodingDictionary->insert(*its);
528 G4String key = GetKey(particle);
529 fDictionary->insert(std::pair<G4String, G4ParticleDefinition*>(key, particle));
530 }
531 G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
532 }
533#endif
534
535#ifdef G4VERBOSE
536 if ((particle == nullptr) && (verboseLevel > 1)) {
537 G4cout << "CODE:" << aPDGEncoding << " does not exist in ParticleTable " << G4endl;
538 }
539#endif
540 return particle;
541}
542
543void G4ParticleTable::DumpTable(const G4String& particle_name)
544{
545 CheckReadiness();
546 if ((particle_name == "ALL") || (particle_name == "all")) {
547 // dump all particles
549 piter->reset();
550 while ((*piter)()) // Loop checking, 09.08.2015, K.Kurashige
551 {
552 (piter->value())->DumpTable();
553 }
554 }
555 else {
556 // dump only particle with name of particle_name
557 G4ParticleDefinition* ptr = FindParticle(particle_name);
558 if (ptr != nullptr) {
559 ptr->DumpTable();
560 }
561 else {
562#ifdef G4VERBOSE
563 if (verboseLevel > 1) {
564 G4cout << " G4ParticleTable::DumpTable : " << particle_name
565 << " does not exist in ParticleTable " << G4endl;
566 }
567#endif
568 }
569 }
570}
571
572void G4ParticleTable::CheckReadiness() const
573{
574 if (!readyToUse) {
575 G4String msg;
576 msg = "Illegal use of G4ParticleTable :\n";
577 msg += "Access to G4ParticleTable for finding a particle or equivalent\n";
578 msg += "operation occurs before G4VUserPhysicsList is instantiated and\n";
579 msg += "assigned to G4RunManager. Such an access is prohibited since\n";
580 msg += "Geant4 version 8.0. To fix this problem, please make sure that\n";
581 msg += "your main() instantiates G4VUserPhysicsList and set it to\n";
582 msg += "G4RunManager before instantiating other user classes such as\n";
583 msg += "G4VUserPrimaryParticleGeneratorAction.";
584 G4Exception("G4ParticleTable::CheckReadiness()", "PART002", FatalException, msg);
585 }
586}
587
589{
590 return fIonTable;
591}
592
597
602
607
608G4bool G4ParticleTable::contains(const G4String& particle_name) const
609{
610 auto it = fDictionaryShadow->find(particle_name);
611 return (it != fDictionaryShadow->cend());
612}
613
615{
616 return (G4int)fDictionary->size();
617}
618
620{
621 return (G4int)fDictionary->size();
622}
G4ApplicationState
@ G4State_PreInit
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#define G4MUTEX_INITIALIZER
#define G4MUTEXLOCK(mutex)
#define G4MUTEXUNLOCK(mutex)
std::mutex G4Mutex
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
void Remove(const G4ParticleDefinition *particle)
void DestroyWorkerG4IonTable()
void WorkerG4IonTable()
static G4bool IsIon(const G4ParticleDefinition *)
void Insert(const G4ParticleDefinition *particle)
void SetVerboseLevel(G4int value)
const G4String & GetParticleName() const
void reset(G4bool ifSkipIon=true)
G4IonTable * GetIonTable() const
static G4ThreadLocal G4PTblEncodingDictionary * fEncodingDictionary
G4ParticleDefinition * GetParticle(G4int index) const
static G4PTblEncodingDictionary * fEncodingDictionaryShadow
G4int entries() const
void DestroyWorkerG4ParticleTable()
G4bool contains(const G4ParticleDefinition *particle) const
static G4ParticleTable * fgParticleTable
G4PTblDicIterator * GetIterator() const
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
static G4ParticleTable * GetParticleTable()
G4ParticleDefinition * Insert(G4ParticleDefinition *particle)
void SelectParticle(const G4String &name)
G4ParticleTableIterator< G4int, G4ParticleDefinition * >::Map G4PTblEncodingDictionary
G4ParticleDefinition * Remove(G4ParticleDefinition *particle)
static G4PTblDictionary * fDictionaryShadow
static G4PTblDicIterator * fIteratorShadow
G4int size() const
G4ParticleTableIterator< G4String, G4ParticleDefinition * > G4PTblDicIterator
G4UImessenger * CreateMessenger()
G4IonTable * fIonTable
virtual ~G4ParticleTable()
G4ParticleMessenger * fParticleMessenger
const G4String & GetKey(const G4ParticleDefinition *particle) const
static G4ThreadLocal G4PTblDicIterator * fIterator
const G4PTblDictionary * GetDictionary() const
const G4PTblEncodingDictionary * GetEncodingDictionary() const
const G4String & GetParticleName(G4int index) const
G4ParticleTableIterator< G4String, G4ParticleDefinition * >::Map G4PTblDictionary
static G4ThreadLocal G4PTblDictionary * fDictionary
void DumpTable(const G4String &particle_name="ALL")
const G4ApplicationState & GetCurrentState() const
static G4StateManager * GetStateManager()
G4bool IsWorkerThread()
#define G4ThreadLocal
Definition tls.hh:77