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