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 9.4)


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