Geant4  10.01.p02
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 //
27 // $Id: G4ParticleTable.cc 86781 2014-11-18 08:40:18Z gcosmo $
28 //
29 // class G4ParticleTable
30 //
31 // Implementation
32 //
33 // History:
34 // modified Apr., 97 H.Kurashige
35 // added fParticleMessenger 14 Nov., 97 H.Kurashige
36 // added GetParticle() 13 Dec., 97 H.Kurashige
37 // added IonTable and ShortLivedTable 27 June, 98 H.Kurashige
38 // modified FindIon 02 Aug., 98 H.Kurashige
39 // added dictionary for encoding 24 Sep., 98 H.Kurashige
40 // fixed bugs in destruction of IonTable 08 Nov.,98 H.Kurashige
41 // commented out G4cout/G4cout in the constructor 10 Nov.,98 H.Kurashige
42 // --------------------------------
43 // modified destructor for STL interface 18 May 1999
44 // fixed some improper codings 08 Apr., 99 H.Kurashige
45 // modified FindIon/GetIon methods 17 AUg., 99 H.Kurashige
46 // implement new version for using STL map instaed of
47 // RW PtrHashedDictionary 28 Oct., 99 H.Kurashige
48 // remove G4ShortLivedTable 25 July, 13 H.Kurashige
49 // remove FindIon/GetIon 25 Sep. 14 H.Kurashige
50 //
51 
52 #include "globals.hh"
53 #include "G4ios.hh"
54 #include "G4ParticleTable.hh"
55 #include "G4UImessenger.hh"
56 #include "G4ParticleMessenger.hh"
57 #include "G4IonTable.hh"
58 #include "G4StateManager.hh"
59 
60 // These fields should be thread local or thread private. For a singleton
61 // class, we can change any member field as static without any problem
62 // because there is only one instance. Then we are allowed to add
63 // "G4ThreadLocal".
64 //
69 
70 // This field should be thread private. However, we have to keep one copy
71 // of the ion table pointer. So we change all important fields of G4IonTable
72 // to the thread local variable.
73 //
75 
76 
77 // These shadow pointers are used by each worker thread to copy the content
78 // from the master thread.
79 //
84 
85 // Static class variable: ptr to single instance of class
87 
88 #ifdef G4MULTITHREADED
89 // Lock for particle table accesses.
90 //
91 G4Mutex G4ParticleTable::particleTableMutex = G4MUTEX_INITIALIZER;
92 G4int G4ParticleTable::lockCount = 0;
93 #endif
94 
97 {
98  static G4ParticleTable theParticleTable;
99  if (!fgParticleTable){
100  fgParticleTable = &theParticleTable;
101  }
102 
103  // Here we initialize all thread private data members.
104  //
106 
107  return fgParticleTable;
108 }
109 
112  :verboseLevel(1),
113  noName(" "),
114  readyToUse(false),
115  genericIon(NULL)
116 {
118 
119  // Set up the shadow pointer used by worker threads.
120  //
121  if (fDictionaryShadow == 0)
122  {
124  }
125 
127 
128  // Set up the shadow pointer used by worker threads.
129  //
130  if (fIteratorShadow == 0)
131  {
133  }
134 
136  // Set up the shadow pointer used by worker threads.
137  //
138  if (fEncodingDictionaryShadow == 0)
139  {
141  }
142 
143 
144  // Ion Table
145  fIonTable = new G4IonTable();
146 
147 }
148 
149 // This method is similar to the constructor. It is used by each worker
150 // thread to achieve the partial effect as that of the master thread.
151 // Here we initialize all thread private data members.
152 //
154 {
155  G4Exception("G4ParticleTable::SlaveG4ParticleTable()","G4MT0000",FatalException,"Obsolete");
156 }
157 
159 {
160  // The iterator for the shadow particle table is not sharable.
161  //
162 #ifdef G4MULTITHREADED
163  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex);
164  G4ParticleTable::lockCount++;
165 #endif
166  if(fDictionary == 0) {
167  fDictionary = new G4PTblDictionary();
168  } else {
169  fDictionary->clear();
170  }
171 
172  if(fEncodingDictionary == 0){
174  } else {
175  fEncodingDictionary->clear();
176  }
177 
178  fIteratorShadow->reset(false);
179  while( (*fIteratorShadow)() )
180  {
182  fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) );
183  G4int code = particle->GetPDGEncoding();
184  if (code !=0 ) {
185  fEncodingDictionary->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) );
186  }
187  }
189 
190 #ifdef G4MULTITHREADED
191  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex);
192 #endif
193 
195 
196 }
197 
198 // Do we need DestroySlaveG4ParticleTable()?
199 //
202 {
203  readyToUse = false;
204 
205  // remove all items from G4ParticleTable
207 
208  //delete Ion Table
209  if (fIonTable!=0) delete fIonTable;
210  fIonTable =0;
211 
212  // delete dictionary for encoding
213  if (fEncodingDictionary!=0){
214  fEncodingDictionary -> clear();
215  delete fEncodingDictionary;
217  }
218 
219 
220  if(fDictionary){
221  if (fIterator!=0 )delete fIterator;
222  fIterator =0;
223 
224  fDictionary->clear();
225  delete fDictionary;
226  fDictionary =0;
227  }
228 
229  if (fParticleMessenger!=0) delete fParticleMessenger;
231 
232  fgParticleTable =0;
233 
234 }
235 
238  :verboseLevel(1),
239  noName(" "),
240  readyToUse(false)
241 {
242  fParticleMessenger = 0 ;
243 
244  G4Exception("G4ParticleTable::G4ParticleTable()",
245  "PART001", FatalException,
246  "Illegal call of copy constructor for G4ParticleTable");
247  fDictionary = new G4PTblDictionary(*(right.fDictionary));
249 }
250 
253 {
254  if (this != &right) {
255  G4Exception("G4ParticleTable::G4ParticleTable()",
256  "PART001", FatalException,
257  "Illegal call of assignment operator for G4ParticleTable");
258  fDictionary = new G4PTblDictionary(*(right.fDictionary));
260  }
261  return *this;
262 }
263 
266 {
267  if (fParticleMessenger== 0) {
268  //UI messenger
270  }
271  return fParticleMessenger;
272 }
273 
276 {
277  if (fParticleMessenger!= 0) {
278  //UI messenger
279  delete fParticleMessenger;
281  }
282 
283 }
284 
287 {
288  //set readyToUse false
289  readyToUse = false;
290 
291 #ifdef G4VERBOSE
292  if (verboseLevel>1){
293  G4cout << "G4ParticleTable::DeleteAllParticles() " << G4endl;
294  }
295 #endif
296 
297  // delete all particles
298  G4PTblDicIterator *piter = fIterator;
299  piter -> reset(false);
300  while( (*piter)() ){
301 #ifdef G4VERBOSE
302  if (verboseLevel>2){
303  G4cout << "Delete " << (piter->value())->GetParticleName()
304  << " " << (piter->value()) << G4endl;
305  }
306 #endif
307  delete (piter->value());
308  }
310 }
311 
314 {
315  if (readyToUse) {
316  G4Exception("G4ParticleTable::RemoveAllParticle()",
317  "PART115", JustWarning,
318  "No effects because readyToUse is true.");
319  return;
320  }
321 
322 #ifdef G4VERBOSE
323  if (verboseLevel>1){
324  G4cout << "G4ParticleTable::RemoveAllParticles() " << G4endl;
325  }
326 #endif
327 
328  //remove all contnts in Ion Table
329  if (fIonTable!=0) {
330  fIonTable->clear();
331  }
332 
333  // clear dictionary
334  if (fDictionary) {
335  fDictionary->clear();
336  }
337 }
338 
341 {
342 
343  // check particle name
344  if ((particle == 0) || (GetKey(particle).isNull())) {
345  G4Exception("G4ParticleTable::Insert()",
346  "PART121", FatalException,
347  "Particle witnout name can not be registered.");
348 #ifdef G4VERBOSE
349  if (verboseLevel>1){
350  G4cout << "The particle[Addr:" << particle << "] has no name "<< G4endl;
351  }
352 #endif
353  return 0;
354 
355  }else {
356 
357  if (contains(particle)) {
358 #ifdef G4VERBOSE
359  if (verboseLevel>2){
360  FindParticle(particle) -> DumpTable();
361  }
362 #endif
363  G4String msg = "The particle ";
364  msg += particle->GetParticleName();
365  msg += " has already been registered in the Particle Table ";
366  G4Exception("G4ParticleTable::Insert()",
367  "PART122", FatalException,msg);
369  return particle;
370 
371  } else {
373 
374  // insert into Dictionary
375  pdic->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) );
376 #ifdef G4MULTITHREADED
378  { fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) ); }
379 #endif
380 
382  // insert into EncodingDictionary
383  G4int code = particle->GetPDGEncoding();
384  if (code !=0 ) {
385  pedic->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) );
386 #ifdef G4MULTITHREADED
388  { fEncodingDictionary->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) ); }
389 #endif
390  }
391 
392  // insert it in IonTable if "nucleus"
393  if (fIonTable->IsIon(particle) ){
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  G4cout << "The particle "<< particle->GetParticleName()
403  << " is inserted in the ParticleTable " << G4endl;
404  }
405 #endif
406 
407  return particle;
408  }
409  }
410 }
411 
414 {
415  if(!particle) return 0;
416 #ifdef G4MULTITHREADED
419  ed << "Request of removing " << particle->GetParticleName()
420  << " is ignored as it is invoked from a worker thread.";
421  G4Exception("G4ParticleTable::Remove()","PART10117",JustWarning,ed);
422  return 0;
423  }
424 #endif
425  if (readyToUse) {
427  G4ApplicationState currentState = pStateManager->GetCurrentState();
428  if (currentState != G4State_PreInit) {
429  G4String msg = "Request of removing ";
430  msg += particle->GetParticleName();
431  msg += " has No effects other than Pre_Init";
432  G4Exception("G4ParticleTable::Remove()",
433  "PART117", JustWarning, msg);
434  return 0;
435  } else {
436 #ifdef G4VERBOSE
437  if (verboseLevel>0){
438  G4cout << particle->GetParticleName()
439  << " will be removed from the ParticleTable " << G4endl;
440  }
441 #endif
442  }
443  }
444 
445  G4PTblDictionary::iterator it = fDictionaryShadow->find(GetKey(particle));
446  if (it != fDictionaryShadow->end()) {
447  fDictionaryShadow->erase(it);
448  // remove from EncodingDictionary
449  G4int code = particle->GetPDGEncoding();
450  if (code !=0 ) {
452  }
453  } else {
454  return 0;
455  }
456 
457  // remove it from IonTable if "nucleus"
458  if (fIonTable->IsIon(particle) ){
459  fIonTable->Remove(particle);
460  }
461 
462 #ifdef G4VERBOSE
463  if (verboseLevel>3){
464  G4cout << "The particle "<< particle->GetParticleName()
465  << " is removed from the ParticleTable " << G4endl;
466  }
467 #endif
468 
469  return particle;
470 }
471 
472 
475 {
476  CheckReadiness();
477  if ( (index >=0) && (index < entries()) ) {
478  G4PTblDicIterator *piter = fIterator;
479  piter -> reset(false);
480  G4int counter = 0;
481  while( (*piter)() ){
482  if ( counter == index ) return piter->value();
483  counter++;
484  }
485  }
486 #ifdef G4VERBOSE
487  if (verboseLevel>1){
488  G4cout << " G4ParticleTable::GetParticle"
489  << " invalid index (=" << index << ")" << G4endl;
490  }
491 #endif
492  return 0;
493 }
494 
497 {
498  G4ParticleDefinition* aParticle =GetParticle(index);
499  if (aParticle != 0) {
500  return aParticle->GetParticleName();
501  } else {
502  return noName;
503  }
504 }
505 
508 {
509  G4PTblDictionary::iterator it = fDictionary->find(particle_name);
510  if (it != fDictionary->end()) {
511  return (*it).second;
512  } else {
513 #ifdef G4MULTITHREADED
514  G4ParticleDefinition* ptcl = 0;
516  {
517  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex);
518  G4PTblDictionary::iterator its = fDictionaryShadow->find(particle_name);
519  if(its != fDictionaryShadow->end())
520  {
521  fDictionary->insert(*its);
522  ptcl = (*its).second;
523  G4int code = ptcl->GetPDGEncoding();
524  if(code!=0) fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code,ptcl) );
525  }
526  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex);
527  }
528  return ptcl;
529 #else
530  return 0;
531 #endif
532  }
533 }
534 
537 {
538  CheckReadiness();
539  G4String key = GetKey(particle);
540  return FindParticle(key);
541 }
542 
545 {
546  CheckReadiness();
547  // check aPDGEncoding is valid
548  if (aPDGEncoding == 0){
549 #ifdef G4VERBOSE
550  if (verboseLevel>1){
551  G4cout << "PDGEncoding [" << aPDGEncoding << "] is not valid " << G4endl;
552  }
553 #endif
554  return 0;
555  }
556 
558  G4ParticleDefinition* particle =0;
559 
560  G4PTblEncodingDictionary::iterator it = pedic->find(aPDGEncoding );
561  if (it != pedic->end()) {
562  particle = (*it).second;
563  }
564 
565 #ifdef G4MULTITHREADED
566  if(particle == 0 && G4Threading::IsWorkerThread())
567  {
568  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex);
569  G4PTblEncodingDictionary::iterator its = fEncodingDictionaryShadow->find(aPDGEncoding);
570  if(its!=fEncodingDictionaryShadow->end())
571  {
572  particle = (*its).second;
573  fEncodingDictionary->insert(*its);
574  G4String key = GetKey(particle);
575  fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(key,particle) );
576  }
577  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex);
578  }
579 #endif
580 
581 #ifdef G4VERBOSE
582  if ((particle == 0) && (verboseLevel>1) ){
583  G4cout << "CODE:" << aPDGEncoding << " does not exist in ParticleTable " << G4endl;
584  }
585 #endif
586  return particle;
587 }
588 
590 void G4ParticleTable::DumpTable(const G4String &particle_name)
591 {
592  CheckReadiness();
593  if (( particle_name == "ALL" ) || (particle_name == "all")){
594  // dump all particles
595  G4PTblDicIterator *piter = fIterator;
596  piter -> reset();
597  while( (*piter)() ){
598  (piter->value())->DumpTable();
599  }
600  } else {
601  // dump only particle with name of particle_name
603  ptr = FindParticle(particle_name);
604  if ( ptr != 0) {
605  ptr->DumpTable();
606  } else {
607 #ifdef G4VERBOSE
608  if (verboseLevel>1) {
609  G4cout << " G4ParticleTable::DumpTable : "
610  << particle_name << " does not exist in ParticleTable " <<G4endl;
611  }
612 #endif
613  }
614  }
615 }
616 
618 {
619  if(!readyToUse) {
620  G4String msg;
621  msg = "Illegal use of G4ParticleTable : ";
622  msg += " Access to G4ParticleTable for finding a particle or equivalent\n";
623  msg += "operation occurs before G4VUserPhysicsList is instantiated and\n";
624  msg += "assigned to G4RunManager. Such an access is prohibited by\n";
625  msg += "Geant4 version 8.0. To fix this problem, please make sure that\n";
626  msg += "your main() instantiates G4VUserPhysicsList and set it to\n";
627  msg += "G4RunManager before instantiating other user classes such as\n";
628  msg += "G4VUserPrimaryParticleGeneratorAction.";
629  G4Exception("G4ParticleTable::CheckReadiness()",
630  "PART002",FatalException,msg);
631  }
632 }
633 
634 
635 
637 {
638  return fIonTable;
639 }
640 
642 {
643  return fDictionary;
644 }
645 
647 {
648  return fIterator;
649 }
650 
652 {
653  return fEncodingDictionary;
654 }
655 
656 G4bool G4ParticleTable::contains(const G4String& particle_name) const
657 {
658  G4PTblDictionary::iterator it = fDictionaryShadow->find(particle_name);
659  return (it != fDictionaryShadow->end());
660 }
661 
663 {
664  return fDictionary->size();
665 }
666 
668 {
669  return fDictionary->size();
670 }
671 
672 
#define G4MUTEXUNLOCK
Definition: G4Threading.hh:180
void WorkerG4ParticleTable()
void WorkerG4IonTable()
Definition: G4IonTable.cc:153
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
void DumpTable(const G4String &particle_name="ALL")
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
const G4PTblDictionary * GetDictionary() const
const G4String & GetParticleName(G4int index) const
G4UImessenger * CreateMessenger()
virtual ~G4ParticleTable()
G4ParticleDefinition * Remove(G4ParticleDefinition *particle)
const G4String & GetKey(const G4ParticleDefinition *particle) const
void Remove(const G4ParticleDefinition *particle)
Definition: G4IonTable.cc:1318
G4ParticleTableIterator< G4int, G4ParticleDefinition * >::Map G4PTblEncodingDictionary
static G4bool IsIon(const G4ParticleDefinition *)
Definition: G4IonTable.cc:1061
#define G4ThreadLocal
Definition: tls.hh:89
G4ParticleTableIterator< G4String, G4ParticleDefinition * > G4PTblDicIterator
int G4int
Definition: G4Types.hh:78
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:175
const G4String & GetParticleName() const
void Insert(const G4ParticleDefinition *particle)
Definition: G4IonTable.cc:1277
static G4ParticleMessenger * fParticleMessengerShadow
static G4ThreadLocal G4ParticleMessenger * fParticleMessenger
static G4PTblEncodingDictionary * fEncodingDictionaryShadow
static G4StateManager * GetStateManager()
G4ParticleDefinition * GetParticle(G4int index) const
G4ParticleTable & operator=(const G4ParticleTable &)
G4ParticleDefinition * Insert(G4ParticleDefinition *particle)
G4IonTable * GetIonTable() const
G4GLOB_DLL std::ostream G4cout
void reset(G4bool ifSkipIon=true)
const G4String noName
bool G4bool
Definition: G4Types.hh:79
#define G4MUTEXLOCK
Definition: G4Threading.hh:179
G4ApplicationState GetCurrentState() const
void SetVerboseLevel(G4int value)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4bool IsWorkerThread()
Definition: G4Threading.cc:128
G4bool contains(const G4ParticleDefinition *particle) const
G4int G4Mutex
Definition: G4Threading.hh:173
static G4ParticleTable * GetParticleTable()
static G4ThreadLocal G4PTblDictionary * fDictionary
void clear()
Definition: G4IonTable.cc:1259
#define G4endl
Definition: G4ios.hh:61
const G4PTblEncodingDictionary * GetEncodingDictionary() const
G4int size() const
void CheckReadiness() const
static G4IonTable * fIonTable
G4PTblDicIterator * GetIterator() const
G4int entries() const
static G4ThreadLocal G4PTblDicIterator * fIterator
G4ApplicationState
static G4ThreadLocal G4PTblEncodingDictionary * fEncodingDictionary
static G4PTblDicIterator * fIteratorShadow
static G4ParticleTable * fgParticleTable
static G4PTblDictionary * fDictionaryShadow
G4ParticleTableIterator< G4String, G4ParticleDefinition * >::Map G4PTblDictionary