Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/particles/management/src/G4ParticleTable.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 "G4ParticleTable.hh"
 38 
 39 #include "G4IonTable.hh"
 40 #include "G4ParticleMessenger.hh"
 41 #include "G4StateManager.hh"
 42 #include "G4UImessenger.hh"
 43 #include "G4ios.hh"
 44 #include "globals.hh"
 45 
 46 // These fields should be thread local or thread private. For a singleton
 47 // class, we can change any member field as static without any problem
 48 // because there is only one instance. Then we are allowed to add
 49 // "G4ThreadLocal"
 50 //
 51 G4ThreadLocal G4ParticleTable::G4PTblDictionary* G4ParticleTable::fDictionary = nullptr;
 52 G4ThreadLocal G4ParticleTable::G4PTblDicIterator* G4ParticleTable::fIterator = nullptr;
 53 G4ThreadLocal G4ParticleTable::G4PTblEncodingDictionary* G4ParticleTable::fEncodingDictionary =
 54   nullptr;
 55 
 56 // These shadow pointers are used by each worker thread to copy the content
 57 // from the master thread
 58 //
 59 G4ParticleTable::G4PTblDictionary* G4ParticleTable::fDictionaryShadow = nullptr;
 60 G4ParticleTable::G4PTblDicIterator* G4ParticleTable::fIteratorShadow = nullptr;
 61 G4ParticleTable::G4PTblEncodingDictionary* G4ParticleTable::fEncodingDictionaryShadow = nullptr;
 62 
 63 // Static class variable: pointer to single instance of class
 64 //
 65 G4ParticleTable* G4ParticleTable::fgParticleTable = nullptr;
 66 
 67 #ifdef G4MULTITHREADED
 68 // Lock for particle table accesses.
 69 //
 70 G4Mutex& G4ParticleTable::particleTableMutex()
 71 {
 72   static G4Mutex _instance = G4MUTEX_INITIALIZER;
 73   return _instance;
 74 }
 75 G4int& G4ParticleTable::lockCount()
 76 {
 77   static G4int _instance = 0;
 78   return _instance;
 79 }
 80 #endif
 81 
 82 G4ParticleTable* G4ParticleTable::GetParticleTable()
 83 {
 84   if (fgParticleTable == nullptr) {
 85     static G4ParticleTable theParticleTable;
 86     fgParticleTable = &theParticleTable;
 87   }
 88 
 89   // Here we initialize all thread private data members.
 90   //
 91   if (fDictionary == nullptr) fgParticleTable->WorkerG4ParticleTable();
 92 
 93   return fgParticleTable;
 94 }
 95 
 96 G4ParticleTable::G4ParticleTable()
 97 {
 98   fDictionary = new G4PTblDictionary();
 99 
100   // Set up the shadow pointer used by worker threads
101   //
102   if (fDictionaryShadow == nullptr) {
103     fDictionaryShadow = fDictionary;
104   }
105 
106   fIterator = new G4PTblDicIterator(*fDictionary);
107 
108   // Set up the shadow pointer used by worker threads
109   //
110   if (fIteratorShadow == nullptr) {
111     fIteratorShadow = fIterator;
112   }
113 
114   fEncodingDictionary = new G4PTblEncodingDictionary();
115   // Set up the shadow pointer used by worker threads
116   //
117   if (fEncodingDictionaryShadow == nullptr) {
118     fEncodingDictionaryShadow = fEncodingDictionary;
119   }
120 
121   // Ion Table
122   //
123   fIonTable = new G4IonTable();
124   fParticleMessenger = nullptr;
125 }
126 
127 // This method is similar to the constructor. It is used by each worker
128 // thread to achieve the partial effect as that of the master thread.
129 // Here we initialize all thread private data members
130 void G4ParticleTable::WorkerG4ParticleTable()
131 {
132   // The iterator for the shadow particle table is not sharable.
133   //
134 #ifdef G4MULTITHREADED
135   G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
136   G4ParticleTable::lockCount()++;
137 #endif
138   if (fDictionary == nullptr) {
139     fDictionary = new G4PTblDictionary();
140   }
141   else {
142     fDictionary->clear();
143   }
144 
145   if (fEncodingDictionary == nullptr) {
146     fEncodingDictionary = new G4PTblEncodingDictionary();
147   }
148   else {
149     fEncodingDictionary->clear();
150   }
151 
152   fIteratorShadow->reset(false);
153   while ((*fIteratorShadow)())  // Loop checking, 09.08.2015, K.Kurashige
154   {
155     G4ParticleDefinition* particle = fIteratorShadow->value();
156     fDictionary->insert(std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle));
157     G4int code = particle->GetPDGEncoding();
158     if (code != 0) {
159       fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code, particle));
160     }
161   }
162   fIterator = new G4PTblDicIterator(*fDictionary);
163 
164 #ifdef G4MULTITHREADED
165   G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
166 #endif
167 
168   fIonTable->WorkerG4IonTable();
169 }
170 
171 G4ParticleTable::~G4ParticleTable()
172 {
173   readyToUse = false;
174 
175   // remove all items from G4ParticleTable
176   RemoveAllParticles();
177 
178   // delete Ion Table
179   delete fIonTable;
180   fIonTable = nullptr;
181 
182   // delete dictionary for encoding
183   if (fEncodingDictionary != nullptr) {
184     fEncodingDictionary->clear();
185     delete fEncodingDictionary;
186     fEncodingDictionary = nullptr;
187   }
188 
189   if (fDictionary != nullptr) {
190     delete fIterator;
191     fIterator = nullptr;
192 
193     fDictionary->clear();
194     delete fDictionary;
195     fDictionary = nullptr;
196   }
197 
198   delete fParticleMessenger;
199   fParticleMessenger = nullptr;
200 
201   fgParticleTable = nullptr;
202 
203   G4ParticleDefinition::Clean();  // Delete sub-instance static data
204 }
205 
206 void G4ParticleTable::DestroyWorkerG4ParticleTable()
207 {
208   // delete Ion Table in worker thread
209   if (fIonTable != nullptr) fIonTable->DestroyWorkerG4IonTable();
210 
211   // delete dictionary for encoding
212   if (fEncodingDictionary != nullptr) {
213     fEncodingDictionary->clear();
214     delete fEncodingDictionary;
215     fEncodingDictionary = nullptr;
216   }
217 
218   if (fDictionary != nullptr) {
219     delete fIterator;
220     fIterator = nullptr;
221 
222     fDictionary->clear();
223     delete fDictionary;
224     fDictionary = nullptr;
225   }
226 }
227 
228 G4UImessenger* G4ParticleTable::CreateMessenger()
229 {
230   if (fParticleMessenger == nullptr) {
231     // UI messenger
232     fParticleMessenger = new G4ParticleMessenger(this);
233   }
234   return fParticleMessenger;
235 }
236 
237 void G4ParticleTable::DeleteAllParticles()
238 {
239   // set readyToUse false
240   readyToUse = false;
241 
242 #ifdef G4VERBOSE
243   if (verboseLevel > 1) {
244     G4cout << "G4ParticleTable::DeleteAllParticles() " << G4endl;
245   }
246 #endif
247 
248   // delete all particles
249   G4PTblDicIterator* piter = fIterator;
250   piter->reset(false);
251   while ((*piter)())  // Loop checking, 09.08.2015, K.Kurashige
252   {
253 #ifdef G4VERBOSE
254     if (verboseLevel > 2) {
255       G4cout << "Delete " << (piter->value())->GetParticleName() << " " << (piter->value())
256              << G4endl;
257     }
258 #endif
259     delete (piter->value());
260   }
261   RemoveAllParticles();
262 }
263 
264 void G4ParticleTable::RemoveAllParticles()
265 {
266   if (readyToUse) {
267     G4Exception("G4ParticleTable::RemoveAllParticle()", "PART115", JustWarning,
268                 "No effects because readyToUse is true.");
269     return;
270   }
271 
272 #ifdef G4VERBOSE
273   if (verboseLevel > 1) {
274     G4cout << "G4ParticleTable::RemoveAllParticles() " << G4endl;
275   }
276 #endif
277 
278   // remove all contents in Ion Table
279   if (fIonTable != nullptr) {
280     fIonTable->clear();
281   }
282 
283   // clear dictionary
284   if (fDictionary != nullptr) {
285     fDictionary->clear();
286   }
287 }
288 
289 G4ParticleDefinition* G4ParticleTable::Insert(G4ParticleDefinition* particle)
290 {
291   // check particle name
292   if ((particle == nullptr) || (GetKey(particle).empty())) {
293     G4Exception("G4ParticleTable::Insert()", "PART121", FatalException,
294                 "Particle witnout name can not be registered.");
295 #ifdef G4VERBOSE
296     if (verboseLevel > 1) {
297       G4cout << "The particle[Addr:" << particle << "] has no name " << G4endl;
298     }
299 #endif
300     return nullptr;
301   }
302 
303   if (contains(particle)) {
304 #ifdef G4VERBOSE
305     if (verboseLevel > 2) {
306       FindParticle(particle)->DumpTable();
307     }
308 #endif
309     G4String msg = "The particle ";
310     msg += particle->GetParticleName();
311     msg += "  has already been registered in the Particle Table ";
312     G4Exception("G4ParticleTable::Insert()", "PART122", FatalException, msg);
313 
314     return particle;
315   }
316 
317   G4PTblDictionary* pdic = fDictionaryShadow;
318 
319   // insert into Dictionary
320   pdic->insert(std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle));
321 #ifdef G4MULTITHREADED
322   if (G4Threading::IsWorkerThread()) {
323     fDictionary->insert(std::pair<G4String, G4ParticleDefinition*>(GetKey(particle), particle));
324   }
325 #endif
326 
327   G4PTblEncodingDictionary* pedic = fEncodingDictionaryShadow;
328 
329   // insert into EncodingDictionary
330   G4int code = particle->GetPDGEncoding();
331   if (code != 0) {
332     pedic->insert(std::pair<G4int, G4ParticleDefinition*>(code, particle));
333 #ifdef G4MULTITHREADED
334     if (G4Threading::IsWorkerThread()) {
335       fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code, particle));
336     }
337 #endif
338   }
339 
340   // insert it in IonTable if "nucleus"
341   if (fIonTable->IsIon(particle)) {
342     fIonTable->Insert(particle);
343   }
344 
345   // set Verbose Level same as ParticleTable
346   particle->SetVerboseLevel(verboseLevel);
347 
348 #ifdef G4VERBOSE
349   if (verboseLevel > 3) {
350     G4cout << "The particle " << particle->GetParticleName() << " is inserted in the ParticleTable "
351            << G4endl;
352   }
353 #endif
354   return particle;
355 }
356 
357 G4ParticleDefinition* G4ParticleTable::Remove(G4ParticleDefinition* particle)
358 {
359   if (particle == nullptr) return nullptr;
360 #ifdef G4MULTITHREADED
361   if (G4Threading::IsWorkerThread()) {
362     G4ExceptionDescription ed;
363     ed << "Request of removing " << particle->GetParticleName()
364        << " is ignored as it is invoked from a worker thread.";
365     G4Exception("G4ParticleTable::Remove()", "PART10117", JustWarning, ed);
366     return nullptr;
367   }
368 #endif
369   if (readyToUse) {
370     G4StateManager* pStateManager = G4StateManager::GetStateManager();
371     G4ApplicationState currentState = pStateManager->GetCurrentState();
372     if (currentState != G4State_PreInit) {
373       G4String msg = "Request of removing ";
374       msg += particle->GetParticleName();
375       msg += " has No effects other than Pre_Init";
376       G4Exception("G4ParticleTable::Remove()", "PART117", JustWarning, msg);
377       return nullptr;
378     }
379 
380 #ifdef G4VERBOSE
381     if (verboseLevel > 0) {
382       G4cout << particle->GetParticleName() << " will be removed from the ParticleTable " << G4endl;
383     }
384 #endif
385   }
386 
387   auto it = fDictionaryShadow->find(GetKey(particle));
388   if (it != fDictionaryShadow->end()) {
389     fDictionaryShadow->erase(it);
390     // remove from EncodingDictionary
391     G4int code = particle->GetPDGEncoding();
392     if (code != 0) {
393       fEncodingDictionaryShadow->erase(fEncodingDictionaryShadow->find(code));
394     }
395   }
396   else {
397     return nullptr;
398   }
399 
400   // remove it from IonTable if "nucleus"
401   if (fIonTable->IsIon(particle)) {
402     fIonTable->Remove(particle);
403   }
404 
405 #ifdef G4VERBOSE
406   if (verboseLevel > 3) {
407     G4cout << "The particle " << particle->GetParticleName()
408            << " is removed from the ParticleTable " << G4endl;
409   }
410 #endif
411 
412   return particle;
413 }
414 
415 G4ParticleDefinition* G4ParticleTable::GetParticle(G4int index) const
416 {
417   CheckReadiness();
418   if ((index >= 0) && (index < entries())) {
419     G4PTblDicIterator* piter = fIterator;
420     piter->reset(false);
421     G4int counter = 0;
422     while ((*piter)())  // Loop checking, 09.08.2015, K.Kurashige
423     {
424       if (counter == index) return piter->value();
425       ++counter;
426     }
427   }
428 #ifdef G4VERBOSE
429   if (verboseLevel > 1) {
430     G4cout << " G4ParticleTable::GetParticle"
431            << " invalid index (=" << index << ")" << G4endl;
432   }
433 #endif
434   return nullptr;
435 }
436 
437 const G4String& G4ParticleTable::GetParticleName(G4int index) const
438 {
439   G4ParticleDefinition* aParticle = GetParticle(index);
440   if (aParticle != nullptr) {
441     return aParticle->GetParticleName();
442   }
443 
444   return noName;
445 }
446 
447 G4ParticleDefinition* G4ParticleTable::FindParticle(const G4String& particle_name)
448 {
449   auto it = fDictionary->find(particle_name);
450   if (it != fDictionary->end()) {
451     return (*it).second;
452   }
453 
454 #ifdef G4MULTITHREADED
455   G4ParticleDefinition* ptcl = nullptr;
456   if (G4Threading::IsWorkerThread()) {
457     G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
458     auto its = fDictionaryShadow->find(particle_name);
459     if (its != fDictionaryShadow->end()) {
460       fDictionary->insert(*its);
461       ptcl = (*its).second;
462       G4int code = ptcl->GetPDGEncoding();
463       if (code != 0)
464         fEncodingDictionary->insert(std::pair<G4int, G4ParticleDefinition*>(code, ptcl));
465     }
466     G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
467   }
468   return ptcl;
469 #else
470   return nullptr;
471 #endif
472 }
473 
474 void G4ParticleTable::SelectParticle(const G4String& name)
475 {
476   if (name != selectedName) {
477     const G4ParticleDefinition* part = FindParticle(name);
478     if (part != nullptr) {
479 #ifdef G4MULTITHREADED
480       G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
481 #endif
482       selectedParticle = part;
483       selectedName = name;
484 #ifdef G4MULTITHREADED
485       G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
486 #endif
487     }
488   }
489 }
490 
491 G4ParticleDefinition* G4ParticleTable::FindParticle(const G4ParticleDefinition* particle)
492 {
493   CheckReadiness();
494   G4String key = GetKey(particle);
495   return FindParticle(key);
496 }
497 
498 G4ParticleDefinition* G4ParticleTable::FindParticle(G4int aPDGEncoding)
499 {
500   CheckReadiness();
501   // check aPDGEncoding is valid
502   if (aPDGEncoding == 0) {
503 #ifdef G4VERBOSE
504     if (verboseLevel > 1) {
505       G4cout << "PDGEncoding  [" << aPDGEncoding << "] is not valid " << G4endl;
506     }
507 #endif
508     return nullptr;
509   }
510 
511   G4PTblEncodingDictionary* pedic = fEncodingDictionary;
512   G4ParticleDefinition* particle = nullptr;
513 
514   if (pedic != nullptr) {
515     auto it = pedic->find(aPDGEncoding);
516     if (it != pedic->end()) {
517       particle = (*it).second;
518     }
519   }
520 
521 #ifdef G4MULTITHREADED
522   if (particle == nullptr && G4Threading::IsWorkerThread()) {
523     G4MUTEXLOCK(&G4ParticleTable::particleTableMutex());
524     auto its = fEncodingDictionaryShadow->find(aPDGEncoding);
525     if (its != fEncodingDictionaryShadow->end()) {
526       particle = (*its).second;
527       fEncodingDictionary->insert(*its);
528       G4String key = GetKey(particle);
529       fDictionary->insert(std::pair<G4String, G4ParticleDefinition*>(key, particle));
530     }
531     G4MUTEXUNLOCK(&G4ParticleTable::particleTableMutex());
532   }
533 #endif
534 
535 #ifdef G4VERBOSE
536   if ((particle == nullptr) && (verboseLevel > 1)) {
537     G4cout << "CODE:" << aPDGEncoding << " does not exist in ParticleTable " << G4endl;
538   }
539 #endif
540   return particle;
541 }
542 
543 void G4ParticleTable::DumpTable(const G4String& particle_name)
544 {
545   CheckReadiness();
546   if ((particle_name == "ALL") || (particle_name == "all")) {
547     // dump all particles
548     G4PTblDicIterator* piter = fIterator;
549     piter->reset();
550     while ((*piter)())  // Loop checking, 09.08.2015, K.Kurashige
551     {
552       (piter->value())->DumpTable();
553     }
554   }
555   else {
556     // dump only particle with name of particle_name
557     G4ParticleDefinition* ptr = FindParticle(particle_name);
558     if (ptr != nullptr) {
559       ptr->DumpTable();
560     }
561     else {
562 #ifdef G4VERBOSE
563       if (verboseLevel > 1) {
564         G4cout << " G4ParticleTable::DumpTable : " << particle_name
565                << " does not exist in ParticleTable " << G4endl;
566       }
567 #endif
568     }
569   }
570 }
571 
572 void G4ParticleTable::CheckReadiness() const
573 {
574   if (!readyToUse) {
575     G4String msg;
576     msg = "Illegal use of G4ParticleTable :\n";
577     msg += "Access to G4ParticleTable for finding a particle or equivalent\n";
578     msg += "operation occurs before G4VUserPhysicsList is instantiated and\n";
579     msg += "assigned to G4RunManager. Such an access is prohibited since\n";
580     msg += "Geant4 version 8.0. To fix this problem, please make sure that\n";
581     msg += "your main() instantiates G4VUserPhysicsList and set it to\n";
582     msg += "G4RunManager before instantiating other user classes such as\n";
583     msg += "G4VUserPrimaryParticleGeneratorAction.";
584     G4Exception("G4ParticleTable::CheckReadiness()", "PART002", FatalException, msg);
585   }
586 }
587 
588 G4IonTable* G4ParticleTable::GetIonTable() const
589 {
590   return fIonTable;
591 }
592 
593 const G4ParticleTable::G4PTblDictionary* G4ParticleTable::GetDictionary() const
594 {
595   return fDictionary;
596 }
597 
598 G4ParticleTable::G4PTblDicIterator* G4ParticleTable::GetIterator() const
599 {
600   return fIterator;
601 }
602 
603 const G4ParticleTable::G4PTblEncodingDictionary* G4ParticleTable::GetEncodingDictionary() const
604 {
605   return fEncodingDictionary;
606 }
607 
608 G4bool G4ParticleTable::contains(const G4String& particle_name) const
609 {
610   auto it = fDictionaryShadow->find(particle_name);
611   return (it != fDictionaryShadow->cend());
612 }
613 
614 G4int G4ParticleTable::entries() const
615 {
616   return (G4int)fDictionary->size();
617 }
618 
619 G4int G4ParticleTable::size() const
620 {
621   return (G4int)fDictionary->size();
622 }
623