Geant4  10.02
G4IonTable.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: G4IonTable.cc 94421 2015-11-16 08:22:56Z gcosmo $
28 //
29 //
30 // --------------------------------------------------------------
31 // GEANT 4 class implementation file
32 //
33 // History: first implementation, based on object model of
34 // 27 June 1998 H.Kurashige
35 // ---------------------------------------------------------------
36 // modified GetIon 02 Aug., 98 H.Kurashige
37 // added Remove() 06 Nov.,98 H.Kurashige
38 // use G4NucleiPropoerties to get nuceli Mass 17 Nov.,98 H.Kurashige
39 // use G4GenericIon for process List
40 // modify fomula of Ion mass 09 Dec., 98 H.Kurashige
41 // -----
42 // Modified GetIon methods 17 Aug. 99 H.Kurashige
43 // New design using G4VIsotopeTable 5 Oct. 99 H.Kurashige
44 // Modified Element Name for Z>103 06 Apr. 01 H.Kurashige
45 // Remove test of cuts in SetCuts 16 Jan 03 V.Ivanchenko
46 
47 #include <iostream>
48 #include <iomanip>
49 #include <sstream>
50 
51 #include "G4ios.hh"
52 #include "G4Threading.hh"
53 
54 #include "G4IonTable.hh"
55 #include "G4PhysicalConstants.hh"
56 #include "G4SystemOfUnits.hh"
57 #include "G4ParticleTable.hh"
58 #include "G4StateManager.hh"
59 #include "G4Ions.hh"
60 #include "G4UImanager.hh"
61 #include "G4NucleiProperties.hh"
63 
64 #include "G4IsotopeProperty.hh"
65 #include "G4VIsotopeTable.hh"
66 #include "G4NuclideTable.hh"
67 
68 // It is very important for multithreaded Geant4 to keep only one copy of the
69 // particle table pointer and the ion table pointer. However, we try to let
70 // each worker thread hold its own copy of the particle dictionary and the
71 // ion list. This implementation is equivalent to make the ion table thread
72 // private. The two shadow ponters are used by each worker thread to copy the
73 // content from the master thread.
74 //
76 G4ThreadLocal std::vector<G4VIsotopeTable*> *G4IonTable::fIsotopeTableList = 0;
78 std::vector<G4VIsotopeTable*> *G4IonTable::fIsotopeTableListShadow = 0;
80 
81 namespace lightions {
82  static const G4ParticleDefinition* p_proton=0;
84  static const G4ParticleDefinition* p_triton=0;
85  static const G4ParticleDefinition* p_alpha=0;
86  static const G4ParticleDefinition* p_He3=0;
87  void Init() {
88  if ( p_proton ) return;
89  p_proton = G4ParticleTable::GetParticleTable()-> FindParticle("proton"); // proton
90  p_deuteron = G4ParticleTable::GetParticleTable()-> FindParticle("deuteron"); // deuteron
91  p_triton = G4ParticleTable::GetParticleTable()-> FindParticle("triton"); // tritoon
92  p_alpha = G4ParticleTable::GetParticleTable()-> FindParticle("alpha"); // alpha
93  p_He3 = G4ParticleTable::GetParticleTable()-> FindParticle("He3"); // He3
94  }
95 }
96 
97 namespace antilightions {
98  static const G4ParticleDefinition* p_proton=0;
101  static const G4ParticleDefinition* p_alpha=0;
102  static const G4ParticleDefinition* p_He3=0;
103  void Init() {
104  if ( p_proton ) return;
105  p_proton = G4ParticleTable::GetParticleTable()-> FindParticle("anti_proton"); // proton
106  p_deuteron = G4ParticleTable::GetParticleTable()-> FindParticle("anti_deuteron"); // deuteron
107  p_triton = G4ParticleTable::GetParticleTable()-> FindParticle("anti_triton"); // tritoon
108  p_alpha = G4ParticleTable::GetParticleTable()-> FindParticle("anti_alpha"); // alpha
109  p_He3 = G4ParticleTable::GetParticleTable()-> FindParticle("anti_He3"); // He3
110  }
111 }
112 
113 #ifdef G4MULTITHREADED
114 G4Mutex G4IonTable::ionTableMutex = G4MUTEX_INITIALIZER;
115 #endif
116 
119  : pNuclideTable(0),
120  isIsomerCreated(false),
121  n_error(0)
122 {
123  fIonList = new G4IonList();
124 
125  // Set up the shadow pointer used by worker threads.
126  //
127  if (fIonListShadow == 0)
128  {
130  }
131 
132  fIsotopeTableList = new std::vector<G4VIsotopeTable*>;
133 
134  // Set up the shadow pointer used by worker threads.
135  //
136  if (fIsotopeTableListShadow == 0)
137  {
139  }
140 
143 }
144 
145 // This method is used by each worker thread to copy the content
146 // from the master thread.
147 //
149 {
150 G4Exception("G4IonTable::SlaveG4ParticleTable()","G4MT0000",FatalException,"Obsolete");
151 }
152 
154 {
155  if( fIonList == 0 )
156  { fIonList = new G4IonList(); }
157  else
158  { fIonList->clear(); }
159 
161  for (it = fIonListShadow->begin() ; it != fIonListShadow->end(); it++ ) {
164  fIonList->insert(*it);
165  }
166 
167  // Do not copy Isotoper Table to Worker thread
168  if( fIsotopeTableList == 0 ) {
169  fIsotopeTableList = new std::vector<G4VIsotopeTable*>;
170  for (size_t i = 0; i < fIsotopeTableListShadow->size(); i++){
171  fIsotopeTableList->push_back((*fIsotopeTableListShadow)[i]);
172  }
173  }
174 
177 }
178 
180 {
181  lightions::Init();
183 }
184 
185 
188 {
189  // delete IsotopeTable if exists
190  if (fIsotopeTableList != 0)
191  {
192  for (size_t i = 0; i< fIsotopeTableList->size(); ++i)
193  {
194  G4VIsotopeTable* fIsotopeTable= (*fIsotopeTableList)[i];
195  //delete fIsotopeTable;
196  if( fIsotopeTable != G4NuclideTable::GetNuclideTable() ) delete fIsotopeTable;
197  }
198  fIsotopeTableList->clear();
199  delete fIsotopeTableList;
200  }
202 
203 
204  if (fIonList ==0) return;
205  // remove all contents in the Ion List
206  // No need to delete here because all particles are dynamic objects
207  fIonList->clear();
208 
209  delete fIonList;
210  fIonList =0;
211 }
212 
215 {
216  // delete IsotopeTable if exists
217  if (fIsotopeTableList != 0)
218  {
219  for (size_t i = 0; i< fIsotopeTableList->size(); ++i)
220  {
221  G4VIsotopeTable* fIsotopeTable= (*fIsotopeTableList)[i];
222  //delete fIsotopeTable;
223  if( fIsotopeTable != G4NuclideTable::GetNuclideTable() ) delete fIsotopeTable;
224  }
225  fIsotopeTableList->clear();
226  delete fIsotopeTableList;
227  }
229 
230 
231  if (fIonList ==0) return;
232  // remove all contents in the Ion List
233  // No need to delete here because all particles are dynamic objects
234  fIonList->clear();
235 
236  delete fIonList;
237  fIonList =0;
238 }
239 
240 
242 // -- CreateIon method ------
245 {
247 
248  // check whether GenericIon has processes
249  G4ParticleDefinition* genericIon =
251  G4ProcessManager* pman=0;
252  if (genericIon!=0) pman = genericIon->GetProcessManager();
253  if ((genericIon ==0) || (genericIon->GetParticleDefinitionID() < 0) || (pman==0)){
254 #ifdef G4VERBOSE
255  if (GetVerboseLevel()>1) {
256  G4cout << "G4IonTable::CreateIon() : can not create ion of "
257  << " Z =" << Z << " A = " << A
258  << " because GenericIon is not ready !!" << G4endl;
259  }
260 #endif
261  G4Exception( "G4IonTable::CreateIon()","PART105",
262  JustWarning,
263  "Can not create ions because GenericIon is not ready");
264  return 0;
265  }
266 
267  G4double life = -1.0;
268  G4DecayTable* decayTable =0;
269  G4bool stable = true;
270  G4double mu = 0.0;
271  G4double Eex = 0.0;
272  G4int lvl =0;
273  G4int J=0;
274 
275  const G4IsotopeProperty* fProperty = FindIsotope(Z, A, E);
276  if (fProperty !=0 ){
277  Eex = fProperty->GetEnergy();
278  lvl = fProperty->GetIsomerLevel();
279  J = fProperty->GetiSpin();
280  life = fProperty->GetLifeTime();
281  mu = fProperty->GetMagneticMoment();
282  decayTable = fProperty->GetDecayTable();
283  stable = (life <= 0.) || (decayTable ==0);
284  lvl = fProperty->GetIsomerLevel();
285  if (lvl <0) lvl=9;
286  } else {
287 #ifdef G4VERBOSE
288  if (GetVerboseLevel()>1) {
290  ed << "G4IonTable::CreateIon() : G4IsotopeProperty object was not found for"
291  << " Z = " << Z << " A = " << A << " E = " << E/keV << " (keV).\n"
292  << " Physics quantities such as life are not set for this ion.";
293  G4Exception( "G4IonTable::CreateIon()","PART70105", JustWarning, ed);
294  }
295 #endif
296  // excitation energy
297  Eex = E;
298  // lvl is assigned to 9 temporally
299  if (Eex>0.0) lvl=9;
300  }
301 
302  Eex = G4NuclideTable::Round(Eex);
303  if (Eex==0.0) lvl=0;
304  // ion name
305  G4String name ="";
307  if (lvl==0) name = GetIonName(Z, A, lvl);
308  else name = GetIonName(Z, A, Eex);
309 
310  // PDG encoding
311  G4int encoding = GetNucleusEncoding(Z,A,E,lvl);
312 
313 //G4cout<<"G4IonTable::CreateIon "<<"Z:"<<Z<<" A:"<<A<<" E:"<<E<<" Eex:"<<Eex<<" lvl:"<<lvl<<" name:"<<name<<" code:"<<encoding<<G4endl;
314  // PDG mass
315  G4double mass = GetNucleusMass(Z, A)+ Eex;
316 
317  // PDG charge is set to one of nucleus
318  G4double charge = G4double(Z)*eplus;
319 
320  // create an ion
321  // spin, parity, isospin values are fixed
322 
323  // Request lock for particle table accesses. Some changes are inside
324  // this critical region.
325  //
326 
327  ion = new G4Ions( name, mass, 0.0*MeV, charge,
328  J, +1, 0,
329  0, 0, 0,
330  "nucleus", 0, A, encoding,
331  stable, life, decayTable, false,
332  "generic", 0,
333  Eex, lvl );
334 
335  // Release lock for particle table accesses.
336  //
337 
338  ion->SetPDGMagneticMoment(mu);
339 
340  //No Anti particle registered
341  ion->SetAntiPDGEncoding(0);
342 
343 #ifdef G4VERBOSE
344  if (GetVerboseLevel()>1) {
345  G4cout << "G4IonTable::CreateIon() : create ion of " << name
346  << " " << Z << ", " << A
347  << " encoding=" << encoding;
348  if (E>0.0) {
349  G4cout << " IsomerLVL=" << lvl
350  << " excited energy=" << Eex/keV << "[keV]";
351  }
352  G4cout << G4endl;
353  }
354 #endif
355 
356  // Add process manager to the ion
357  AddProcessManager(ion);
358 
359 #ifdef G4MULTITHREADED
360  // Fill decay channels if this method is invoked from worker
362  {
363  if(!stable && decayTable)
364  {
365  G4int nCh = decayTable->entries();
366  for(G4int iCh=0;iCh<nCh;iCh++)
367  { decayTable->GetDecayChannel(iCh)->GetDaughter(0); }
368  }
369  }
370 #endif
371 
372  return ion;
373 }
374 
375 
378 {
379  if (LL==0) return CreateIon(Z,A,E);
380 
381  // create hyper nucleus
383 
384  // check whether GenericIon has processes
385  G4ParticleDefinition* genericIon =
387  G4ProcessManager* pman=0;
388  if (genericIon!=0) pman = genericIon->GetProcessManager();
389  if ((genericIon ==0) || (genericIon->GetParticleDefinitionID() < 0) || (pman==0)){
390 #ifdef G4VERBOSE
391  if (GetVerboseLevel()>1) {
392  G4cout << "G4IonTable::CreateIon() : can not create ion of "
393  << " Z =" << Z << " A = " << A
394  << " because GenericIon is not ready !!" << G4endl;
395  }
396 #endif
397  G4Exception( "G4IonTable::CreateIon()","PART105", JustWarning,
398  "Can not create ions because GenericIon is not ready");
399  return 0;
400  }
401 
402  G4int J=0;
403  G4double life = -1.0;
404  G4DecayTable* decayTable =0;
405  G4bool stable = true;
406 
407  // excitation energy
409  G4double mass = GetNucleusMass(Z, A, LL)+ Eex;
410  G4int lvl = 0;
411  // lvl is assigned to 9 temporally
412  if (Eex>0.0) lvl=9;
413 
414  // PDG encoding
415  G4int encoding = GetNucleusEncoding(Z,A,LL,E,lvl);
416 
417  // PDG charge is set to one of nucleus
418  G4double charge = G4double(Z)*eplus;
419 
420  // create an ion
421  // spin, parity, isospin values are fixed
422  //
423  // get ion name
424  G4String name = GetIonName(Z, A, LL, Eex);
425 
426  ion = new G4Ions( name, mass, 0.0*MeV, charge,
427  J, +1, 0,
428  0, 0, 0,
429  "nucleus", 0, A, encoding,
430  stable, life, decayTable, false,
431  "generic", 0,
432  Eex, lvl );
433 
434  // Release lock for particle table accesses.
435  //
436 
437  G4double mu = 0.0; // magnetic moment
438  ion->SetPDGMagneticMoment(mu);
439 
440  //No Anti particle registered
441  ion->SetAntiPDGEncoding(0);
442 
443 #ifdef G4VERBOSE
444  if (GetVerboseLevel()>1) {
445  G4cout << "G4IonTable::CreateIon() : create hyper ion of " << name
446  << " " << Z << ", " << A << ", " << LL
447  << " encoding=" << encoding;
448  if (E>0.0) {
449  G4cout << " IsomerLVL=" << lvl
450  << " excited energy=" << Eex/keV << "[keV]";
451  }
452  G4cout << G4endl;
453  }
454 #endif
455 
456  // Add process manager to the ion
457  AddProcessManager(ion);
458 
459  return ion;
460 }
461 
464 {
465  if(lvl == 0) return CreateIon(Z,A,0.0);
466  G4Exception( "G4IonTable::CreateIon()","PART105", JustWarning,
467  "Ion cannot be created by an isomer level. Use excitation energy.");
468  return 0;
469 }
470 
471 
474 {
475  if (LL==0) return CreateIon(Z,A,lvl);
476 
477  if (lvl>0) {
479  ed << "Isomer level " << lvl << " is unknown for the isotope (Z="
480  << Z << ", A=" << A << ", L=" << LL << "). Null pointer is returned.";
481  G4Exception( "G4IonTable::GetIon()","PART106", JustWarning, ed);
482  return 0;
483  }
484 
485  return CreateIon(A,Z,LL,0.0);
486 }
487 
489 // -- GetIon methods ------
492 {
493  if ( (A<1) || (Z<=0) || (lvl<0) || (A>999) ) {
494 #ifdef G4VERBOSE
495  if (GetVerboseLevel()>0) {
496  G4cout << "G4IonTable::GetIon() : illegal atomic number/mass"
497  << " Z =" << Z << " A = " << A << " Lvl = " << lvl << G4endl;
498  }
499 #endif
500  return 0;
501  }
502 
503  // Search ions with A, Z, lvl
504  G4ParticleDefinition* ion = FindIon(Z,A,lvl);
505 
506  // create ion
507 #ifdef G4MULTITHREADED
508  if(ion == 0)
509  {
511  {
512  G4MUTEXLOCK(&G4IonTable::ionTableMutex);
513  ion = FindIonInMaster(Z,A,lvl);
514  if(ion == 0 && lvl == 0) ion = CreateIon(Z,A,lvl);
515  if(ion != 0) InsertWorker(ion);
516  G4MUTEXUNLOCK(&G4IonTable::ionTableMutex);
517  }
518  else
519  { if(lvl == 0) ion = CreateIon(Z,A,lvl); }
520  }
521 #else
522  if(ion == 0 && lvl == 0) ion = CreateIon(Z, A, lvl);
523 #endif
524 
525 // if(ion == 0)
526 // {
527 // G4ExceptionDescription ed;
528 // ed << "Isomer level " << lvl << " is unknown for the isotope (Z="
529 // << Z << ", A=" << A << "). Null pointer is returned.";
530 // G4Exception( "G4IonTable::GetIon()","PART106", JustWarning, ed);
531 // }
532  return ion;
533 }
534 
535 
538 {
539  if (LL==0) return GetIon(Z,A,lvl);
540 
541  if (A < 2 || Z < 0 || Z > A-LL || LL>A || A>999 ) {
542 #ifdef G4VERBOSE
543  if (GetVerboseLevel()>0) {
544  G4cout << "G4IonTable::GetIon() : illegal atomic number/mass"
545  << " Z =" << Z << " A = " << A << " L = " << LL
546  <<" IsomerLvl = " << lvl << G4endl;
547  }
548 #endif
549  return 0;
550  } else if( A==2 ) {
551 #ifdef G4VERBOSE
552  if (GetVerboseLevel()>0) {
553  G4cout << "G4IonTable::GetIon() : No boud state for "
554  << " Z =" << Z << " A = " << A << " L = " << LL
555  <<" IsomerLvl = " << lvl << G4endl;
556  }
557 #endif
558  return 0;
559  }
560 
561  // Search ions with A, Z
562  G4ParticleDefinition* ion = FindIon(Z,A,LL,lvl);
563 
564  // create ion
565  if (ion == 0) {
566  if (lvl==0) {
567 #ifdef G4MULTITHREADED
569  {
570  G4MUTEXLOCK(&G4IonTable::ionTableMutex);
571  ion = FindIonInMaster(Z,A,LL,lvl);
572  if(ion == 0) ion = CreateIon(Z, A, LL, lvl);
573  InsertWorker(ion);
574  G4MUTEXUNLOCK(&G4IonTable::ionTableMutex);
575  }
576  else
577  { ion = CreateIon(Z, A, LL, lvl); }
578 #else
579  ion = CreateIon(Z, A, LL, lvl);
580 #endif
581  }
582  }
583 
584 // if(ion == 0)
585 // {
586 // G4ExceptionDescription ed;
587 // ed << "Isomer level " << lvl << " is unknown for the isotope (Z="
588 // << Z << ", A=" << A << ", L=" << LL << "). Null pointer is returned.";
589 // G4Exception( "G4IonTable::GetIon()","PART106", JustWarning, ed);
590 // }
591  return ion;
592 }
593 
596 {
597  if ( (A<1) || (Z<=0) || (E<0.0) || (A>999) || (J<0) ) {
598 #ifdef G4VERBOSE
599  if (GetVerboseLevel()>0) {
600  G4cout << "G4IonTable::GetIon() : illegal atomic number/mass"
601  << " Z =" << Z << " A = " << A << " E = " << E/keV << G4endl;
602  }
603 #endif
604  return 0;
605  }
606 
607  // Search ions with A, Z
608  G4ParticleDefinition* ion = FindIon(Z,A,E,J);
609 
610  // create ion
611 #ifdef G4MULTITHREADED
612  if(ion == 0)
613  {
615  {
616  G4MUTEXLOCK(&G4IonTable::ionTableMutex);
617  ion = FindIonInMaster(Z,A,E,J);
618  if(ion == 0) ion = CreateIon(Z,A,E);
619  InsertWorker(ion);
620  G4MUTEXUNLOCK(&G4IonTable::ionTableMutex);
621  }
622  else
623  { ion = CreateIon(Z,A,E); }
624  }
625 #else
626  if (ion == 0) ion = CreateIon(Z, A, E);
627 #endif
628 
629  return ion;
630 }
631 
634 {
635  if (LL==0) return GetIon(Z,A,E,J);
636 
637  if (A < 2 || Z < 0 || Z > A-LL || LL>A || A>999 ) {
638 #ifdef G4VERBOSE
639  if (GetVerboseLevel()>0) {
640  G4cout << "G4IonTable::GetIon() : illegal atomic number/mass"
641  << " Z =" << Z << " A = " << A << " L = " << LL
642  <<" E = " << E/keV << G4endl;
643  }
644 #endif
645  return 0;
646  } else if( A==2 ) {
647 #ifdef G4VERBOSE
648  if (GetVerboseLevel()>0) {
649  G4cout << "G4IonTable::GetIon() : No boud state for "
650  << " Z =" << Z << " A = " << A << " L = " << LL
651  << " E = " << E/keV << G4endl;
652  }
653 #endif
654  return 0;
655  }
656 
657  // Search ions with A, Z
658  G4ParticleDefinition* ion = FindIon(Z,A,LL,E,J);
659 
660  // create ion
661 #ifdef G4MULTITHREADED
662  if(ion == 0)
663  {
665  {
666  G4MUTEXLOCK(&G4IonTable::ionTableMutex);
667  ion = FindIonInMaster(Z,A,LL,E,J);
668  if(ion == 0) ion = CreateIon(Z,A,LL,E);
669  InsertWorker(ion);
670  G4MUTEXUNLOCK(&G4IonTable::ionTableMutex);
671  }
672  else
673  { ion = CreateIon(Z,A,LL,E); }
674  }
675 #else
676  if(ion == 0) ion = CreateIon(Z, A, LL, E);
677 #endif
678 
679  return ion;
680 }
681 
684 {
685  G4int Z, A, LL, IsoLvl;
686  G4double E;
687  if (!GetNucleusByEncoding(encoding,Z,A,LL,E,IsoLvl) ){
688 #ifdef G4VERBOSE
689  if (GetVerboseLevel()>0) {
690  G4cout << "G4IonTable::GetIon() : illegal encoding"
691  << " CODE:" << encoding << G4endl;
692  }
693 #endif
694  G4Exception( "G4IonTable::GetIon()","PART106",
695  JustWarning, "illegal encoding for an ion");
696  return 0;
697  }
698  //
699  return GetIon( Z, A, LL, IsoLvl);
700 }
701 
704 {
705  if ( (A<1) || (Z<=0) || (J<0) || (E<0.0) || (A>999) ) {
706 #ifdef G4VERBOSE
707  if (GetVerboseLevel()>0) {
708  G4cout << "G4IonTable::FindIon() : illegal atomic number/mass or excitation level "
709  << " Z =" << Z << " A = " << A << " E = " << E/keV << G4endl;
710  }
711 #endif
712  G4Exception( "G4IonTable::FindIon()","PART107",
713  JustWarning, "illegal atomic number/mass");
714  return 0;
715  }
716  // Search ions with A, Z ,E
717  // !! J is omitted now !!
718  const G4ParticleDefinition* ion=0;
719  G4bool isFound = false;
720 
721  // check if light ion
722  ion = GetLightIon(Z,A);
723  if (ion!=0 && E==0.0) {
724  // light ion
725  isFound = true;
726  } else {
727  // -- loop over all particles in Ion table
729  G4IonList::iterator i = fIonList->find(encoding);
730  for( ;i != fIonList->end() ; i++) {
731  ion = i->second;
732  if ( ( ion->GetAtomicNumber() != Z) || (ion->GetAtomicMass()!=A) ) break;
733  // excitation level
734  G4double anExcitaionEnergy = ((const G4Ions*)(ion))->GetExcitationEnergy();
735  if ( std::fabs( E - anExcitaionEnergy )< tolerance) {
736  isFound = true;
737  break;
738  }
739  }
740  }
741 
742  if ( isFound ){
743  return const_cast<G4ParticleDefinition*>(ion);
744  } else {
745  return 0;
746  }
747 }
748 
749 
752 {
753  if (LL==0) return FindIon(Z,A,E,J);
754 
755  if (A < 2 || Z < 0 || Z > A-LL || LL>A || A>999 ) {
756 #ifdef G4VERBOSE
757  if (GetVerboseLevel()>0) {
758  G4cout << "G4IonTable::FindIon() : illegal atomic number/mass or excitation level "
759  << " Z =" << Z << " A = " << A << " L = " << LL
760  <<" E = " << E/keV << G4endl;
761  }
762 #endif
763  G4Exception( "G4IonTable::FindIon()","PART107",
764  JustWarning, "illegal atomic number/mass");
765  return 0;
766  }
767  // Search ions with A, Z ,E
768  // !! J is omitted now !!
769  const G4ParticleDefinition* ion=0;
770  G4bool isFound = false;
771 
772  // -- loop over all particles in Ion table
773  G4int encoding=GetNucleusEncoding(Z, A, LL, 0.0, 0);
774  G4IonList::iterator i = fIonList->find(encoding);
775  for( ;i != fIonList->end() ; i++) {
776  ion = i->second;
777  if ( ( ion->GetAtomicNumber() != Z) || (ion->GetAtomicMass()!=A) ) break;
778  if( ion->GetQuarkContent(3) != LL) break;
779  // excitation level
780  G4double anExcitaionEnergy = ((const G4Ions*)(ion))->GetExcitationEnergy();
781  if ( std::fabs( E - anExcitaionEnergy )< tolerance) {
782  isFound = true;
783  break;
784  }
785  }
786 
787  if ( isFound ){
788  return const_cast<G4ParticleDefinition*>(ion);
789  } else {
790  return 0;
791  }
792 }
793 
794 
797 {
798  if ( (A<1) || (Z<=0) || (lvl<0) || (A>999) ) {
799 #ifdef G4VERBOSE
800  if (GetVerboseLevel()>0) {
801  G4cout << "G4IonTable::FindIon() : illegal atomic number/mass or excitation level "
802  << " Z =" << Z << " A = " << A << " IsoLvl = " << lvl << G4endl;
803  }
804 #endif
805  G4Exception( "G4IonTable::FindIon()","PART107",
806  JustWarning, "illegal atomic number/mass");
807  return 0;
808  }
809  // Search ions with A, Z ,E
810  // !! J is omitted now !!
811  const G4ParticleDefinition* ion=0;
812  G4bool isFound = false;
813 
814  // check if light ion
815  ion = GetLightIon(Z,A);
816  if (ion!=0 && lvl==0) {
817  // light ion
818  isFound = true;
819  } else {
820  // -- loop over all particles in Ion table
822  G4IonList::iterator i = fIonList->find(encoding);
823  for( ;i != fIonList->end() ; i++) {
824  ion = i->second;
825  if ( ( ion->GetAtomicNumber() != Z) || (ion->GetAtomicMass()!=A) ) break;
826  // excitation level
827  if ( ((const G4Ions*)(ion))->GetIsomerLevel() == lvl) {
828  isFound = true;
829  break;
830  }
831  }
832  }
833 
834  if ( isFound ){
835  if(lvl==9)
836  {
837  G4Exception("G4IonTable::FindIon()","PART5107",JustWarning,
838  "Isomer level 9 may be ambiguous.");
839  }
840  return const_cast<G4ParticleDefinition*>(ion);
841  } else {
842  return 0;
843  }
844 }
845 
846 
849 {
850  if (LL==0) return FindIon(Z,A,lvl);
851 
852  if (A < 2 || Z < 0 || Z > A-LL || LL>A || A>999 ) {
853 #ifdef G4VERBOSE
854  if (GetVerboseLevel()>0) {
855  G4cout << "G4IonTable::FindIon() : illegal atomic number/mass or excitation level "
856  << " Z =" << Z << " A = " << A << " L = " << LL
857  <<" IsomerLvl = " << lvl << G4endl;
858  }
859 #endif
860  G4Exception( "G4IonTable::FindIon()","PART107",
861  JustWarning, "illegal atomic number/mass");
862  return 0;
863  }
864  // Search ions with A, Z ,E, lvl
865  const G4ParticleDefinition* ion=0;
866  G4bool isFound = false;
867 
868  // -- loop over all particles in Ion table
870  G4IonList::iterator i = fIonList->find(encoding);
871  for( ;i != fIonList->end() ; i++) {
872  ion = i->second;
873  if ( ( ion->GetAtomicNumber() != Z) || (ion->GetAtomicMass()!=A) ) break;
874  if ( ion->GetQuarkContent(3) != LL) break;
875  // excitation level
876  if ( ((const G4Ions*)(ion))->GetIsomerLevel() == lvl) {
877  isFound = true;
878  break;
879  }
880  }
881 
882  if ( isFound ){
883  if(lvl==9)
884  {
885  G4Exception("G4IonTable::FindIon()","PART5107",JustWarning,
886  "Isomer level 9 may be ambiguous.");
887  }
888  return const_cast<G4ParticleDefinition*>(ion);
889  } else {
890  return 0;
891  }
892 }
893 
894 
897 {
898  // PDG code for Ions
899  // Nuclear codes are given as 10-digit numbers +-100ZZZAAAI.
900  //For a nucleus consisting of np protons and nn neutrons
901  // A = np + nn and Z = np.
902  // I gives the isomer level, with I = 0 corresponding
903  // to the ground state and I >0 to excitations
904 
905  if ( Z==1 && A==1 && E==0.0 ) return 2212; // proton
906 
907  G4int encoding = 1000000000;
908  encoding += Z * 10000;
909  encoding += A *10;
910  if (lvl>0&&lvl<10) encoding +=lvl; //isomer level
911  else if (E>0.0) encoding += 9; //isomer level
912 
913  return encoding;
914 }
915 
918  G4double E, G4int lvl)
919 {
920  // get PDG code for Hyper-Nucleus Ions
921  // Nuclear codes are given as 10-digit numbers +-10LZZZAAAI.
922  //For a nucleus consisting of np protons and nn neutrons
923  // A = np + nn +nlambda and Z = np.
924  // LL = nlambda
925  // I gives the isomer level, with I = 0 corresponding
926  // to the ground state and I >0 to excitations
927 
928  G4int encoding = GetNucleusEncoding(Z, A, E, lvl);
929  if (LL==0) return encoding;
930  encoding += LL* 10000000;
931  if ( Z==1 && A==1 && E==0.0 ) encoding = 3122; // Lambda
932 
933  return encoding;
934 }
935 
938  G4int &Z, G4int &A,
939  G4double &E, G4int &lvl)
940 {
941  if (encoding <= 0) return false; // anti particle
942 
943  if (encoding == 2212) { // proton
944  Z = 1; A = 1;
945  E = 0.0; lvl =0;
946  return true;
947  }
948 
949  encoding -= 1000000000;
950  Z = encoding/10000;
951  encoding -= 10000*Z;
952  A = encoding/10;
953  lvl = encoding % 10;
954  return true;
955 }
956 
959  G4int &Z, G4int &A,
960  G4int &LL,
961  G4double &E, G4int &lvl)
962 {
963  if (encoding <= 0) return false; // anti particle
964 
965  if (encoding == 3122) { // Lambda
966  Z = 1; A = 1; LL = 1;
967  E = 0.0; lvl =0;
968  return true;
969  }
970 
971  if (encoding % 10 != 0) {
973  return false;
974  }
975  if (encoding < 1000000000) {
976  // anti particle
977  return false;
978  }
979 
980  encoding -= 1000000000;
981  LL = encoding/10000000;
982  encoding -= 10000000*LL;
983  Z = encoding/10000;
984  encoding -= 10000*Z;
985  A = encoding/10;
986  lvl = encoding % 10;
987  return true;
988 }
989 
990 #include "G4AutoDelete.hh"
993 {
994  static G4ThreadLocal G4String *pname = 0;
995  if (!pname) { pname = new G4String(""); G4AutoDelete::Register(pname); }
996  G4String &name = *pname;
997 
998  static G4ThreadLocal std::ostringstream* os = 0;
999  if ( ! os ) {
1000  os = new std::ostringstream();
1002  os->setf(std::ios::fixed);
1003  os->precision(3);
1004  }
1005 
1006  name = GetIonName(Z, A);
1007 
1008  //excited energy
1009  if ( E>0 ){
1010  os->str("");
1011  std::ostringstream& oo = *os;
1012  // Excited nucleus
1013  oo<<'['<<E/keV << ']';
1014  name += os->str();
1015  }
1016 
1017  return name;
1018 }
1019 
1022 {
1023  if (LL==0) return GetIonName(Z, A, E);
1024  static G4ThreadLocal G4String *pname = 0;
1025  if (!pname) { pname = new G4String(""); G4AutoDelete::Register(pname); }
1026  G4String &name = *pname;
1027  name = "";
1028  for (int i =0; i<LL; i++){
1029  name +="L";
1030  }
1031  name += GetIonName(Z, A, E);
1032  return name;
1033 }
1034 
1037 {
1038  static G4ThreadLocal G4String *pname = 0;
1039  if (!pname) { pname = new G4String(""); G4AutoDelete::Register(pname); }
1040  G4String &name = *pname;
1041 
1042  static G4ThreadLocal std::ostringstream* os = 0;
1043  if ( ! os ) {
1044  os = new std::ostringstream();
1046  os->setf(std::ios::fixed);
1047  }
1048 
1049  if ( (0< Z) && (Z <=numberOfElements) ) {
1050  name = elementName[Z-1];
1051  } else if (Z > numberOfElements) {
1052  os->str("");
1053  os->operator<<(Z);
1054  name = "E" + os->str() + "-";
1055  } else {
1056  name = "?";
1057  return name;
1058  }
1059  // Atomic Mass
1060  os->str("");
1061  os->operator<<(A);
1062 
1063  if ( lvl>0 ){
1064  std::ostringstream& oo = *os;
1065  // isomer level for Excited nucelus
1066  oo<<'['<<lvl << ']';
1067  }
1068  name += os->str();
1069 
1070  return name;
1071 }
1072 
1075 {
1076  if (LL==0) return GetIonName(Z, A, lvl);
1077  static G4ThreadLocal G4String *pname = 0;
1078  if (!pname) { pname = new G4String(""); G4AutoDelete::Register(pname); }
1079  G4String &name = *pname;
1080  for (int i =0; i<LL; i++){
1081  name +="L";
1082  }
1083  name += GetIonName(Z, A, lvl);
1084  return name;
1085 }
1086 
1087 
1090 {
1091  // return true if the particle is ion
1092 
1093  static const G4String nucleus("nucleus");
1094  static const G4String proton("proton");
1095 
1096  // neutron is not ion
1097  if ((particle->GetAtomicMass()>0) &&
1098  (particle->GetAtomicNumber()>0) ){
1099  if (particle->GetBaryonNumber()>0) return true;
1100  else return false;
1101  }
1102 
1103 
1104  // particles derived from G4Ions
1105  if (particle->GetParticleType() == nucleus) return true;
1106 
1107  // proton (Hydrogen nucleus)
1108  if (particle->GetParticleName() == proton) return true;
1109 
1110  return false;
1111 }
1112 
1115 {
1116  // return true if the particle is ion
1117 
1118  static const G4String anti_nucleus("anti_nucleus");
1119  static const G4String anti_proton("anti_proton");
1120 
1121  // anti_neutron is not ion
1122  if ((particle->GetAtomicMass()>0) &&
1123  (particle->GetAtomicNumber()>0) ){
1124  if (particle->GetBaryonNumber()<0) return true;
1125  else return false;
1126  }
1127 
1128  // particles derived from G4Ions
1129  if (particle->GetParticleType() == anti_nucleus) return true;
1130 
1131  // anti_proton (Anti_Hydrogen nucleus)
1132  if (particle->GetParticleName() == anti_proton) return true;
1133 
1134  return false;
1135 }
1136 
1138 #include <algorithm>
1139 
1141 {
1142  static const std::string names[] = { "proton", "alpha", "deuteron",
1143  "triton", "He3"};
1144 
1145  // return true if the particle is pre-defined ion
1146  return std::find(names, names+5, particle->GetParticleName())!=names+5;
1147 }
1148 
1150 {
1151  static const std::string names[] = { "anti_proton", "anti_alpha", "anti_deuteron",
1152  "anti_triton", "anti_He3"};
1153 
1154  // return true if the particle is pre-defined ion
1155  return std::find(names, names+5, particle->GetParticleName())!=names+5;
1156 }
1157 
1160 {
1161  // returns pointer to pre-defined ions
1162  const G4ParticleDefinition* ion=0;
1163  if ( (Z<=2) ) {
1164 #ifndef G4MULTITHREADED
1165  //In sequential use lazy-initialization
1166  lightions::Init();
1167 #endif
1168  if ( (Z==1)&&(A==1) ) {
1169  ion = lightions::p_proton;
1170  } else if ( (Z==1)&&(A==2) ) {
1171  ion = lightions::p_deuteron;
1172  } else if ( (Z==1)&&(A==3) ) {
1173  ion = lightions::p_triton;
1174  } else if ( (Z==2)&&(A==4) ) {
1175  ion = lightions::p_alpha;
1176  } else if ( (Z==2)&&(A==3) ) {
1177  ion = lightions::p_He3;
1178  }
1179  }
1180  return const_cast<G4ParticleDefinition*>(ion);
1181 }
1182 
1185 {
1186  // returns pointer to pre-defined ions
1187  const G4ParticleDefinition* ion=0;
1188  if ( (Z<=2) ) {
1189 #ifndef G4MULTITHREADED
1190  //In sequential use lazy-initialization
1192 #endif
1193  if ( (Z==1)&&(A==1) ) {
1195  } else if ( (Z==1)&&(A==2) ) {
1197  } else if ( (Z==1)&&(A==3) ) {
1199  } else if ( (Z==2)&&(A==4) ) {
1200  ion = antilightions::p_alpha;
1201  } else if ( (Z==2)&&(A==3) ) {
1202  ion = antilightions::p_He3;
1203  }
1204  }
1205  return const_cast<G4ParticleDefinition*>(ion);
1206 }
1207 
1208 
1210 // -- GetNucleusMass/GetIonMass ---
1213 {
1214  if ( (A<1) || (Z<0) || (LL<0) || (lvl<0) || (lvl>9) ){
1215 #ifdef G4VERBOSE
1216  if (GetVerboseLevel()>0) {
1217  G4cout << "G4IonTable::GetNucleusMass() : illegal atomic number/mass "
1218  << " Z =" << Z << " A = " << A
1219  << " L = " << LL << " lvl = " << lvl << G4endl;
1220  }
1221 #endif
1222  G4Exception( "G4IonTable::GetNucleusMass()","PART107",
1223  EventMustBeAborted, "illegal atomic number/mass");
1224  return -1.0;
1225  }
1226 
1227  G4double mass;
1228  if (LL == 0) {
1229  // calculate nucleus mass
1230  const G4ParticleDefinition* ion=GetLightIon(Z, A);
1231 
1232  if (ion!=0) {
1233  mass = ion->GetPDGMass();
1234  } else {
1235  // use G4NucleiProperties::GetNuclearMass
1237  }
1238 
1239  // Isomer
1240  if ( lvl>0 ) {
1241  // -- loop over all particles in Ion table
1243  G4IonList::iterator i = fIonList->find(encoding);
1244  G4bool isFound =false;
1245  for( ;i != fIonList->end() ; i++) {
1246  ion = i->second;
1247  if ( ( ion->GetAtomicNumber() != Z) || (ion->GetAtomicMass()!=A) ) break;
1248  // excitation level
1249  if ( ((const G4Ions*)(ion))->GetIsomerLevel() == lvl) {
1250  isFound = true;
1251  break;
1252  }
1253  }
1254  if (isFound) {
1255  // return existing isomer mass
1256  mass = ion->GetPDGMass();
1257  } else {
1258  // Find isomer from IsotopeTable
1259  const G4IsotopeProperty* fProperty = FindIsotope(Z, A, lvl);
1260  if (fProperty !=0 ) mass += fProperty->GetEnergy();
1261  }
1262  }
1263 
1264  } else {
1265  mass = G4HyperNucleiProperties::GetNuclearMass(A, Z, LL);
1266  }
1267  return mass;
1268 }
1269 
1272 {
1273  return GetNucleusMass(Z,A,0,lvl);
1274 }
1275 
1278 {
1279  return GetNucleusMass(Z,A,LL,lvl);
1280 }
1281 
1282 
1284 // -- Methods for handling conatiner ---
1286 
1288 {
1289  if (G4ParticleTable::GetParticleTable()->GetReadiness()) {
1290  G4Exception("G4IonTable::clear()",
1291  "PART116", JustWarning,
1292  "No effects because readyToUse is true.");
1293  return;
1294  }
1295 
1296 #ifdef G4VERBOSE
1297  if (GetVerboseLevel()>2) {
1298  G4cout << "G4IonTable::Clear() : number of Ion regsitered = ";
1299  G4cout << fIonList->size() << G4endl;
1300  }
1301 #endif
1302  fIonList->clear();
1303 }
1304 
1306 {
1307  if (!IsIon(particle)) return;
1308  if (Contains(particle)) return;
1309 
1310  G4int Z = particle->GetAtomicNumber();
1311  G4int A = particle->GetAtomicMass();
1312  G4int LL = particle->GetQuarkContent(3); //strangeness
1313  G4int encoding=GetNucleusEncoding(Z, A, LL); // encoding of the groud state
1314 
1315  // regsiter the ion with its encoding of the groud state
1316  fIonListShadow->insert( std::pair<const G4int, const G4ParticleDefinition*>(encoding, particle) );
1317 
1318 }
1319 
1321 {
1322  if(!particle) return;
1323 
1324  G4int Z = particle->GetAtomicNumber();
1325  G4int A = particle->GetAtomicMass();
1326  G4int LL = particle->GetQuarkContent(3); //strangeness
1327  G4int encoding=GetNucleusEncoding(Z, A, LL);
1328  G4bool found = false;
1329  if (encoding !=0 ) {
1330  G4IonList::iterator i = fIonList->find(encoding);
1331  for( ;i != fIonList->end() ; i++) {
1332  if (particle == i->second ) {
1333  found = true;
1334  break;
1335  }
1336  }
1337  }
1338  if(found) return;
1339 
1340  // regsiter the ion with its encoding of the groud state
1341  fIonList->insert( std::pair<const G4int, const G4ParticleDefinition*>(encoding, particle) );
1342 
1343 }
1344 
1347 {
1348  if(!particle) return;
1349 #ifdef G4MULTITHREADED
1352  ed << "Request of removing " << particle->GetParticleName()
1353  << " is ignored as it is invoked from a worker thread.";
1354  G4Exception("G4IonTable::Remove()","PART10117",JustWarning,ed);
1355  return;
1356  }
1357 #endif
1358  if (G4ParticleTable::GetParticleTable()->GetReadiness()) {
1360  G4ApplicationState currentState = pStateManager->GetCurrentState();
1361  if (currentState != G4State_PreInit) {
1362  G4String msg = "Request of removing ";
1363  msg += particle->GetParticleName();
1364  msg += " has No effects other than Pre_Init";
1365  G4Exception("G4IonTable::Remove()",
1366  "PART117", JustWarning, msg);
1367  return;
1368  } else {
1369 #ifdef G4VERBOSE
1370  if (GetVerboseLevel()>0){
1371  G4cout << particle->GetParticleName()
1372  << " will be removed from the IonTable " << G4endl;
1373  }
1374 #endif
1375  }
1376  }
1377 
1378  if (IsIon(particle)) {
1379  G4int Z = particle->GetAtomicNumber();
1380  G4int A = particle->GetAtomicMass();
1381  G4int LL = particle->GetQuarkContent(3); //strangeness
1382  G4int encoding=GetNucleusEncoding(Z, A, LL);
1383  if (encoding !=0 ) {
1384  G4IonList::iterator i = fIonListShadow->find(encoding);
1385  for( ;i != fIonListShadow->end() ; i++) {
1386  if (particle == i->second) {
1387  fIonListShadow->erase(i);
1388  break;
1389  }
1390  }
1391  }
1392  } else {
1393 #ifdef G4VERBOSE
1394  if (GetVerboseLevel()>1) {
1395  G4cout << "G4IonTable::Remove :" << particle->GetParticleName()
1396  << " is not ions" << G4endl;
1397  }
1398 #endif
1399  }
1400 
1401 }
1402 
1403 
1404 
1406 // -- Dump Information
1408 void G4IonTable::DumpTable(const G4String &particle_name) const
1409 {
1410  const G4ParticleDefinition* ion;
1411  G4IonList::iterator idx;
1412  for (idx = fIonList->begin(); idx!= fIonList->end(); ++idx) {
1413  ion = idx->second;
1414  if (( particle_name == "ALL" ) || (particle_name == "all")){
1415  ion->DumpTable();
1416  } else if ( particle_name == ion->GetParticleName() ) {
1417  ion->DumpTable();
1418  }
1419  }
1420 }
1421 
1424  "H", "He",
1425  "Li", "Be", "B", "C", "N", "O", "F", "Ne",
1426  "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar",
1427  "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr",
1428  "Rb", "Sr", "Y", "Zr", "Nb", "Mo","Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe",
1429  "Cs", "Ba",
1430  "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu",
1431  "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn",
1432  "Fr", "Ra",
1433  "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr",
1434  "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg",
1435  "Cp", "Uut", "Fl","Uup","Lv","Uus","Uuo"
1436 };
1437 
1438 
1441 {
1443 }
1444 
1447 {
1448  // check State and do not attach process managaer in event loop
1449 // G4StateManager* pStateManager = G4StateManager::GetStateManager();
1450 // G4ApplicationState currentState = pStateManager->GetCurrentState();
1451 // if (currentState == G4State_EventProc) return;
1452 // {
1453 // if (n_error<10)
1454 // {
1455 // G4cout << "Defining process manager for " << ion->GetParticleName() << G4endl;
1456 // G4Exception("G4IonTable::AddProcessManager()", "PART130", JustWarning,
1457 // "Defining process manager during an event loop is thread unsafe and will be dropped from the next release.");
1458 // n_error +=1;
1459 // }
1460 // return;
1461 // }
1462 
1463  // check whether GenericIon has processes
1464  G4ParticleDefinition* genericIon =
1466 
1467  G4ProcessManager* pman=0;
1468  if (genericIon!=0) pman = genericIon->GetProcessManager();
1469  if ((genericIon ==0) || (genericIon->GetParticleDefinitionID() < 0) || (pman==0)){
1470  G4cout << "G4IonTable::AddProcessManager() : can not create ion of "
1471  << ion->GetParticleName()
1472  << " because GenericIon is not available!!" << G4endl;
1473  G4Exception( "G4IonTable::AddProcessManager()","PART105", FatalException,
1474  "Can not create ions because GenericIon is not available");
1475  return;
1476  }
1477 
1480 }
1481 
1482 #include <vector>
1483 
1486 {
1487  //check duplication
1488  G4String name = table->GetName();
1489  for (size_t i = 0; i< fIsotopeTableList->size(); ++i) {
1490  G4VIsotopeTable* fIsotopeTable= (*fIsotopeTableList)[i];
1491  if (name == fIsotopeTable->GetName()) return;
1492  }
1493 
1494  // register
1495  fIsotopeTableList->push_back(table);
1496 }
1497 
1500 {
1501  G4VIsotopeTable* fIsotopeTable=0;
1502  if ( index < fIsotopeTableList->size() ) {
1503  fIsotopeTable = (*fIsotopeTableList)[index];
1504  }
1505  return fIsotopeTable;
1506 }
1507 
1508 
1511 {
1512  if (fIsotopeTableList ==0) return 0;
1513  if (fIsotopeTableList->size()==0) return 0;
1514 
1515  G4IsotopeProperty* property =0;
1516 
1517  // iterate
1518  for (size_t i = 0; i<fIsotopeTableList->size(); ++i) {
1519  G4VIsotopeTable* fIsotopeTable= (*fIsotopeTableList)[fIsotopeTableList->size()-i-1];
1520  property = fIsotopeTable->GetIsotope(Z,A,E);
1521  if(property) break;
1522  }
1523 
1524  return property;
1525 }
1526 
1529 {
1530  if (fIsotopeTableList ==0) return 0;
1531  if (fIsotopeTableList->size()==0) return 0;
1532 
1533  G4IsotopeProperty* property =0;
1534 
1535  // iterate
1536  for (size_t i = 0; i<fIsotopeTableList->size(); ++i) {
1537  G4VIsotopeTable* fIsotopeTable= (*fIsotopeTableList)[fIsotopeTableList->size()-i-1];
1538  property = fIsotopeTable->GetIsotope(Z,A,lvl);
1539  if(property) break;
1540  }
1541 
1542  return property;
1543 }
1544 
1545 
1548 {
1549  PreloadNuclide();
1550 }
1551 
1554 {
1555  PreloadNuclide();
1556 }
1557 
1560 {
1562 }
1563 
1566 {
1568 
1570 
1571  for ( size_t i = 0 ; i != pNuclideTable->entries() ; i++ ) {
1572  const G4IsotopeProperty* fProperty = pNuclideTable->GetIsotopeByIndex( i );
1573  G4int Z = fProperty->GetAtomicNumber();
1574  G4int A = fProperty->GetAtomicMass();
1575  G4double Eex = fProperty->GetEnergy();
1576  GetIon(Z,A,Eex);
1577  }
1578 
1579  isIsomerCreated = true;
1580 }
1581 
1582 
1585 {
1586  if ( (index >=0) && (index < Entries()) ) {
1587  G4IonList::iterator idx = fIonList->begin();
1588  G4int counter = 0;
1589  while( idx != fIonList->end() ){// Loop checking, 09.08.2015, K.Kurashige
1590  if ( counter == index ) {
1591  return const_cast<G4ParticleDefinition*>(idx->second);
1592  }
1593  counter++;
1594  idx++;
1595  }
1596  }
1597 #ifdef G4VERBOSE
1598  if (GetVerboseLevel()>1){
1599  G4cout << " G4IonTable::GetParticle"
1600  << " invalid index (=" << index << ")"
1601  << " entries = " << Entries() << G4endl;
1602  }
1603 #endif
1604  return 0;
1605 }
1606 
1609 {
1610  if (!IsIon(particle)) return false;
1611 
1612  G4int Z = particle->GetAtomicNumber();
1613  G4int A = particle->GetAtomicMass();
1614  G4int LL = particle->GetQuarkContent(3); //strangeness
1615  G4int encoding=GetNucleusEncoding(Z, A, LL);
1616  G4bool found = false;
1617  if (encoding !=0 ) {
1618  G4IonList::iterator i = fIonListShadow->find(encoding);
1619  for( ;i != fIonListShadow->end() ; i++) {
1620  if (particle == i->second ) {
1621  found = true;
1622  break;
1623  }
1624  }
1625  }
1626  return found;
1627 }
1628 
1631 {
1632  return fIonList->size();
1633 }
1634 
1637 {
1638  return fIonList->size();
1639 }
1640 
1641 
1644 {
1645  // Search ions with A, Z ,E
1646  // !! J is omitted now !!
1647  const G4ParticleDefinition* ion=0;
1648  G4bool isFound = false;
1649 
1650  // -- loop over all particles in Ion table
1652  G4IonList::iterator i = fIonListShadow->find(encoding);
1653  for( ;i != fIonListShadow->end() ; i++) {
1654  ion = i->second;
1655  if ( ( ion->GetAtomicNumber() != Z) || (ion->GetAtomicMass()!=A) ) break;
1656  // excitation level
1657  G4double anExcitaionEnergy = ((const G4Ions*)(ion))->GetExcitationEnergy();
1658  if ( std::fabs( E - anExcitaionEnergy )< tolerance) {
1659  isFound = true;
1660  break;
1661  }
1662  }
1663 
1664  if ( isFound ){
1665  return const_cast<G4ParticleDefinition*>(ion);
1666  } else {
1667  return 0;
1668  }
1669 }
1670 
1671 
1674 {
1675  if (LL==0) return FindIon(Z,A,E,J);
1676 
1677  // Search ions with A, Z ,E
1678  // !! J is omitted now !!
1679  const G4ParticleDefinition* ion=0;
1680  G4bool isFound = false;
1681 
1682  // -- loop over all particles in Ion table
1683  G4int encoding=GetNucleusEncoding(Z, A, LL, 0.0, 0);
1684  G4IonList::iterator i = fIonListShadow->find(encoding);
1685  for( ;i != fIonListShadow->end() ; i++) {
1686  ion = i->second;
1687  if ( ( ion->GetAtomicNumber() != Z) || (ion->GetAtomicMass()!=A) ) break;
1688  if( ion->GetQuarkContent(3) != LL) break;
1689  // excitation level
1690  G4double anExcitaionEnergy = ((const G4Ions*)(ion))->GetExcitationEnergy();
1691  if ( std::fabs( E - anExcitaionEnergy )< tolerance) {
1692  isFound = true;
1693  break;
1694  }
1695  }
1696 
1697  if ( isFound ){
1698  return const_cast<G4ParticleDefinition*>(ion);
1699  } else {
1700  return 0;
1701  }
1702 }
1703 
1704 
1707 {
1708  // Search ions with A, Z ,E
1709  // !! J is omitted now !!
1710  const G4ParticleDefinition* ion=0;
1711  G4bool isFound = false;
1712 
1713  // -- loop over all particles in Ion table
1715  G4IonList::iterator i = fIonListShadow->find(encoding);
1716  for( ;i != fIonListShadow->end() ; i++) {
1717  ion = i->second;
1718  if ( ( ion->GetAtomicNumber() != Z) || (ion->GetAtomicMass()!=A) ) break;
1719  // excitation level
1720  if ( ((const G4Ions*)(ion))->GetIsomerLevel() == lvl) {
1721  isFound = true;
1722  break;
1723  }
1724  }
1725 
1726  if ( isFound ){
1727  return const_cast<G4ParticleDefinition*>(ion);
1728  } else {
1729  return 0;
1730  }
1731 }
1732 
1733 
1736 {
1737  if (LL==0) return FindIon(Z,A,lvl);
1738 
1739  // Search ions with A, Z ,E, lvl
1740  const G4ParticleDefinition* ion=0;
1741  G4bool isFound = false;
1742 
1743  // -- loop over all particles in Ion table
1744  G4int encoding=GetNucleusEncoding(Z, A, LL);
1745  G4IonList::iterator i = fIonListShadow->find(encoding);
1746  for( ;i != fIonListShadow->end() ; i++) {
1747  ion = i->second;
1748  if ( ( ion->GetAtomicNumber() != Z) || (ion->GetAtomicMass()!=A) ) break;
1749  if ( ion->GetQuarkContent(3) != LL) break;
1750  // excitation level
1751  if ( ((const G4Ions*)(ion))->GetIsomerLevel() == lvl) {
1752  isFound = true;
1753  break;
1754  }
1755  }
1756 
1757  if ( isFound ){
1758  return const_cast<G4ParticleDefinition*>(ion);
1759  } else {
1760  return 0;
1761  }
1762 }
1763 
1764 
1767 {
1768  //if(!(particle->IsGeneralIon())) return particle->GetPDGLifeTime();
1769 
1770  //const G4Ions* ion = static_cast<const G4Ions*>(particle);
1771  //G4int Z = ion->GetAtomicNumber();
1772  //G4int A = ion->GetAtomicMass();
1773  //G4double E = ion->GetExcitationEnergy();
1774 
1775  if((particle->IsGeneralIon()) && !pNuclideTable)
1776  {
1777  G4Exception("G4IonTable::GetLifeTime()","ParticleIon1001",FatalException,
1778  "Method is invoked before G4IonTable is initialized.");
1779  //return 0.;
1780  } //else {
1781  //G4IsotopeProperty* isoP = pNuclideTable->GetIsotope(Z,A,E);
1782  //if(!isoP) return -1001.0;
1783  //return isoP->GetLifeTime();
1784  //}
1785  return particle->GetPDGLifeTime();
1786 }
1787 
1789 {
1790  G4double life = -1001.0;
1791  const G4IsotopeProperty* fProperty = FindIsotope(Z, A, E);
1792  if( fProperty !=0 ) life = fProperty->GetLifeTime();
1793  return life;
1794 }
1795 
1796 
1797 
1798 
1799 
1800 
#define G4MUTEXUNLOCK
Definition: G4Threading.hh:180
G4int GetParticleDefinitionID() const
void InitializeLightIons()
Definition: G4IonTable.cc:179
G4double GetMagneticMoment() const
static const G4ParticleDefinition * p_triton
Definition: G4IonTable.cc:84
void RegisterIsotopeTable(G4VIsotopeTable *table)
Definition: G4IonTable.cc:1485
void WorkerG4IonTable()
Definition: G4IonTable.cc:153
static std::vector< G4VIsotopeTable * > * fIsotopeTableListShadow
Definition: G4IonTable.hh:292
void Init()
Definition: G4IonTable.cc:87
static const double MeV
Definition: G4SIunits.hh:211
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4DecayTable * GetDecayTable() const
G4int size() const
Definition: G4IonTable.cc:1636
void SetParticleDefinitionID(G4int id=-1)
G4int Entries() const
Definition: G4IonTable.cc:1630
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
void SetAntiPDGEncoding(G4int aEncoding)
const G4String & GetName() const
G4int GetAtomicNumber() const
G4int GetiSpin() const
void PrepareNuclideTable()
Definition: G4IonTable.cc:1559
void DumpTable(const G4String &particle_name="ALL") const
Definition: G4IonTable.cc:1408
G4String name
Definition: TRTMaterials.hh:40
static const G4ParticleDefinition * p_alpha
Definition: G4IonTable.cc:85
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:491
G4ParticleDefinition * GetDaughter(G4int anIndex)
void Remove(const G4ParticleDefinition *particle)
Definition: G4IonTable.cc:1346
G4double GetIsomerMass(G4int Z, G4int A, G4int lvl=0) const
Definition: G4IonTable.cc:1271
static G4bool IsIon(const G4ParticleDefinition *)
Definition: G4IonTable.cc:1089
G4bool IsLightAntiIon(const G4ParticleDefinition *) const
Definition: G4IonTable.cc:1149
G4VIsotopeTable * GetIsotopeTable(size_t idx=0) const
Definition: G4IonTable.cc:1499
void InsertWorker(const G4ParticleDefinition *particle)
Definition: G4IonTable.cc:1320
static G4bool IsAntiIon(const G4ParticleDefinition *)
Definition: G4IonTable.cc:1114
static G4int GetNucleusEncoding(G4int Z, G4int A, G4double E=0.0, G4int lvl=0)
Definition: G4IonTable.cc:896
G4int GetVerboseLevel() const
Definition: G4IonTable.cc:1440
G4int GetIsomerLevel() const
G4VDecayChannel * GetDecayChannel(G4int index) const
static G4ThreadLocal std::vector< G4VIsotopeTable * > * fIsotopeTableList
Definition: G4IonTable.hh:290
static const G4ParticleDefinition * p_proton
Definition: G4IonTable.cc:98
G4IsotopeProperty * GetIsotopeByIndex(size_t idx) const
G4ParticleDefinition * GetGenericIon() const
#define G4ThreadLocal
Definition: tls.hh:89
G4ProcessManager * GetProcessManager() const
int G4int
Definition: G4Types.hh:78
G4IsotopeProperty * FindIsotope(G4int Z, G4int A, G4double E) const
Definition: G4IonTable.cc:1510
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:175
static G4bool GetNucleusByEncoding(G4int encoding, G4int &Z, G4int &A, G4double &E, G4int &lvl)
Definition: G4IonTable.cc:937
const G4String & GetParticleName() const
const G4String & GetIonName(G4int Z, G4int A, G4int lvl=0) const
Definition: G4IonTable.cc:1036
G4int GetAtomicNumber() const
G4bool IsGeneralIon() const
void Insert(const G4ParticleDefinition *particle)
Definition: G4IonTable.cc:1305
void SlaveG4IonTable()
Definition: G4IonTable.cc:148
static G4IonList * fIonListShadow
Definition: G4IonTable.hh:291
G4int entries() const
G4bool isIsomerCreated
Definition: G4IonTable.hh:285
void CreateAllIsomer()
Definition: G4IonTable.cc:1553
static G4StateManager * GetStateManager()
G4ParticleDefinition * CreateIon(G4int Z, G4int A, G4double E)
Definition: G4IonTable.cc:244
void Register(T *inst)
Definition: G4AutoDelete.hh:65
G4GLOB_DLL std::ostream G4cout
double A(double temperature)
virtual G4IsotopeProperty * GetIsotope(G4int Z, G4int A, G4double E)=0
Definition: G4Ions.hh:51
std::multimap< G4int, const G4ParticleDefinition * > G4IonList
Definition: G4IonTable.hh:74
G4double GetEnergy() const
static const G4ParticleDefinition * p_He3
Definition: G4IonTable.cc:86
bool G4bool
Definition: G4Types.hh:79
G4double GetIonMass(G4int Z, G4int A, G4int L=0, G4int lvl=0) const
Definition: G4IonTable.cc:1277
G4int GetQuarkContent(G4int flavor) const
const G4String & GetParticleType() const
#define G4MUTEXLOCK
Definition: G4Threading.hh:179
G4ApplicationState GetCurrentState() const
G4bool IsMultithreadedApplication()
Definition: G4Threading.cc:136
#define encoding
Definition: xmlparse.cc:605
void AddProcessManager(G4ParticleDefinition *)
Definition: G4IonTable.cc:1446
static const G4ParticleDefinition * p_triton
Definition: G4IonTable.cc:100
G4int GetAtomicMass() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4bool Contains(const G4ParticleDefinition *particle) const
Definition: G4IonTable.cc:1608
G4bool IsWorkerThread()
Definition: G4Threading.cc:129
static G4NuclideTable * GetNuclideTable()
G4ParticleDefinition * FindIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:796
G4int G4Mutex
Definition: G4Threading.hh:173
G4NuclideTable * pNuclideTable
Definition: G4IonTable.hh:284
G4double GetPDGMass() const
static G4ParticleTable * GetParticleTable()
void PreloadNuclide()
Definition: G4IonTable.cc:1565
static const G4ParticleDefinition * p_deuteron
Definition: G4IonTable.cc:83
static const G4ParticleDefinition * p_alpha
Definition: G4IonTable.cc:101
void CreateAllIon()
Definition: G4IonTable.cc:1547
void clear()
Definition: G4IonTable.cc:1287
static const G4ParticleDefinition * p_He3
Definition: G4IonTable.cc:102
void DestroyWorkerG4IonTable()
Definition: G4IonTable.cc:214
static const G4int LL[nN]
static const G4double tolerance
Definition: G4IonTable.hh:299
static G4ThreadLocal G4IonList * fIonList
Definition: G4IonTable.hh:289
G4double GetPDGLifeTime() const
#define G4endl
Definition: G4ios.hh:61
G4double GetLifeTime(const G4ParticleDefinition *) const
Definition: G4IonTable.cc:1766
G4double GetNucleusMass(G4int Z, G4int A, G4int L=0, G4int lvl=0) const
Definition: G4IonTable.cc:1212
G4ParticleDefinition * GetLightAntiIon(G4int Z, G4int A) const
Definition: G4IonTable.cc:1184
static const double keV
Definition: G4SIunits.hh:213
static const G4ParticleDefinition * p_proton
Definition: G4IonTable.cc:82
double G4double
Definition: G4Types.hh:76
static const double eplus
Definition: G4SIunits.hh:196
G4ParticleDefinition * GetLightIon(G4int Z, G4int A) const
Definition: G4IonTable.cc:1159
G4ParticleDefinition * FindIonInMaster(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:1706
G4bool IsLightIon(const G4ParticleDefinition *) const
Definition: G4IonTable.cc:1140
static G4double Round(G4double eex)
G4int GetVerboseLevel() const
std::multimap< G4int, const G4ParticleDefinition * >::iterator G4IonListIterator
Definition: G4IonTable.hh:75
size_t entries() const
G4int GetAtomicMass() const
G4ApplicationState
G4double GetLifeTime() const
void SetPDGMagneticMoment(G4double mageticMoment)
static const G4String elementName[numberOfElements]
Definition: G4IonTable.hh:302
static G4double GetNuclearMass(G4int A, G4int Z, G4int L)
static const G4ParticleDefinition * p_deuteron
Definition: G4IonTable.cc:99
virtual ~G4IonTable()
Definition: G4IonTable.cc:187
G4ParticleDefinition * GetParticle(G4int index) const
Definition: G4IonTable.cc:1584