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