Geant4  10.02
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 94421 2015-11-16 08:22:56Z 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)() ) { // Loop checking, 09.08.2015, K.Kurashige
181  fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) );
182  G4int code = particle->GetPDGEncoding();
183  if (code !=0 ) {
184  fEncodingDictionary->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) );
185  }
186  }
188 
189 #ifdef G4MULTITHREADED
190  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex);
191 #endif
192 
194 
195 }
196 
199 {
200  readyToUse = false;
201 
202  // remove all items from G4ParticleTable
204 
205  //delete Ion Table
206  if (fIonTable!=0) delete fIonTable;
207  fIonTable =0;
208 
209  // delete dictionary for encoding
210  if (fEncodingDictionary!=0){
211  fEncodingDictionary -> clear();
212  delete fEncodingDictionary;
214  }
215 
216  if(fDictionary){
217  if (fIterator!=0 )delete fIterator;
218  fIterator =0;
219 
220  fDictionary->clear();
221  delete fDictionary;
222  fDictionary =0;
223  }
224 
225  if (fParticleMessenger!=0) delete fParticleMessenger;
227 
228  fgParticleTable =0;
229 
230 }
231 
234 {
235  //delete Ion Table in worker thread
237 
238  // delete dictionary for encoding
239  if (fEncodingDictionary!=0){
240  fEncodingDictionary -> clear();
241  delete fEncodingDictionary;
243  }
244 
245  if(fDictionary){
246  if (fIterator!=0 )delete fIterator;
247  fIterator =0;
248 
249  fDictionary->clear();
250  delete fDictionary;
251  fDictionary =0;
252  }
253 
254  if (fParticleMessenger!=0) delete fParticleMessenger;
256 }
257 
260  :verboseLevel(1),
261  noName(" "),
262  readyToUse(false)
263 {
264  fParticleMessenger = 0 ;
265 
266  G4Exception("G4ParticleTable::G4ParticleTable()",
267  "PART001", FatalException,
268  "Illegal call of copy constructor for G4ParticleTable");
269  fDictionary = new G4PTblDictionary(*(right.fDictionary));
271 }
272 
275 {
276  if (this != &right) {
277  G4Exception("G4ParticleTable::G4ParticleTable()",
278  "PART001", FatalException,
279  "Illegal call of assignment operator for G4ParticleTable");
280  fDictionary = new G4PTblDictionary(*(right.fDictionary));
282  }
283  return *this;
284 }
285 
288 {
289  if (fParticleMessenger== 0) {
290  //UI messenger
292  }
293  return fParticleMessenger;
294 }
295 
298 {
299  if (fParticleMessenger!= 0) {
300  //UI messenger
301  delete fParticleMessenger;
303  }
304 
305 }
306 
309 {
310  //set readyToUse false
311  readyToUse = false;
312 
313 #ifdef G4VERBOSE
314  if (verboseLevel>1){
315  G4cout << "G4ParticleTable::DeleteAllParticles() " << G4endl;
316  }
317 #endif
318 
319  // delete all particles
320  G4PTblDicIterator *piter = fIterator;
321  piter -> reset(false);
322  while( (*piter)() ){// Loop checking, 09.08.2015, K.Kurashige
323 #ifdef G4VERBOSE
324  if (verboseLevel>2){
325  G4cout << "Delete " << (piter->value())->GetParticleName()
326  << " " << (piter->value()) << G4endl;
327  }
328 #endif
329  delete (piter->value());
330  }
332 }
333 
336 {
337  if (readyToUse) {
338  G4Exception("G4ParticleTable::RemoveAllParticle()",
339  "PART115", JustWarning,
340  "No effects because readyToUse is true.");
341  return;
342  }
343 
344 #ifdef G4VERBOSE
345  if (verboseLevel>1){
346  G4cout << "G4ParticleTable::RemoveAllParticles() " << G4endl;
347  }
348 #endif
349 
350  //remove all contnts in Ion Table
351  if (fIonTable!=0) {
352  fIonTable->clear();
353  }
354 
355  // clear dictionary
356  if (fDictionary) {
357  fDictionary->clear();
358  }
359 }
360 
363 {
364 
365  // check particle name
366  if ((particle == 0) || (GetKey(particle).isNull())) {
367  G4Exception("G4ParticleTable::Insert()",
368  "PART121", FatalException,
369  "Particle witnout name can not be registered.");
370 #ifdef G4VERBOSE
371  if (verboseLevel>1){
372  G4cout << "The particle[Addr:" << particle << "] has no name "<< G4endl;
373  }
374 #endif
375  return 0;
376 
377  }else {
378 
379  if (contains(particle)) {
380 #ifdef G4VERBOSE
381  if (verboseLevel>2){
382  FindParticle(particle) -> DumpTable();
383  }
384 #endif
385  G4String msg = "The particle ";
386  msg += particle->GetParticleName();
387  msg += " has already been registered in the Particle Table ";
388  G4Exception("G4ParticleTable::Insert()",
389  "PART122", FatalException,msg);
391  return particle;
392 
393  } else {
395 
396  // insert into Dictionary
397  pdic->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) );
398 #ifdef G4MULTITHREADED
400  { fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) ); }
401 #endif
402 
404  // insert into EncodingDictionary
405  G4int code = particle->GetPDGEncoding();
406  if (code !=0 ) {
407  pedic->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) );
408 #ifdef G4MULTITHREADED
410  { fEncodingDictionary->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) ); }
411 #endif
412  }
413 
414  // insert it in IonTable if "nucleus"
415  if (fIonTable->IsIon(particle) ){
416  fIonTable->Insert(particle);
417  }
418 
419  // set Verbose Level same as ParticleTable
420  particle->SetVerboseLevel(verboseLevel);
421 
422 #ifdef G4VERBOSE
423  if (verboseLevel>3){
424  G4cout << "The particle "<< particle->GetParticleName()
425  << " is inserted in the ParticleTable " << G4endl;
426  }
427 #endif
428 
429  return particle;
430  }
431  }
432 }
433 
436 {
437  if(!particle) return 0;
438 #ifdef G4MULTITHREADED
441  ed << "Request of removing " << particle->GetParticleName()
442  << " is ignored as it is invoked from a worker thread.";
443  G4Exception("G4ParticleTable::Remove()","PART10117",JustWarning,ed);
444  return 0;
445  }
446 #endif
447  if (readyToUse) {
449  G4ApplicationState currentState = pStateManager->GetCurrentState();
450  if (currentState != G4State_PreInit) {
451  G4String msg = "Request of removing ";
452  msg += particle->GetParticleName();
453  msg += " has No effects other than Pre_Init";
454  G4Exception("G4ParticleTable::Remove()",
455  "PART117", JustWarning, msg);
456  return 0;
457  } else {
458 #ifdef G4VERBOSE
459  if (verboseLevel>0){
460  G4cout << particle->GetParticleName()
461  << " will be removed from the ParticleTable " << G4endl;
462  }
463 #endif
464  }
465  }
466 
467  G4PTblDictionary::iterator it = fDictionaryShadow->find(GetKey(particle));
468  if (it != fDictionaryShadow->end()) {
469  fDictionaryShadow->erase(it);
470  // remove from EncodingDictionary
471  G4int code = particle->GetPDGEncoding();
472  if (code !=0 ) {
474  }
475  } else {
476  return 0;
477  }
478 
479  // remove it from IonTable if "nucleus"
480  if (fIonTable->IsIon(particle) ){
481  fIonTable->Remove(particle);
482  }
483 
484 #ifdef G4VERBOSE
485  if (verboseLevel>3){
486  G4cout << "The particle "<< particle->GetParticleName()
487  << " is removed from the ParticleTable " << G4endl;
488  }
489 #endif
490 
491  return particle;
492 }
493 
494 
497 {
498  CheckReadiness();
499  if ( (index >=0) && (index < entries()) ) {
500  G4PTblDicIterator *piter = fIterator;
501  piter -> reset(false);
502  G4int counter = 0;
503  while( (*piter)() ){ // Loop checking, 09.08.2015, K.Kurashige
504  if ( counter == index ) return piter->value();
505  counter++;
506  }
507  }
508 #ifdef G4VERBOSE
509  if (verboseLevel>1){
510  G4cout << " G4ParticleTable::GetParticle"
511  << " invalid index (=" << index << ")" << G4endl;
512  }
513 #endif
514  return 0;
515 }
516 
519 {
520  G4ParticleDefinition* aParticle =GetParticle(index);
521  if (aParticle != 0) {
522  return aParticle->GetParticleName();
523  } else {
524  return noName;
525  }
526 }
527 
530 {
531  G4PTblDictionary::iterator it = fDictionary->find(particle_name);
532  if (it != fDictionary->end()) {
533  return (*it).second;
534  } else {
535 #ifdef G4MULTITHREADED
536  G4ParticleDefinition* ptcl = 0;
538  {
539  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex);
540  G4PTblDictionary::iterator its = fDictionaryShadow->find(particle_name);
541  if(its != fDictionaryShadow->end())
542  {
543  fDictionary->insert(*its);
544  ptcl = (*its).second;
545  G4int code = ptcl->GetPDGEncoding();
546  if(code!=0) fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code,ptcl) );
547  }
548  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex);
549  }
550  return ptcl;
551 #else
552  return 0;
553 #endif
554  }
555 }
556 
559 {
560  CheckReadiness();
561  G4String key = GetKey(particle);
562  return FindParticle(key);
563 }
564 
567 {
568  CheckReadiness();
569  // check aPDGEncoding is valid
570  if (aPDGEncoding == 0){
571 #ifdef G4VERBOSE
572  if (verboseLevel>1){
573  G4cout << "PDGEncoding [" << aPDGEncoding << "] is not valid " << G4endl;
574  }
575 #endif
576  return 0;
577  }
578 
580  G4ParticleDefinition* particle =0;
581 
582  G4PTblEncodingDictionary::iterator it = pedic->find(aPDGEncoding );
583  if (it != pedic->end()) {
584  particle = (*it).second;
585  }
586 
587 #ifdef G4MULTITHREADED
588  if(particle == 0 && G4Threading::IsWorkerThread())
589  {
590  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex);
591  G4PTblEncodingDictionary::iterator its = fEncodingDictionaryShadow->find(aPDGEncoding);
592  if(its!=fEncodingDictionaryShadow->end())
593  {
594  particle = (*its).second;
595  fEncodingDictionary->insert(*its);
596  G4String key = GetKey(particle);
597  fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(key,particle) );
598  }
599  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex);
600  }
601 #endif
602 
603 #ifdef G4VERBOSE
604  if ((particle == 0) && (verboseLevel>1) ){
605  G4cout << "CODE:" << aPDGEncoding << " does not exist in ParticleTable " << G4endl;
606  }
607 #endif
608  return particle;
609 }
610 
612 void G4ParticleTable::DumpTable(const G4String &particle_name)
613 {
614  CheckReadiness();
615  if (( particle_name == "ALL" ) || (particle_name == "all")){
616  // dump all particles
617  G4PTblDicIterator *piter = fIterator;
618  piter -> reset();
619  while( (*piter)() ){// Loop checking, 09.08.2015, K.Kurashige
620  (piter->value())->DumpTable();
621  }
622  } else {
623  // dump only particle with name of particle_name
625  ptr = FindParticle(particle_name);
626  if ( ptr != 0) {
627  ptr->DumpTable();
628  } else {
629 #ifdef G4VERBOSE
630  if (verboseLevel>1) {
631  G4cout << " G4ParticleTable::DumpTable : "
632  << particle_name << " does not exist in ParticleTable " <<G4endl;
633  }
634 #endif
635  }
636  }
637 }
638 
640 {
641  if(!readyToUse) {
642  G4String msg;
643  msg = "Illegal use of G4ParticleTable : ";
644  msg += " Access to G4ParticleTable for finding a particle or equivalent\n";
645  msg += "operation occurs before G4VUserPhysicsList is instantiated and\n";
646  msg += "assigned to G4RunManager. Such an access is prohibited by\n";
647  msg += "Geant4 version 8.0. To fix this problem, please make sure that\n";
648  msg += "your main() instantiates G4VUserPhysicsList and set it to\n";
649  msg += "G4RunManager before instantiating other user classes such as\n";
650  msg += "G4VUserPrimaryParticleGeneratorAction.";
651  G4Exception("G4ParticleTable::CheckReadiness()",
652  "PART002",FatalException,msg);
653  }
654 }
655 
656 
657 
659 {
660  return fIonTable;
661 }
662 
664 {
665  return fDictionary;
666 }
667 
669 {
670  return fIterator;
671 }
672 
674 {
675  return fEncodingDictionary;
676 }
677 
678 G4bool G4ParticleTable::contains(const G4String& particle_name) const
679 {
680  G4PTblDictionary::iterator it = fDictionaryShadow->find(particle_name);
681  return (it != fDictionaryShadow->end());
682 }
683 
685 {
686  return fDictionary->size();
687 }
688 
690 {
691  return fDictionary->size();
692 }
693 
694 
#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:1346
G4ParticleTableIterator< G4int, G4ParticleDefinition * >::Map G4PTblEncodingDictionary
static G4bool IsIon(const G4ParticleDefinition *)
Definition: G4IonTable.cc:1089
#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:1305
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
void DestroyWorkerG4ParticleTable()
#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:129
G4bool contains(const G4ParticleDefinition *particle) const
G4int G4Mutex
Definition: G4Threading.hh:173
static G4ParticleTable * GetParticleTable()
static G4ThreadLocal G4PTblDictionary * fDictionary
void clear()
Definition: G4IonTable.cc:1287
void DestroyWorkerG4IonTable()
Definition: G4IonTable.cc:214
#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