Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/particles/management/src/G4IonTable.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /particles/management/src/G4IonTable.cc (Version 11.3.0) and /particles/management/src/G4IonTable.cc (Version 10.0.p2)


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