Geant4-11
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// --------------------------------------------------------------------
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{
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 {
562 if(part)
563 {
564#ifdef G4MULTITHREADED
565 G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
566#endif
567 selectedParticle = part;
569#ifdef G4MULTITHREADED
570 G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
571#endif
572 }
573 }
574}
575
576// --------------------------------------------------------------------
579{
581 G4String key = GetKey(particle);
582 return FindParticle(key);
583}
584
585// --------------------------------------------------------------------
587{
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{
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// --------------------------------------------------------------------
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:35
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
const G4String noName
const G4ParticleDefinition * selectedParticle
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()
void CheckReadiness() const
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()
const char * name(G4int ptype)
G4bool IsWorkerThread()
Definition: G4Threading.cc:123
Definition: inftrees.h:24
#define G4ThreadLocal
Definition: tls.hh:77