ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ParticleTable.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4ParticleTable.cc
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 //
28 // class G4ParticleTable
29 //
30 // Implementation
31 //
32 // History:
33 // modified Apr., 97 H.Kurashige
34 // added fParticleMessenger 14 Nov., 97 H.Kurashige
35 // added GetParticle() 13 Dec., 97 H.Kurashige
36 // added IonTable and ShortLivedTable 27 June, 98 H.Kurashige
37 // modified FindIon 02 Aug., 98 H.Kurashige
38 // added dictionary for encoding 24 Sep., 98 H.Kurashige
39 // fixed bugs in destruction of IonTable 08 Nov.,98 H.Kurashige
40 // commented out G4cout/G4cout in the constructor 10 Nov.,98 H.Kurashige
41 // --------------------------------
42 // modified destructor for STL interface 18 May 1999
43 // fixed some improper codings 08 Apr., 99 H.Kurashige
44 // modified FindIon/GetIon methods 17 AUg., 99 H.Kurashige
45 // implement new version for using STL map instaed of
46 // RW PtrHashedDictionary 28 Oct., 99 H.Kurashige
47 // remove G4ShortLivedTable 25 July, 13 H.Kurashige
48 // remove FindIon/GetIon 25 Sep. 14 H.Kurashige
49 // added support for MuonicAtom September, 17 K.L.Genser
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()
92 {
93  static G4Mutex _instance = G4MUTEX_INITIALIZER;
94  return _instance;
95 }
96 G4int& G4ParticleTable::lockCount()
97 {
98  static G4int _instance = 0;
99  return _instance;
100 }
101 #endif
102 
105 {
106  static G4ParticleTable theParticleTable;
107  if ( fgParticleTable == nullptr ){
108  fgParticleTable = &theParticleTable;
109  }
110 
111  // Here we initialize all thread private data members.
112  //
114 
115  return fgParticleTable;
116 }
117 
120  :verboseLevel(1),
121  noName(" "),
122  readyToUse(false),
123  genericIon(nullptr),
124  genericMuonicAtom(nullptr)
125 {
127 
128  // Set up the shadow pointer used by worker threads.
129  //
130  if (fDictionaryShadow == nullptr) {
132  }
133 
135 
136  // Set up the shadow pointer used by worker threads.
137  //
138  if (fIteratorShadow == nullptr){
140  }
141 
143  // Set up the shadow pointer used by worker threads.
144  //
145  if (fEncodingDictionaryShadow == nullptr){
147  }
148 
149  // Ion Table
150  fIonTable = new G4IonTable();
151 
152 }
153 
154 // This method is similar to the constructor. It is used by each worker
155 // thread to achieve the partial effect as that of the master thread.
156 // Here we initialize all thread private data members.
157 //
159 {
160  G4Exception("G4ParticleTable::SlaveG4ParticleTable()","G4MT0000",FatalException,"Obsolete");
161 }
162 
164 {
165  // The iterator for the shadow particle table is not sharable.
166  //
167 #ifdef G4MULTITHREADED
168  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
169  G4ParticleTable::lockCount()++;
170 #endif
171  if(fDictionary == nullptr) {
172  fDictionary = new G4PTblDictionary();
173  } else {
174  fDictionary->clear();
175  }
176 
177  if(fEncodingDictionary == nullptr){
179  } else {
180  fEncodingDictionary->clear();
181  }
182 
183  fIteratorShadow->reset(false);
184  while( (*fIteratorShadow)() ) { // Loop checking, 09.08.2015, K.Kurashige
186  fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) );
187  G4int code = particle->GetPDGEncoding();
188  if (code !=0 ) {
189  fEncodingDictionary->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) );
190  }
191  }
193 
194 #ifdef G4MULTITHREADED
195  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
196 #endif
197 
199 
200 }
201 
204 {
205  readyToUse = false;
206 
207  // remove all items from G4ParticleTable
209 
210  //delete Ion Table
211  if (fIonTable != nullptr) delete fIonTable;
212  fIonTable = nullptr;
213 
214  // delete dictionary for encoding
215  if (fEncodingDictionary != nullptr){
217  delete fEncodingDictionary;
218  fEncodingDictionary = nullptr;
219  }
220 
221  if( fDictionary != nullptr){
222  if (fIterator != nullptr )delete fIterator;
223  fIterator = nullptr;
224 
225  fDictionary->clear();
226  delete fDictionary;
227  fDictionary =nullptr;
228  }
229 
230  if ( fParticleMessenger != nullptr) delete fParticleMessenger;
231  fParticleMessenger = nullptr;
232 
233  fgParticleTable = nullptr;
234 
235  G4ParticleDefinition::Clean(); // Delete sub-instance static data
236 }
237 
240 {
241  //delete Ion Table in worker thread
242  if (fIonTable != nullptr) fIonTable->DestroyWorkerG4IonTable();
243 
244  // delete dictionary for encoding
245  if (fEncodingDictionary != nullptr){
247  delete fEncodingDictionary;
248  fEncodingDictionary = nullptr;
249  }
250 
251  if( fDictionary != nullptr){
252  if (fIterator != nullptr )delete fIterator;
253  fIterator = nullptr;
254 
255  fDictionary->clear();
256  delete fDictionary;
257  fDictionary = nullptr;
258  }
259 
260  if (fParticleMessenger != nullptr) delete fParticleMessenger;
261  fParticleMessenger = nullptr;
262 }
263 
266  :verboseLevel(1),
267  noName(" "),
268  readyToUse(false)
269 {
270  G4Exception("G4ParticleTable::G4ParticleTable()",
271  "PART001", FatalException,
272  "Illegal call of copy constructor for G4ParticleTable");
273  fParticleMessenger = nullptr ;
274  fDictionary = nullptr;
275  fIterator = nullptr;
276 }
277 
280 {
281  if (this != &right) {
282  G4Exception("G4ParticleTable::G4ParticleTable()",
283  "PART001", FatalException,
284  "Illegal call of assignment operator for G4ParticleTable");
285  }
286  return *this;
287 }
288 
291 {
292  if (fParticleMessenger == nullptr) {
293  //UI messenger
295  }
296  return fParticleMessenger;
297 }
298 
301 {
302  if (fParticleMessenger != nullptr) {
303  //UI messenger
304  delete fParticleMessenger;
305  fParticleMessenger = nullptr;
306  }
307 
308 }
309 
312 {
313  //set readyToUse false
314  readyToUse = false;
315 
316 #ifdef G4VERBOSE
317  if (verboseLevel>1){
318  G4cout << "G4ParticleTable::DeleteAllParticles() " << G4endl;
319  }
320 #endif
321 
322  // delete all particles
324  piter -> reset(false);
325  while( (*piter)() ){// Loop checking, 09.08.2015, K.Kurashige
326 #ifdef G4VERBOSE
327  if (verboseLevel>2){
328  G4cout << "Delete " << (piter->value())->GetParticleName()
329  << " " << (piter->value()) << G4endl;
330  }
331 #endif
332  delete (piter->value());
333  }
335 }
336 
339 {
340  if (readyToUse) {
341  G4Exception("G4ParticleTable::RemoveAllParticle()",
342  "PART115", JustWarning,
343  "No effects because readyToUse is true.");
344  return;
345  }
346 
347 #ifdef G4VERBOSE
348  if (verboseLevel>1){
349  G4cout << "G4ParticleTable::RemoveAllParticles() " << G4endl;
350  }
351 #endif
352 
353  //remove all contnts in Ion Table
354  if (fIonTable != nullptr) {
355  fIonTable->clear();
356  }
357 
358  // clear dictionary
359  if (fDictionary != nullptr) {
360  fDictionary->clear();
361  }
362 }
363 
366 {
367 
368  // check particle name
369  if ((particle == nullptr) || (GetKey(particle).isNull())) {
370  G4Exception("G4ParticleTable::Insert()",
371  "PART121", FatalException,
372  "Particle witnout name can not be registered.");
373 #ifdef G4VERBOSE
374  if (verboseLevel>1){
375  G4cout << "The particle[Addr:" << particle << "] has no name "<< G4endl;
376  }
377 #endif
378  return nullptr;
379 
380  }else {
381 
382  if (contains(particle)) {
383 #ifdef G4VERBOSE
384  if (verboseLevel>2){
385  FindParticle(particle) -> DumpTable();
386  }
387 #endif
388  G4String msg = "The particle ";
389  msg += particle->GetParticleName();
390  msg += " has already been registered in the Particle Table ";
391  G4Exception("G4ParticleTable::Insert()",
392  "PART122", FatalException,msg);
394  return particle;
395 
396  } else {
398 
399  // insert into Dictionary
400  pdic->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) );
401 #ifdef G4MULTITHREADED
403  { fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle) ); }
404 #endif
405 
407  // insert into EncodingDictionary
408  G4int code = particle->GetPDGEncoding();
409  if (code !=0 ) {
410  pedic->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) );
411 #ifdef G4MULTITHREADED
413  { fEncodingDictionary->insert( std::pair<G4int, G4ParticleDefinition*>(code ,particle) ); }
414 #endif
415  }
416 
417  // insert it in IonTable if "nucleus"
418  if (fIonTable->IsIon(particle) ){
419  fIonTable->Insert(particle);
420  }
421 
422  // set Verbose Level same as ParticleTable
423  particle->SetVerboseLevel(verboseLevel);
424 
425 #ifdef G4VERBOSE
426  if (verboseLevel>3){
427  G4cout << "The particle "<< particle->GetParticleName()
428  << " is inserted in the ParticleTable " << G4endl;
429  }
430 #endif
431 
432  return particle;
433  }
434  }
435 }
436 
439 {
440  if( particle == nullptr) return nullptr;
441 #ifdef G4MULTITHREADED
444  ed << "Request of removing " << particle->GetParticleName()
445  << " is ignored as it is invoked from a worker thread.";
446  G4Exception("G4ParticleTable::Remove()","PART10117",JustWarning,ed);
447  return nullptr;
448  }
449 #endif
450  if (readyToUse) {
452  G4ApplicationState currentState = pStateManager->GetCurrentState();
453  if (currentState != G4State_PreInit) {
454  G4String msg = "Request of removing ";
455  msg += particle->GetParticleName();
456  msg += " has No effects other than Pre_Init";
457  G4Exception("G4ParticleTable::Remove()",
458  "PART117", JustWarning, msg);
459  return nullptr;
460  } else {
461 #ifdef G4VERBOSE
462  if (verboseLevel>0){
463  G4cout << particle->GetParticleName()
464  << " will be removed from the ParticleTable " << G4endl;
465  }
466 #endif
467  }
468  }
469 
470  G4PTblDictionary::iterator it = fDictionaryShadow->find(GetKey(particle));
471  if (it != fDictionaryShadow->end()) {
472  fDictionaryShadow->erase(it);
473  // remove from EncodingDictionary
474  G4int code = particle->GetPDGEncoding();
475  if (code != 0 ) {
477  }
478  } else {
479  return nullptr;
480  }
481 
482  // remove it from IonTable if "nucleus"
483  if (fIonTable->IsIon(particle) ){
484  fIonTable->Remove(particle);
485  }
486 
487 #ifdef G4VERBOSE
488  if (verboseLevel>3){
489  G4cout << "The particle "<< particle->GetParticleName()
490  << " is removed from the ParticleTable " << G4endl;
491  }
492 #endif
493 
494  return particle;
495 }
496 
497 
500 {
501  CheckReadiness();
502  if ( (index >=0) && (index < entries()) ) {
504  piter -> reset(false);
505  G4int counter = 0;
506  while( (*piter)() ){ // Loop checking, 09.08.2015, K.Kurashige
507  if ( counter == index ) return piter->value();
508  counter++;
509  }
510  }
511 #ifdef G4VERBOSE
512  if (verboseLevel>1){
513  G4cout << " G4ParticleTable::GetParticle"
514  << " invalid index (=" << index << ")" << G4endl;
515  }
516 #endif
517  return nullptr;
518 }
519 
522 {
523  G4ParticleDefinition* aParticle =GetParticle(index);
524  if (aParticle != nullptr) {
525  return aParticle->GetParticleName();
526  } else {
527  return noName;
528  }
529 }
530 
533 {
534  G4PTblDictionary::iterator it = fDictionary->find(particle_name);
535  if (it != fDictionary->end()) {
536  return (*it).second;
537  } else {
538 #ifdef G4MULTITHREADED
539  G4ParticleDefinition* ptcl = nullptr;
541  {
542  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
543  G4PTblDictionary::iterator its = fDictionaryShadow->find(particle_name);
544  if(its != fDictionaryShadow->end())
545  {
546  fDictionary->insert(*its);
547  ptcl = (*its).second;
548  G4int code = ptcl->GetPDGEncoding();
549  if(code!=0) fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code,ptcl) );
550  }
551  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
552  }
553  return ptcl;
554 #else
555  return nullptr;
556 #endif
557  }
558 }
559 
562 {
563  CheckReadiness();
564  G4String key = GetKey(particle);
565  return FindParticle(key);
566 }
567 
570 {
571  CheckReadiness();
572  // check aPDGEncoding is valid
573  if (aPDGEncoding == 0){
574 #ifdef G4VERBOSE
575  if (verboseLevel>1){
576  G4cout << "PDGEncoding [" << aPDGEncoding << "] is not valid " << G4endl;
577  }
578 #endif
579  return nullptr;
580  }
581 
583  G4ParticleDefinition* particle = nullptr;
584 
585  G4PTblEncodingDictionary::iterator it = pedic->find(aPDGEncoding );
586  if (it != pedic->end()) {
587  particle = (*it).second;
588  }
589 
590 #ifdef G4MULTITHREADED
591  if(particle == nullptr && G4Threading::IsWorkerThread())
592  {
593  G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
594  G4PTblEncodingDictionary::iterator its = fEncodingDictionaryShadow->find(aPDGEncoding);
595  if(its!=fEncodingDictionaryShadow->end()){
596  particle = (*its).second;
597  fEncodingDictionary->insert(*its);
598  G4String key = GetKey(particle);
599  fDictionary->insert( std::pair<G4String, G4ParticleDefinition*>(key,particle) );
600  }
601  G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
602  }
603 #endif
604 
605 #ifdef G4VERBOSE
606  if ((particle == nullptr) && (verboseLevel>1) ){
607  G4cout << "CODE:" << aPDGEncoding << " does not exist in ParticleTable " << G4endl;
608  }
609 #endif
610  return particle;
611 }
612 
614 void G4ParticleTable::DumpTable(const G4String &particle_name)
615 {
616  CheckReadiness();
617  if (( particle_name == "ALL" ) || (particle_name == "all")){
618  // dump all particles
620  piter -> reset();
621  while( (*piter)() ){// Loop checking, 09.08.2015, K.Kurashige
622  (piter->value())->DumpTable();
623  }
624  } else {
625  // dump only particle with name of particle_name
626  G4ParticleDefinition *ptr = FindParticle(particle_name);
627  if ( ptr != nullptr) {
628  ptr->DumpTable();
629  } else {
630 #ifdef G4VERBOSE
631  if (verboseLevel>1) {
632  G4cout << " G4ParticleTable::DumpTable : "
633  << particle_name << " does not exist in ParticleTable " <<G4endl;
634  }
635 #endif
636  }
637  }
638 }
639 
641 {
642  if(!readyToUse) {
643  G4String msg;
644  msg = "Illegal use of G4ParticleTable : ";
645  msg += " Access to G4ParticleTable for finding a particle or equivalent\n";
646  msg += "operation occurs before G4VUserPhysicsList is instantiated and\n";
647  msg += "assigned to G4RunManager. Such an access is prohibited by\n";
648  msg += "Geant4 version 8.0. To fix this problem, please make sure that\n";
649  msg += "your main() instantiates G4VUserPhysicsList and set it to\n";
650  msg += "G4RunManager before instantiating other user classes such as\n";
651  msg += "G4VUserPrimaryParticleGeneratorAction.";
652  G4Exception("G4ParticleTable::CheckReadiness()",
653  "PART002",FatalException,msg);
654  }
655 }
656 
657 
658 
660 {
661  return fIonTable;
662 }
663 
665 {
666  return fDictionary;
667 }
668 
670 {
671  return fIterator;
672 }
673 
675 {
676  return fEncodingDictionary;
677 }
678 
679 G4bool G4ParticleTable::contains(const G4String& particle_name) const
680 {
681  G4PTblDictionary::iterator it = fDictionaryShadow->find(particle_name);
682  return (it != fDictionaryShadow->end());
683 }
684 
686 {
687  return fDictionary->size();
688 }
689 
691 {
692  return fDictionary->size();
693 }
694 
695