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
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 "globals.hh"
38#include "G4ios.hh"
39#include "G4ParticleTable.hh"
40#include "G4UImessenger.hh"
42#include "G4IonTable.hh"
43#include "G4StateManager.hh"
44
45// These fields should be thread local or thread private. For a singleton
46// class, we can change any member field as static without any problem
47// because there is only one instance. Then we are allowed to add
48// "G4ThreadLocal"
49//
56
57// These shadow pointers are used by each worker thread to copy the content
58// from the master thread
59//
66
67// Static class variable: pointer to single instance of class
68//
70
71#ifdef G4MULTITHREADED
72// Lock for particle table accesses.
73//
74G4Mutex& G4ParticleTable::particleTableMutex()
75{
76 static G4Mutex _instance = G4MUTEX_INITIALIZER;
77 return _instance;
78}
79G4int& G4ParticleTable::lockCount()
80{
81 static G4int _instance = 0;
82 return _instance;
83}
84#endif
85
86// --------------------------------------------------------------------
88{
89 if ( fgParticleTable == nullptr )
90 {
91 static G4ParticleTable theParticleTable;
92 fgParticleTable = &theParticleTable;
93 }
94
95 // Here we initialize all thread private data members.
96 //
98
99 return fgParticleTable;
100}
101
102// --------------------------------------------------------------------
103G4ParticleTable::G4ParticleTable()
104{
106
107 // Set up the shadow pointer used by worker threads
108 //
109 if (fDictionaryShadow == nullptr)
110 {
112 }
113
115
116 // Set up the shadow pointer used by worker threads
117 //
118 if (fIteratorShadow == nullptr)
119 {
121 }
122
124 // Set up the shadow pointer used by worker threads
125 //
126 if (fEncodingDictionaryShadow == nullptr)
127 {
129 }
130
131 // Ion Table
132 //
133 fIonTable = new G4IonTable();
134 fParticleMessenger = nullptr;
135}
136
137// --------------------------------------------------------------------
138// This method is similar to the constructor. It is used by each worker
139// thread to achieve the partial effect as that of the master thread.
140// Here we initialize all thread private data members
141//
143{
144 // The iterator for the shadow particle table is not sharable.
145 //
146#ifdef G4MULTITHREADED
147 G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
148 G4ParticleTable::lockCount()++;
149#endif
150 if(fDictionary == nullptr)
151 {
153 }
154 else
155 {
156 fDictionary->clear();
157 }
158
159 if(fEncodingDictionary == nullptr)
160 {
162 }
163 else
164 {
165 fEncodingDictionary->clear();
166 }
167
168 fIteratorShadow->reset(false);
169 while( (*fIteratorShadow)() ) // Loop checking, 09.08.2015, K.Kurashige
170 {
172 fDictionary->insert( std::pair<G4String,
173 G4ParticleDefinition*>(GetKey(particle), particle) );
174 G4int code = particle->GetPDGEncoding();
175 if (code !=0 )
176 {
177 fEncodingDictionary->insert( std::pair<G4int,
178 G4ParticleDefinition*>(code ,particle) );
179 }
180 }
182
183#ifdef G4MULTITHREADED
184 G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
185#endif
186
188}
189
190// --------------------------------------------------------------------
192{
193 readyToUse = false;
194
195 // remove all items from G4ParticleTable
197
198 // delete Ion Table
199 if (fIonTable != nullptr) delete fIonTable;
200 fIonTable = nullptr;
201
202 // delete dictionary for encoding
203 if (fEncodingDictionary != nullptr)
204 {
205 fEncodingDictionary->clear();
206 delete fEncodingDictionary;
207 fEncodingDictionary = nullptr;
208 }
209
210 if( fDictionary != nullptr)
211 {
212 if (fIterator != nullptr ) delete fIterator;
213 fIterator = nullptr;
214
215 fDictionary->clear();
216 delete fDictionary;
217 fDictionary =nullptr;
218 }
219
220 if ( fParticleMessenger != nullptr) delete fParticleMessenger;
221 fParticleMessenger = nullptr;
222
223 fgParticleTable = nullptr;
224
225 G4ParticleDefinition::Clean(); // Delete sub-instance static data
226}
227
228// --------------------------------------------------------------------
230{
231 // delete Ion Table in worker thread
233
234 // delete dictionary for encoding
235 if (fEncodingDictionary != nullptr)
236 {
237 fEncodingDictionary->clear();
238 delete fEncodingDictionary;
239 fEncodingDictionary = nullptr;
240 }
241
242 if( fDictionary != nullptr)
243 {
244 if (fIterator != nullptr ) delete fIterator;
245 fIterator = nullptr;
246
247 fDictionary->clear();
248 delete fDictionary;
249 fDictionary = nullptr;
250 }
251}
252
253// --------------------------------------------------------------------
255{
256 if (fParticleMessenger == nullptr)
257 {
258 // UI messenger
260 }
261 return fParticleMessenger;
262}
263
264// --------------------------------------------------------------------
266{
267 //set readyToUse false
268 readyToUse = false;
269
270#ifdef G4VERBOSE
271 if (verboseLevel>1)
272 {
273 G4cout << "G4ParticleTable::DeleteAllParticles() " << G4endl;
274 }
275#endif
276
277 // delete all particles
279 piter->reset(false);
280 while( (*piter)() ) // Loop checking, 09.08.2015, K.Kurashige
281 {
282#ifdef G4VERBOSE
283 if (verboseLevel>2)
284 {
285 G4cout << "Delete " << (piter->value())->GetParticleName()
286 << " " << (piter->value()) << G4endl;
287 }
288#endif
289 delete (piter->value());
290 }
292}
293
294// --------------------------------------------------------------------
296{
297 if (readyToUse)
298 {
299 G4Exception("G4ParticleTable::RemoveAllParticle()",
300 "PART115", JustWarning,
301 "No effects because readyToUse is true.");
302 return;
303 }
304
305#ifdef G4VERBOSE
306 if (verboseLevel>1)
307 {
308 G4cout << "G4ParticleTable::RemoveAllParticles() " << G4endl;
309 }
310#endif
311
312 // remove all contents in Ion Table
313 if (fIonTable != nullptr)
314 {
315 fIonTable->clear();
316 }
317
318 // clear dictionary
319 if (fDictionary != nullptr)
320 {
321 fDictionary->clear();
322 }
323}
324
325// --------------------------------------------------------------------
327{
328 // check particle name
329 if ((particle == nullptr) || (GetKey(particle).empty()))
330 {
331 G4Exception("G4ParticleTable::Insert()",
332 "PART121", FatalException,
333 "Particle witnout name can not be registered.");
334#ifdef G4VERBOSE
335 if (verboseLevel>1)
336 {
337 G4cout << "The particle[Addr:" << particle << "] has no name "<< G4endl;
338 }
339#endif
340 return nullptr;
341 }
342 else
343 {
344 if (contains(particle))
345 {
346#ifdef G4VERBOSE
347 if (verboseLevel>2)
348 {
349 FindParticle(particle) -> DumpTable();
350 }
351#endif
352 G4String msg = "The particle ";
353 msg += particle->GetParticleName();
354 msg += " has already been registered in the Particle Table ";
355 G4Exception("G4ParticleTable::Insert()", "PART122", FatalException, msg);
356
357 return particle;
358 }
359 else
360 {
362
363 // insert into Dictionary
364 pdic->insert( std::pair<G4String,
365 G4ParticleDefinition*>(GetKey(particle), particle) );
366#ifdef G4MULTITHREADED
368 {
369 fDictionary->insert( std::pair<G4String,
370 G4ParticleDefinition*>(GetKey(particle), particle) );
371 }
372#endif
373
375
376 // insert into EncodingDictionary
377 G4int code = particle->GetPDGEncoding();
378 if (code != 0 )
379 {
380 pedic->insert( std::pair<G4int,
381 G4ParticleDefinition*>(code ,particle) );
382#ifdef G4MULTITHREADED
384 {
385 fEncodingDictionary->insert( std::pair<G4int,
386 G4ParticleDefinition*>(code ,particle) );
387 }
388#endif
389 }
390
391 // insert it in IonTable if "nucleus"
392 if (fIonTable->IsIon(particle) )
393 {
394 fIonTable->Insert(particle);
395 }
396
397 // set Verbose Level same as ParticleTable
398 particle->SetVerboseLevel(verboseLevel);
399
400#ifdef G4VERBOSE
401 if (verboseLevel>3)
402 {
403 G4cout << "The particle "<< particle->GetParticleName()
404 << " is inserted in the ParticleTable " << G4endl;
405 }
406#endif
407 return particle;
408 }
409 }
410}
411
412// --------------------------------------------------------------------
414{
415 if( particle == nullptr) return nullptr;
416#ifdef G4MULTITHREADED
418 {
420 ed << "Request of removing " << particle->GetParticleName()
421 << " is ignored as it is invoked from a worker thread.";
422 G4Exception("G4ParticleTable::Remove()", "PART10117", JustWarning, ed);
423 return nullptr;
424 }
425#endif
426 if (readyToUse)
427 {
429 G4ApplicationState currentState = pStateManager->GetCurrentState();
430 if (currentState != G4State_PreInit)
431 {
432 G4String msg = "Request of removing ";
433 msg += particle->GetParticleName();
434 msg += " has No effects other than Pre_Init";
435 G4Exception("G4ParticleTable::Remove()", "PART117", JustWarning, msg);
436 return nullptr;
437 }
438 else
439 {
440#ifdef G4VERBOSE
441 if (verboseLevel>0)
442 {
443 G4cout << particle->GetParticleName()
444 << " will be removed from the ParticleTable " << G4endl;
445 }
446#endif
447 }
448 }
449
450 G4PTblDictionary::iterator it = fDictionaryShadow->find(GetKey(particle));
451 if (it != fDictionaryShadow->end())
452 {
453 fDictionaryShadow->erase(it);
454 // remove from EncodingDictionary
455 G4int code = particle->GetPDGEncoding();
456 if (code != 0 )
457 {
459 }
460 }
461 else
462 {
463 return nullptr;
464 }
465
466 // remove it from IonTable if "nucleus"
467 if (fIonTable->IsIon(particle) )
468 {
469 fIonTable->Remove(particle);
470 }
471
472#ifdef G4VERBOSE
473 if (verboseLevel>3)
474 {
475 G4cout << "The particle "<< particle->GetParticleName()
476 << " is removed from the ParticleTable " << G4endl;
477 }
478#endif
479
480 return particle;
481}
482
483// --------------------------------------------------------------------
485{
486 CheckReadiness();
487 if ( (index >=0) && (index < entries()) )
488 {
490 piter -> reset(false);
491 G4int counter = 0;
492 while( (*piter)() ) // Loop checking, 09.08.2015, K.Kurashige
493 {
494 if ( counter == index ) return piter->value();
495 ++counter;
496 }
497 }
498#ifdef G4VERBOSE
499 if (verboseLevel>1)
500 {
501 G4cout << " G4ParticleTable::GetParticle"
502 << " invalid index (=" << index << ")" << G4endl;
503 }
504#endif
505 return nullptr;
506}
507
508// --------------------------------------------------------------------
510{
511 G4ParticleDefinition* aParticle =GetParticle(index);
512 if (aParticle != nullptr)
513 {
514 return aParticle->GetParticleName();
515 }
516 else
517 {
518 return noName;
519 }
520}
521
522// --------------------------------------------------------------------
525{
526 G4PTblDictionary::iterator it = fDictionary->find(particle_name);
527 if (it != fDictionary->end())
528 {
529 return (*it).second;
530 }
531 else
532 {
533#ifdef G4MULTITHREADED
534 G4ParticleDefinition* ptcl = nullptr;
536 {
537 G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
538 G4PTblDictionary::iterator its = fDictionaryShadow->find(particle_name);
539 if(its != fDictionaryShadow->end())
540 {
541 fDictionary->insert(*its);
542 ptcl = (*its).second;
543 G4int code = ptcl->GetPDGEncoding();
544 if(code!=0) fEncodingDictionary->insert(std::pair<G4int,
545 G4ParticleDefinition*>(code,ptcl) );
546 }
547 G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
548 }
549 return ptcl;
550#else
551 return nullptr;
552#endif
553 }
554}
555
556// --------------------------------------------------------------------
558{
559 if(name != selectedName)
560 {
561 const G4ParticleDefinition* part = FindParticle(name);
562 if(part)
563 {
564#ifdef G4MULTITHREADED
565 G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
566#endif
567 selectedParticle = part;
568 selectedName = name;
569#ifdef G4MULTITHREADED
570 G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
571#endif
572 }
573 }
574}
575
576// --------------------------------------------------------------------
579{
580 CheckReadiness();
581 G4String key = GetKey(particle);
582 return FindParticle(key);
583}
584
585// --------------------------------------------------------------------
587{
588 CheckReadiness();
589 // check aPDGEncoding is valid
590 if (aPDGEncoding == 0)
591 {
592#ifdef G4VERBOSE
593 if (verboseLevel>1)
594 {
595 G4cout << "PDGEncoding [" << aPDGEncoding << "] is not valid "
596 << G4endl;
597 }
598#endif
599 return nullptr;
600 }
601
603 G4ParticleDefinition* particle = nullptr;
604
605 if (pedic)
606 {
607 G4PTblEncodingDictionary::iterator it = pedic->find(aPDGEncoding );
608 if (it != pedic->end())
609 {
610 particle = (*it).second;
611 }
612 }
613
614#ifdef G4MULTITHREADED
615 if(particle == nullptr && G4Threading::IsWorkerThread())
616 {
617 G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
618 G4PTblEncodingDictionary::iterator its
619 = fEncodingDictionaryShadow->find(aPDGEncoding);
620 if(its!=fEncodingDictionaryShadow->end())
621 {
622 particle = (*its).second;
623 fEncodingDictionary->insert(*its);
624 G4String key = GetKey(particle);
625 fDictionary->insert( std::pair<G4String,
626 G4ParticleDefinition*>(key,particle) );
627 }
628 G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
629 }
630#endif
631
632#ifdef G4VERBOSE
633 if ((particle == nullptr) && (verboseLevel>1) )
634 {
635 G4cout << "CODE:" << aPDGEncoding << " does not exist in ParticleTable "
636 << G4endl;
637 }
638#endif
639 return particle;
640}
641
642// --------------------------------------------------------------------
643void G4ParticleTable::DumpTable(const G4String& particle_name)
644{
645 CheckReadiness();
646 if (( particle_name == "ALL" ) || (particle_name == "all"))
647 {
648 // dump all particles
650 piter -> reset();
651 while( (*piter)() ) // Loop checking, 09.08.2015, K.Kurashige
652 {
653 (piter->value())->DumpTable();
654 }
655 }
656 else
657 {
658 // dump only particle with name of particle_name
659 G4ParticleDefinition *ptr = FindParticle(particle_name);
660 if ( ptr != nullptr)
661 {
662 ptr->DumpTable();
663 }
664 else
665 {
666#ifdef G4VERBOSE
667 if (verboseLevel>1)
668 {
669 G4cout << " G4ParticleTable::DumpTable : "
670 << particle_name << " does not exist in ParticleTable "
671 << G4endl;
672 }
673#endif
674 }
675 }
676}
677
678// --------------------------------------------------------------------
679void G4ParticleTable::CheckReadiness() const
680{
681 if(!readyToUse)
682 {
683 G4String msg;
684 msg = "Illegal use of G4ParticleTable :\n";
685 msg += "Access to G4ParticleTable for finding a particle or equivalent\n";
686 msg += "operation occurs before G4VUserPhysicsList is instantiated and\n";
687 msg += "assigned to G4RunManager. Such an access is prohibited since\n";
688 msg += "Geant4 version 8.0. To fix this problem, please make sure that\n";
689 msg += "your main() instantiates G4VUserPhysicsList and set it to\n";
690 msg += "G4RunManager before instantiating other user classes such as\n";
691 msg += "G4VUserPrimaryParticleGeneratorAction.";
692 G4Exception("G4ParticleTable::CheckReadiness()",
693 "PART002", FatalException, msg);
694 }
695}
696
697// --------------------------------------------------------------------
699{
700 return fIonTable;
701}
702
703// --------------------------------------------------------------------
705{
706 return fDictionary;
707}
708
709// --------------------------------------------------------------------
711{
712 return fIterator;
713}
714
715// --------------------------------------------------------------------
718{
719 return fEncodingDictionary;
720}
721
722// --------------------------------------------------------------------
723G4bool G4ParticleTable::contains(const G4String& particle_name) const
724{
725 G4PTblDictionary::iterator it = fDictionaryShadow->find(particle_name);
726 return (it != fDictionaryShadow->cend());
727}
728
729// --------------------------------------------------------------------
731{
732 return (G4int)fDictionary->size();
733}
734
735// --------------------------------------------------------------------
737{
738 return (G4int)fDictionary->size();
739}
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 G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
#define G4MUTEXLOCK(mutex)
Definition: G4Threading.hh:251
#define G4MUTEXUNLOCK(mutex)
Definition: G4Threading.hh:254
std::mutex G4Mutex
Definition: G4Threading.hh:81
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
void Remove(const G4ParticleDefinition *particle)
Definition: G4IonTable.cc:1594
void clear()
Definition: G4IonTable.cc:1526
void DestroyWorkerG4IonTable()
Definition: G4IonTable.cc:214
void WorkerG4IonTable()
Definition: G4IonTable.cc:180
static G4bool IsIon(const G4ParticleDefinition *)
Definition: G4IonTable.cc:1302
void Insert(const G4ParticleDefinition *particle)
Definition: G4IonTable.cc:1548
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
void WorkerG4ParticleTable()
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()
Definition: G4Threading.cc:123
Definition: inftrees.h:24
#define G4ThreadLocal
Definition: tls.hh:77