Geant4  10.00.p03
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 79155 2014-02-19 15:27:31Z 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 //
50 
51 #include "globals.hh"
52 #include "G4ios.hh"
53 #include "G4ParticleTable.hh"
54 #include "G4UImessenger.hh"
55 #include "G4ParticleMessenger.hh"
56 #include "G4IonTable.hh"
57 #include "G4StateManager.hh"
58 
59 // These fields should be thread local or thread private. For a singleton
60 // class, we can change any member field as static without any problem
61 // because there is only one instance. Then we are allowed to add
62 // "G4ThreadLocal".
63 //
68 
69 // This field should be thread private. However, we have to keep one copy
70 // of the ion table pointer. So we change all important fields of G4IonTable
71 // to the thread local variable.
72 //
74 
75 
76 // These shadow pointers are used by each worker thread to copy the content
77 // from the master thread.
78 //
83 
84 // Static class variable: ptr to single instance of class
86 
87 #ifdef G4MULTITHREADED
88 // Lock for particle table accesses.
89 //
90 G4Mutex G4ParticleTable::particleTableMutex = G4MUTEX_INITIALIZER;
91 G4int G4ParticleTable::lockCount = 0;
92 #endif
93 
96 {
97  static G4ParticleTable theParticleTable;
98  if (!fgParticleTable){
99  fgParticleTable = &theParticleTable;
100  }
101 
102  // Here we initialize all thread private data members.
103  //
105 
106  return fgParticleTable;
107 }
108 
111  :verboseLevel(1),
112  noName(" "),
113  readyToUse(false),
114  genericIon(NULL)
115 {
117 
118  // Set up the shadow pointer used by worker threads.
119  //
120  if (fDictionaryShadow == 0)
121  {
123  }
124 
126 
127  // Set up the shadow pointer used by worker threads.
128  //
129  if (fIteratorShadow == 0)
130  {
132  }
133 
135  // Set up the shadow pointer used by worker threads.
136  //
137  if (fEncodingDictionaryShadow == 0)
138  {
140  }
141 
142 
143  // Ion Table
144  fIonTable = new G4IonTable();
145 
146 }
147 
148 // This method is similar to the constructor. It is used by each worker
149 // thread to achieve the partial effect as that of the master thread.
150 // Here we initialize all thread private data members.
151 //
153 {
154  G4Exception("G4ParticleTable::SlaveG4ParticleTable()","G4MT0000",FatalException,"Obsolete");
155 }
156 
158 {
159  // The iterator for the shadow particle table is not sharable.
160  //
161 #ifdef G4MULTITHREADED
162  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex);
163  G4ParticleTable::lockCount++;
164 #endif
165  if(fDictionary == 0) {
166  fDictionary = new G4PTblDictionary();
167  } else {
168  fDictionary->clear();
169  }
170 
171  if(fEncodingDictionary == 0){
173  } else {
174  fEncodingDictionary->clear();
175  }
176 
177  fIteratorShadow->reset(false);
178  while( (*fIteratorShadow)() )
179  {
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 
197 // Do we need DestroySlaveG4ParticleTable()?
198 //
201 {
202  readyToUse = false;
203 
204  // remove all items from G4ParticleTable
206 
207  //delete Ion Table
208  if (fIonTable!=0) delete fIonTable;
209  fIonTable =0;
210 
211  // delete dictionary for encoding
212  if (fEncodingDictionary!=0){
213  fEncodingDictionary -> clear();
214  delete fEncodingDictionary;
216  }
217 
218 
219  if(fDictionary){
220  if (fIterator!=0 )delete fIterator;
221  fIterator =0;
222 
223  fDictionary->clear();
224  delete fDictionary;
225  fDictionary =0;
226  }
227 
228  if (fParticleMessenger!=0) delete fParticleMessenger;
230 
231  fgParticleTable =0;
232 
233 }
234 
237  :verboseLevel(1),
238  noName(" "),
239  readyToUse(false)
240 {
241  fParticleMessenger = 0 ;
242 
243  G4Exception("G4ParticleTable::G4ParticleTable()",
244  "PART001", FatalException,
245  "Illegal call of copy constructor for G4ParticleTable");
246  fDictionary = new G4PTblDictionary(*(right.fDictionary));
248 }
249 
252 {
253  if (this != &right) {
254  G4Exception("G4ParticleTable::G4ParticleTable()",
255  "PART001", FatalException,
256  "Illegal call of assignment operator for G4ParticleTable");
257  fDictionary = new G4PTblDictionary(*(right.fDictionary));
259  }
260  return *this;
261 }
262 
265 {
266  if (fParticleMessenger== 0) {
267  //UI messenger
269  }
270  return fParticleMessenger;
271 }
272 
275 {
276  if (fParticleMessenger!= 0) {
277  //UI messenger
278  delete fParticleMessenger;
280  }
281 
282 }
283 
286 {
287  //set readyToUse false
288  readyToUse = false;
289 
290 #ifdef G4VERBOSE
291  if (verboseLevel>1){
292  G4cout << "G4ParticleTable::DeleteAllParticles() " << G4endl;
293  }
294 #endif
295 
296  // delete all particles
297  G4PTblDicIterator *piter = fIterator;
298  piter -> reset();
299  while( (*piter)() ){
300 #ifdef G4VERBOSE
301  if (verboseLevel>2){
302  G4cout << "Delete " << (piter->value())->GetParticleName()
303  << " " << (piter->value()) << G4endl;
304  }
305 #endif
306  delete (piter->value());
307  }
309 }
310 
313 {
314  if (readyToUse) {
315  G4Exception("G4ParticleTable::RemoveAllParticle()",
316  "PART115", JustWarning,
317  "No effects because readyToUse is true.");
318  return;
319  }
320 
321 #ifdef G4VERBOSE
322  if (verboseLevel>1){
323  G4cout << "G4ParticleTable::RemoveAllParticles() " << G4endl;
324  }
325 #endif
326 
327  //remove all contnts in Ion Table
328  if (fIonTable!=0) {
329  fIonTable->clear();
330  }
331 
332  // clear dictionary
333  if (fDictionary) {
334  fDictionary->clear();
335  }
336 }
337 
340 {
341 
342  // check particle name
343  if ((particle == 0) || (GetKey(particle).isNull())) {
344  G4Exception("G4ParticleTable::Insert()",
345  "PART121", FatalException,
346  "Particle witnout name can not be registered.");
347 #ifdef G4VERBOSE
348  if (verboseLevel>1){
349  G4cout << "The particle[Addr:" << particle << "] has no name "<< G4endl;
350  }
351 #endif
352  return 0;
353 
354  }else {
355 
356  if (contains(particle)) {
357 #ifdef G4VERBOSE
358  if (verboseLevel>2){
359  FindParticle(particle) -> DumpTable();
360  }
361 #endif
362  G4String msg = "The particle ";
363  msg += particle->GetParticleName();
364  msg += " has already been registered in the Particle Table ";
365  G4Exception("G4ParticleTable::Insert()",
366  "PART122", FatalException,msg);
368  return particle;
369 
370  } else {
372 
373  // insert into Dictionary
374  pdic->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) );
375 #ifdef G4MULTITHREADED
377  { fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) ); }
378 #endif
379 
381  // insert into EncodingDictionary
382  G4int code = particle->GetPDGEncoding();
383  if (code !=0 ) {
384  pedic->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) );
385 #ifdef G4MULTITHREADED
387  { fEncodingDictionary->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) ); }
388 #endif
389  }
390 
391  // insert it in IonTable if "nucleus"
392  if (fIonTable->IsIon(particle) ){
393  fIonTable->Insert(particle);
394  }
395 
396  // set Verbose Level same as ParticleTable
397  particle->SetVerboseLevel(verboseLevel);
398 
399 #ifdef G4VERBOSE
400  if (verboseLevel>3){
401  G4cout << "The particle "<< particle->GetParticleName()
402  << " is inserted in the ParticleTable " << G4endl;
403  }
404 #endif
405 
406  return particle;
407  }
408  }
409 }
410 
413 {
414  if(!particle) return 0;
415 #ifdef G4MULTITHREADED
418  ed << "Request of removing " << particle->GetParticleName()
419  << " is ignored as it is invoked from a worker thread.";
420  G4Exception("G4ParticleTable::Remove()","PART10117",JustWarning,ed);
421  return 0;
422  }
423 #endif
424  if (readyToUse) {
426  G4ApplicationState currentState = pStateManager->GetCurrentState();
427  if (currentState != G4State_PreInit) {
428  G4String msg = "Request of removing ";
429  msg += particle->GetParticleName();
430  msg += " has No effects other than Pre_Init";
431  G4Exception("G4ParticleTable::Remove()",
432  "PART117", JustWarning, msg);
433  return 0;
434  } else {
435 #ifdef G4VERBOSE
436  if (verboseLevel>0){
437  G4cout << particle->GetParticleName()
438  << " will be removed from the ParticleTable " << G4endl;
439  }
440 #endif
441  }
442  }
443 
444  G4PTblDictionary::iterator it = fDictionaryShadow->find(GetKey(particle));
445  if (it != fDictionaryShadow->end()) {
446  fDictionaryShadow->erase(it);
447  // remove from EncodingDictionary
448  G4int code = particle->GetPDGEncoding();
449  if (code !=0 ) {
451  }
452  } else {
453  return 0;
454  }
455 
456  // remove it from IonTable if "nucleus"
457  if (fIonTable->IsIon(particle) ){
458  fIonTable->Remove(particle);
459  }
460 
461 #ifdef G4VERBOSE
462  if (verboseLevel>3){
463  G4cout << "The particle "<< particle->GetParticleName()
464  << " is removed from the ParticleTable " << G4endl;
465  }
466 #endif
467 
468  return particle;
469 }
470 
472 // NOTE ::
473 // Following FindIon/GetIon methods will be removed in future relases
474 // Use FindIon/GetIon methods of G4IonTable instead
475 //
478 {
479  G4Exception("G4ParticleTable::FindIon()","PART11117",JustWarning,
480  "This method is obsolete and will be dropped from v10.0. Use G4IonTable::FindIon().");
481  CheckReadiness();
482  if (Z<=0) return 0;
483  if (A<Z) return 0;
484  return fIonTable->GetIon(Z, A);
485 }
486 
489 {
490  G4Exception("G4ParticleTable::FindIon()","PART11117",JustWarning,
491  "This method is obsolete and will be dropped from v10.0. Use G4IonTable::FindIon().");
492  CheckReadiness();
493  if (Z<=0) return 0;
494  if (A<Z) return 0;
495  if (E<0.) return 0;
496  return fIonTable->GetIon(Z, A, E);
497 }
498 
501 {
502  G4Exception("G4ParticleTable::GetIon()","PART11117",JustWarning,
503  "This method is obsolete and will be dropped from v10.0. Use G4IonTable::FindIon().");
504  CheckReadiness();
505  if (Z<=0) return 0;
506  if (A-L<Z) return 0;
507  if (L<0) return 0;
508  if (E<0.) return 0;
509  return fIonTable->GetIon(Z, A, L, E);
510 }
511 
513 {
514  G4Exception("G4ParticleTable::GetIon()","PART11117",JustWarning,
515  "This method is obsolete and will be dropped from v10.0. Use G4IonTable::FindIon().");
516  CheckReadiness();
517  if (Z <= 0) return 0;
518  if (A < Z) return 0;
519  if (level < 0) return 0;
520  return fIonTable->GetIon(Z, A, level);
521 }
522 
525 {
526  G4Exception("G4ParticleTable::FindIon()","PART11117",JustWarning,
527  "This method is obsolete and will be dropped from v10.0. Use G4IonTable::FindIon().");
528  CheckReadiness();
529  if (Z<=0) return 0;
530  if (A<Z) return 0;
531  if (E<0.) return 0;
532  return fIonTable->FindIon(Z, A, E);
533 }
534 
537 {
538  G4Exception("G4ParticleTable::FindIon()","PART11117",JustWarning,
539  "This method is obsolete and will be dropped from v10.0. Use G4IonTable::FindIon().");
540  CheckReadiness();
541  if (Z<=0) return 0;
542  if (A-L<Z) return 0;
543  if (L<0) return 0;
544  if (E<0.) return 0;
545  return fIonTable->FindIon(Z, A, L, E);
546 }
548 
551 {
552  CheckReadiness();
553  if ( (index >=0) && (index < entries()) ) {
554  G4PTblDicIterator *piter = fIterator;
555  piter -> reset(false);
556  G4int counter = 0;
557  while( (*piter)() ){
558  if ( counter == index ) return piter->value();
559  counter++;
560  }
561  }
562 #ifdef G4VERBOSE
563  if (verboseLevel>1){
564  G4cout << " G4ParticleTable::GetParticle"
565  << " invalid index (=" << index << ")" << G4endl;
566  }
567 #endif
568  return 0;
569 }
570 
573 {
574  G4ParticleDefinition* aParticle =GetParticle(index);
575  if (aParticle != 0) {
576  return aParticle->GetParticleName();
577  } else {
578  return noName;
579  }
580 }
581 
584 {
585  G4PTblDictionary::iterator it = fDictionary->find(particle_name);
586  if (it != fDictionary->end()) {
587  return (*it).second;
588  } else {
589 #ifdef G4MULTITHREADED
590  G4ParticleDefinition* ptcl = 0;
592  {
593  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex);
594  G4PTblDictionary::iterator its = fDictionaryShadow->find(particle_name);
595  if(its != fDictionaryShadow->end())
596  {
597  fDictionary->insert(*its);
598  ptcl = (*its).second;
599  G4int code = ptcl->GetPDGEncoding();
600  if(code!=0) fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code,ptcl) );
601  }
602  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex);
603  }
604  return ptcl;
605 #else
606  return 0;
607 #endif
608  }
609 }
610 
613 {
614  CheckReadiness();
615  G4String key = GetKey(particle);
616  return FindParticle(key);
617 }
618 
621 {
622  CheckReadiness();
623  // check aPDGEncoding is valid
624  if (aPDGEncoding == 0){
625 #ifdef G4VERBOSE
626  if (verboseLevel>1){
627  G4cout << "PDGEncoding [" << aPDGEncoding << "] is not valid " << G4endl;
628  }
629 #endif
630  return 0;
631  }
632 
634  G4ParticleDefinition* particle =0;
635 
636  G4PTblEncodingDictionary::iterator it = pedic->find(aPDGEncoding );
637  if (it != pedic->end()) {
638  particle = (*it).second;
639  }
640 
641 #ifdef G4MULTITHREADED
642  if(particle == 0 && G4Threading::IsWorkerThread())
643  {
644  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex);
645  G4PTblEncodingDictionary::iterator its = fEncodingDictionaryShadow->find(aPDGEncoding);
646  if(its!=fEncodingDictionaryShadow->end())
647  {
648  particle = (*its).second;
649  fEncodingDictionary->insert(*its);
650  G4String key = GetKey(particle);
651  fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(key,particle) );
652  }
653  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex);
654  }
655 #endif
656 
657 #ifdef G4VERBOSE
658  if ((particle == 0) && (verboseLevel>1) ){
659  G4cout << "CODE:" << aPDGEncoding << " does not exist in ParticleTable " << G4endl;
660  }
661 #endif
662  return particle;
663 }
664 
666 void G4ParticleTable::DumpTable(const G4String &particle_name)
667 {
668  CheckReadiness();
669  if (( particle_name == "ALL" ) || (particle_name == "all")){
670  // dump all particles
671  G4PTblDicIterator *piter = fIterator;
672  piter -> reset();
673  while( (*piter)() ){
674  (piter->value())->DumpTable();
675  }
676  } else {
677  // dump only particle with name of particle_name
679  ptr = FindParticle(particle_name);
680  if ( ptr != 0) {
681  ptr->DumpTable();
682  } else {
683 #ifdef G4VERBOSE
684  if (verboseLevel>1) {
685  G4cout << " G4ParticleTable::DumpTable : "
686  << particle_name << " does not exist in ParticleTable " <<G4endl;
687  }
688 #endif
689  }
690  }
691 }
692 
694 {
695  if(!readyToUse) {
696  G4String msg;
697  msg = "Illegal use of G4ParticleTable : ";
698  msg += " Access to G4ParticleTable for finding a particle or equivalent\n";
699  msg += "operation occurs before G4VUserPhysicsList is instantiated and\n";
700  msg += "assigned to G4RunManager. Such an access is prohibited by\n";
701  msg += "Geant4 version 8.0. To fix this problem, please make sure that\n";
702  msg += "your main() instantiates G4VUserPhysicsList and set it to\n";
703  msg += "G4RunManager before instantiating other user classes such as\n";
704  msg += "G4VUserPrimaryParticleGeneratorAction.";
705  G4Exception("G4ParticleTable::CheckReadiness()",
706  "PART002",FatalException,msg);
707  }
708 }
709 
710 
711 
713 {
714  return fIonTable;
715 }
716 
718 {
719  return fDictionary;
720 }
721 
723 {
724  return fIterator;
725 }
726 
728 {
729  return fEncodingDictionary;
730 }
731 
732 G4bool G4ParticleTable::contains(const G4String& particle_name) const
733 {
734  G4PTblDictionary::iterator it = fDictionaryShadow->find(particle_name);
735  return (it != fDictionaryShadow->end());
736 }
737 
739 {
740  return fDictionary->size();
741 }
742 
744 {
745  return fDictionary->size();
746 }
747 
748 
#define G4MUTEXUNLOCK
Definition: G4Threading.hh:162
void WorkerG4ParticleTable()
void WorkerG4IonTable()
Definition: G4IonTable.cc:152
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
void DumpTable(const G4String &particle_name="ALL")
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
const G4PTblDictionary * GetDictionary() const
G4ParticleDefinition * GetIon(G4int atomicNumber, G4int atomicMass, G4double excitationEnergy)
const G4String & GetParticleName(G4int index) const
G4UImessenger * CreateMessenger()
virtual ~G4ParticleTable()
G4ParticleDefinition * Remove(G4ParticleDefinition *particle)
const G4String & GetKey(const G4ParticleDefinition *particle) const
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:462
void Remove(const G4ParticleDefinition *particle)
Definition: G4IonTable.cc:1314
G4ParticleTableIterator< G4int, G4ParticleDefinition * >::Map G4PTblEncodingDictionary
static G4bool IsIon(const G4ParticleDefinition *)
Definition: G4IonTable.cc:1057
#define G4ThreadLocal
Definition: tls.hh:52
G4ParticleTableIterator< G4String, G4ParticleDefinition * > G4PTblDicIterator
int G4int
Definition: G4Types.hh:78
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:158
const G4String & GetParticleName() const
void Insert(const G4ParticleDefinition *particle)
Definition: G4IonTable.cc:1273
static G4ParticleMessenger * fParticleMessengerShadow
static G4ThreadLocal G4ParticleMessenger * fParticleMessenger
static const G4int L[nN]
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
G4ParticleDefinition * FindIon(G4int atomicNumber, G4int atomicMass, G4double excitationEnergy)
#define G4MUTEXLOCK
Definition: G4Threading.hh:161
G4ApplicationState GetCurrentState() const
void SetVerboseLevel(G4int value)
static const G4double A[nN]
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4bool IsWorkerThread()
Definition: G4Threading.cc:104
G4bool contains(const G4ParticleDefinition *particle) const
G4ParticleDefinition * FindIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:767
G4int G4Mutex
Definition: G4Threading.hh:156
static G4ParticleTable * GetParticleTable()
static G4ThreadLocal G4PTblDictionary * fDictionary
void clear()
Definition: G4IonTable.cc:1255
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
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