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