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