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


                                                   >>   1 // This code implementation is the intellectual property of
                                                   >>   2 // the GEANT4 collaboration.
  1 //                                                  3 //
  2 // ******************************************* <<   4 // By copying, distributing or modifying the Program (or any work
  3 // * License and Disclaimer                    <<   5 // based on the Program) you indicate your acceptance of this statement,
  4 // *                                           <<   6 // and all its terms.
  5 // * The  Geant4 software  is  copyright of th << 
  6 // * the Geant4 Collaboration.  It is provided << 
  7 // * conditions of the Geant4 Software License << 
  8 // * LICENSE and available at  http://cern.ch/ << 
  9 // * include a list of copyright holders.      << 
 10 // *                                           << 
 11 // * Neither the authors of this software syst << 
 12 // * institutes,nor the agencies providing fin << 
 13 // * work  make  any representation or  warran << 
 14 // * regarding  this  software system or assum << 
 15 // * use.  Please see the license in the file  << 
 16 // * for the full disclaimer and the limitatio << 
 17 // *                                           << 
 18 // * This  code  implementation is the result  << 
 19 // * technical work of the GEANT4 collaboratio << 
 20 // * By using,  copying,  modifying or  distri << 
 21 // * any work based  on the software)  you  ag << 
 22 // * use  in  resulting  scientific  publicati << 
 23 // * acceptance of all terms of the Geant4 Sof << 
 24 // ******************************************* << 
 25 //                                                  7 //
 26 // G4IonTable class implementation             <<   8 // $Id: G4IonTable.cc,v 1.22.4.6 1999/12/14 09:16:47 gunter Exp $
                                                   >>   9 // GEANT4 tag $Name: geant4-01-01 $
 27 //                                                 10 //
 28 // Author: H.Kurashige, 27 June 1998           <<  11 // 
 29 // ------------------------------------------- <<  12 // --------------------------------------------------------------
                                                   >>  13 //  GEANT 4 class implementation file 
                                                   >>  14 //
                                                   >>  15 //  For information related to this code contact:
                                                   >>  16 //  CERN, IT Division, ASD Group
                                                   >>  17 //  History: first implementation, based on object model of
                                                   >>  18 //  27 June 1998  H.Kurashige
                                                   >>  19 // ---------------------------------------------------------------
                                                   >>  20 //      modified GetIon                 02 Aug., 98 H.Kurashige
                                                   >>  21 //      added Remove()                  06 Nov.,98 H.Kurashige
                                                   >>  22 //      use G4NucleiPropoerties to get nuceli Mass 17  Nov.,98 H.Kurashige
                                                   >>  23 //      use G4GenericIon for process List
                                                   >>  24 //      modify fomula of Ion mass       09 Dec., 98 H.Kurashige 
                                                   >>  25 //          -----
                                                   >>  26 //      Modified GetIon methods         17 Aug. 99 H.Kurashige
                                                   >>  27 //      New design using G4VIsotopeTable          5 Oct. 99 H.Kurashige
 30                                                    28 
 31 #include "G4IonTable.hh"                       << 
 32                                                    29 
 33 #include "G4AutoDelete.hh"                     <<  30 #include "G4IonTable.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"                      31 #include "G4ParticleTable.hh"
 42 #include "G4PhysicalConstants.hh"              <<  32 #include "G4Ions.hh"
 43 #include "G4StateManager.hh"                   << 
 44 #include "G4SystemOfUnits.hh"                  << 
 45 #include "G4Threading.hh"                      << 
 46 #include "G4UImanager.hh"                          33 #include "G4UImanager.hh"
                                                   >>  34 #include "G4NucleiProperties.hh"
                                                   >>  35 
                                                   >>  36 #include "G4IsotopeProperty.hh"
 47 #include "G4VIsotopeTable.hh"                      37 #include "G4VIsotopeTable.hh"
 48 #include "G4ios.hh"                            << 
 49                                                    38 
 50 #include <algorithm>                           <<  39 #include "G4ios.hh"
 51 #include <iomanip>                             <<  40 #include "g4std/iostream"               
 52 #include <iostream>                            <<  41 #include "g4std/iomanip"               
 53 #include <sstream>                             << 
 54 #include <vector>                              << 
 55                                                << 
 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                                                    42 
104 #ifdef G4MULTITHREADED                         <<  43 #include "g4std/strstream"
105 G4Mutex G4IonTable::ionTableMutex = G4MUTEX_IN << 
106 #endif                                         << 
107                                                    44 
108 // ------------------------------------------- << 
109                                                    45 
                                                   >>  46 ////////////////////
110 G4IonTable::G4IonTable()                           47 G4IonTable::G4IonTable()
111 {                                                  48 {
112   fIonList = new G4IonList();                      49   fIonList = new G4IonList();
113                                                <<  50   fIsotopeTable = 0;
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 << 
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 }                                                  51 }
131                                                    52 
                                                   >>  53 ////////////////////
132 G4IonTable::~G4IonTable()                          54 G4IonTable::~G4IonTable()
133 {                                                  55 {
134   // delete IsotopeTable if existing           <<  56   // delete IsotopeTable if exists
135   if (fIsotopeTableList != nullptr) {          <<  57   if (fIsotopeTable != 0) delete fIsotopeTable;
136     for (const auto fIsotopeTable : *fIsotopeT <<  58   fIsotopeTable =0;
137       if (fIsotopeTable != G4NuclideTable::Get <<  59 
138         delete fIsotopeTable;                  <<  60   if (fIonList ==0) return;
139       }                                        <<  61 
140     }                                          <<  62   // delete ion objects
141     fIsotopeTableList->clear();                <<  63   G4ParticleDefinition* particle;
142     delete fIsotopeTableList;                  <<  64 #ifdef G4USE_STL
143   }                                            <<  65   G4IonList::reverse_iterator i;
144   fIsotopeTableList = nullptr;                 <<  66   for (i = fIonList->rbegin(); i!= fIonList->rend(); ++i) {
145                                                <<  67     particle = *i;
146   if (fIonList == nullptr) return;             <<  68 #else
147                                                <<  69   G4int idx;
148   // remove all contents in the Ion List       <<  70   for (idx=(fIonList->entries()-1); idx >=0 ; idx--) {
149   // No need to delete here because all partic <<  71     particle = (*fIonList)(idx);
150   fIonList->clear();                           << 
151   delete fIonList;                             << 
152   fIonList = nullptr;                          << 
153 }                                              << 
154                                                << 
155 G4IonTable* G4IonTable::GetIonTable()          << 
156 {                                              << 
157   return G4ParticleTable::GetParticleTable()-> << 
158 }                                              << 
159                                                << 
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                                                << 
184 void G4IonTable::InitializeLightIons()         << 
185 {                                              << 
186   lightions::Init();                           << 
187   antilightions::Init();                       << 
188 }                                              << 
189                                                << 
190 void G4IonTable::DestroyWorkerG4IonTable()     << 
191 {                                              << 
192   // delete IsotopeTable if existing           << 
193   if (fIsotopeTableList != nullptr) {          << 
194     for (auto fIsotopeTable : *fIsotopeTableLi << 
195       if (fIsotopeTable != G4NuclideTable::Get << 
196         delete fIsotopeTable;                  << 
197       }                                        << 
198     }                                          << 
199     fIsotopeTableList->clear();                << 
200     delete fIsotopeTableList;                  << 
201   }                                            << 
202   fIsotopeTableList = nullptr;                 << 
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   }                                            << 
224   if ((genericIon == nullptr) || (genericIon-> << 
225 #ifdef G4VERBOSE                               << 
226     if (GetVerboseLevel() > 1) {               << 
227       G4cout << "G4IonTable::CreateIon() : can << 
228              << " Z =" << Z << "  A = " << A < << 
229     }                                          << 
230 #endif                                             72 #endif
231     G4Exception("G4IonTable::CreateIon()", "PA << 
232                 "Can not create ions because G << 
233     return nullptr;                            << 
234   }                                            << 
235                                                    73 
236   G4double life = 0.0;                         <<  74     if ( !IsLightIon(particle) ) {
237   G4DecayTable* decayTable = nullptr;          <<  75       // delete if not static objects
238   G4bool stable = true;                        << 
239   G4double mu = 0.0;                           << 
240   G4double Eex = 0.0;                          << 
241   G4int lvl = 0;                               << 
242   G4int J = 0;                                 << 
243                                                << 
244   const G4IsotopeProperty* fProperty = FindIso << 
245   if (fProperty != nullptr) {                  << 
246     Eex = fProperty->GetEnergy();              << 
247     lvl = fProperty->GetIsomerLevel();         << 
248     J = fProperty->GetiSpin();                 << 
249     life = fProperty->GetLifeTime();           << 
250     mu = fProperty->GetMagneticMoment();       << 
251     decayTable = fProperty->GetDecayTable();   << 
252     stable = (life <= 0.) || (decayTable == nu << 
253     lvl = fProperty->GetIsomerLevel();         << 
254     if (lvl < 0) lvl = 9;                      << 
255   }                                            << 
256   else {                                       << 
257 #ifdef G4VERBOSE                                   76 #ifdef G4VERBOSE
258     if (GetVerboseLevel() > 1) {               <<  77       G4String name;
259       G4ExceptionDescription ed;               <<  78       if (GetVerboseLevel()>1) {
260       ed << "G4IonTable::CreateIon(): G4Isotop <<  79         G4cout << "G4IonTable:~IonTable() : delete ion of  " ;
261          << " Z = " << Z << " A = " << A << "  <<  80         G4cout << particle->GetParticleName() << G4endl;
262       if (flb != G4Ions::G4FloatLevelBase::no_ << 
263         ed << " FloatingLevel +" << G4Ions::Fl << 
264       }                                            81       }
265       ed << ".\n"                              << 
266          << " Physics quantities such as life  << 
267       G4Exception("G4IonTable::CreateIon()", " << 
268     }                                          << 
269 #endif                                             82 #endif
270     // excitation energy                       <<  83       delete particle;
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                                                << 
295   // create an ion                             << 
296   // spin, parity, isospin values are fixed    << 
297                                                << 
298   // Request lock for particle table accesses. << 
299   // this critical region.                     << 
300   //                                           << 
301   // clang-format off                          << 
302   ion = new G4Ions(   name,            mass,   << 
303                          J,              +1,   << 
304                          0,               0,   << 
305                  "nucleus",               0,   << 
306                     stable,            life,   << 
307                  "generic",               0,   << 
308                        Eex,             lvl    << 
309   // clang-format on                           << 
310                                                << 
311   // Release lock for particle table accesses. << 
312   //                                           << 
313   ion->SetPDGMagneticMoment(mu);               << 
314   static_cast<G4Ions*>(ion)->SetFloatLevelBase << 
315                                                << 
316   // No Anti particle registered               << 
317   ion->SetAntiPDGEncoding(0);                  << 
318                                                << 
319 #ifdef G4VERBOSE                               << 
320   if (GetVerboseLevel() > 1) {                 << 
321     G4cout << "G4IonTable::CreateIon() : creat << 
322            << " encoding=" << encoding;        << 
323     if (E > 0.0) {                             << 
324       G4cout << " IsomerLVL=" << lvl << " exci << 
325     }                                              84     }
326     G4cout << G4endl;                          << 
327   }                                            << 
328 #endif                                         << 
329                                                << 
330   // Add process manager to the ion            << 
331   AddProcessManager(ion);                      << 
332                                                    85 
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   }                                                86   }
343 #endif                                         << 
344                                                    87 
345   return ion;                                  <<  88   // remove all contents in the Ion List 
346 }                                              <<  89   fIonList->clear();
347                                                    90 
348 G4ParticleDefinition* G4IonTable::CreateIon(G4 <<  91   delete fIonList;
349                                             G4 <<  92   fIonList =0;
350 {                                              <<  93 }
351   if (LL == 0) return CreateIon(Z, A, E, flb); << 
352                                                    94 
353   // create hyper nucleus                      << 
354   G4ParticleDefinition* ion = nullptr;         << 
355                                                    95 
356   // check whether GenericIon has processes    <<  96 ////////////////////
357   G4ParticleDefinition* genericIon = G4Particl <<  97 // -- CreateIon method ------
358   G4ProcessManager* pman = nullptr;            <<  98 ////////////////////
359   if (genericIon != nullptr) pman = genericIon <<  99 G4ParticleDefinition* G4IonTable::CreateIon(G4int Z, G4int A, G4double E, G4int J)
360   if ((genericIon == nullptr) || (genericIon-> << 100 {
                                                   >> 101   G4ParticleDefinition* ion=0;
                                                   >> 102   
                                                   >> 103   // get ion name
                                                   >> 104   G4String name = GetIonName(Z, A, E);
                                                   >> 105   if ( name(0) == '?') {
361 #ifdef G4VERBOSE                                  106 #ifdef G4VERBOSE
362     if (GetVerboseLevel() > 1) {               << 107     if (GetVerboseLevel()>0) {
363       G4cout << "G4IonTable::CreateIon() : can << 108       G4cout << "G4IonTable::GetIon() : can not create ions " << G4endl;
364              << " Z =" << Z << "  A = " << A < << 109       G4cout << " Z =" << Z << "  A = " << A <<  G4endl;
365     }                                             110     }
366 #endif                                            111 #endif
367     G4Exception("G4IonTable::CreateIon()", "PA << 112       return 0;
368                 "Can not create ions because G << 113   } 
369     return nullptr;                            << 
370   }                                            << 
371                                                   114 
372   G4int J = 0;                                 << 115   G4double life = -1.0;
373   G4double life = 0.0;                         << 116   G4DecayTable* decayTable =0;
374   G4DecayTable* decayTable = nullptr;          << 
375   G4bool stable = true;                        << 
376                                                << 
377   // excitation energy                         << 
378   // G4double Eex = G4NuclideTable::Round(E);  << 
379   G4double Eex = E;                            << 
380   G4double mass = GetNucleusMass(Z, A, LL) + E << 
381   G4int lvl = 0;                               << 
382   // lvl is assigned to 9 temporarily          << 
383   if (Eex > 0.0) lvl = 9;                      << 
384                                                   117 
385   // PDG encoding                              << 118   G4IsotopeProperty*  fProperty = FindIsotope(Z, A, E, J);
386   G4int encoding = GetNucleusEncoding(Z, A, LL << 119   if (fProperty !=0 ){
387                                                << 120     J =    fProperty->GetiSpin();
388   // PDG charge is set to one of nucleus       << 121     E =    fProperty->GetEnergy();
389   G4double charge = G4double(Z) * eplus;       << 122     life = fProperty->GetLifeTime();
                                                   >> 123     decayTable = fProperty->GetDecayTable();
                                                   >> 124   }
390                                                   125 
                                                   >> 126   G4double mass =  GetNucleusMass(Z, A)+ E;
                                                   >> 127   G4double charge =  G4double(Z)*eplus;
                                                   >> 128   
391   // create an ion                                129   // create an ion
392   // spin, parity, isospin values are fixed    << 130   //   spin, parity, isospin values are fixed
393   //                                              131   //
394   // get ion name                              << 
395   G4String name = GetIonName(Z, A, LL, Eex, fl << 
396                                                << 
397   // clang-format off                          << 
398   ion = new G4Ions(   name,            mass,      132   ion = new G4Ions(   name,            mass,       0.0*MeV,     charge, 
399                          J,              +1,   << 133        J,              +1,             0,          
400                          0,               0,   << 134        0,               0,             0,             
401                  "nucleus",               0,   << 135      "nucleus",               0,             A,           0,
402                     stable,            life,   << 136           true,            life,    decayTable);
403                   "generic",              0,   << 
404                       Eex,              lvl    << 
405   // clang-format on                           << 
406                                                << 
407   // Release lock for particle table accesses  << 
408                                                << 
409   G4double mu = 0.0;  //  magnetic moment      << 
410   ion->SetPDGMagneticMoment(mu);               << 
411   static_cast<G4Ions*>(ion)->SetFloatLevelBase << 
412                                                << 
413   // No Anti particle registered               << 
414   ion->SetAntiPDGEncoding(0);                  << 
415                                                   137 
416 #ifdef G4VERBOSE                                  138 #ifdef G4VERBOSE
417   if (GetVerboseLevel() > 1) {                 << 139   if (GetVerboseLevel()>1) {
418     G4cout << "G4IonTable::CreateIon() : creat << 140     G4cout << "G4IonTable::GetIon() : create ion of " << name << G4endl;
419            << ", " << LL << " encoding=" << en << 141   } 
420     if (E > 0.0) {                             << 
421       G4cout << " IsomerLVL=" << lvl << " exci << 
422     }                                          << 
423     G4cout << G4endl;                          << 
424   }                                            << 
425 #endif                                            142 #endif
426                                                << 143   
427   // Add process manager to the ion               144   // Add process manager to the ion
428   AddProcessManager(ion);                      << 145   AddProcessManager(name);
429                                                << 146   
                                                   >> 147   // Set cut value same as "GenericIon"
                                                   >> 148   SetCuts(ion);
                                                   >> 149     
                                                   >> 150   if (fProperty !=0) delete fProperty;
430   return ion;                                     151   return ion;
431 }                                                 152 }
432                                                   153 
433 G4ParticleDefinition* G4IonTable::CreateIon(G4 << 154 ////////////////////
                                                   >> 155 // -- GetIon methods  ------
                                                   >> 156 ////////////////////
                                                   >> 157 G4ParticleDefinition* G4IonTable::GetIon(G4int Z, G4int A, G4int J, G4int Q)
434 {                                                 158 {
435   // always create an ion for any lvl          << 159   return GetIon(Z, A);
436   return CreateIon(Z, A, 0.0, G4Ions::FloatLev << 
437 }                                                 160 }
438                                                   161 
439 G4ParticleDefinition* G4IonTable::CreateIon(G4 << 162 ////////////////////
                                                   >> 163 G4ParticleDefinition* G4IonTable::GetIon(G4int Z, G4int A, G4int J)
440 {                                                 164 {
441   return (LL == 0) ? CreateIon(Z, A, 0.0, G4Io << 165   return GetIon( Z, A, 0.0, J);
442                    : CreateIon(Z, A, LL, 0.0,  << 
443 }                                              << 
444                                                << 
445 G4ParticleDefinition* G4IonTable::GetIon(G4int << 
446 {                                              << 
447   return GetIon(Z, A, 0.0, G4Ions::G4FloatLeve << 
448 }                                              << 
449                                                << 
450 G4ParticleDefinition* G4IonTable::GetIon(G4int << 
451 {                                              << 
452   return (LL == 0) ? GetIon(Z, A, 0.0, G4Ions: << 
453                    : GetIon(Z, A, LL, 0.0, G4I << 
454 }                                                 166 }
455                                                   167 
                                                   >> 168 ////////////////////
456 G4ParticleDefinition* G4IonTable::GetIon(G4int    169 G4ParticleDefinition* G4IonTable::GetIon(G4int Z, G4int A, G4double E, G4int J)
457 {                                                 170 {
458   return GetIon(Z, A, E, G4Ions::G4FloatLevelB << 171   if ( (A<1) || (Z>numberOfElements) || (Z<=0) || (J<0) || (E<0.0) ) {
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                               << 
471     if (GetVerboseLevel() > 0) {               << 
472       G4cout << "G4IonTable::GetIon() : illega << 
473              << " Z =" << Z << "  A = " << A < << 
474     }                                          << 
475 #endif                                         << 
476     return nullptr;                            << 
477   }                                            << 
478   auto flb1 = flb;                             << 
479                                                << 
480   // Search ions with A, Z                     << 
481   G4ParticleDefinition* ion = FindIon(Z, A, E, << 
482                                                << 
483   // find out ground state floating level      << 
484   if (ion == nullptr && E == 0.0) {            << 
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                                                << 
494   // create ion                                << 
495 #ifdef G4MULTITHREADED                         << 
496   if (ion == nullptr) {                        << 
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   }                                            << 
508 #else                                          << 
509   if (ion == nullptr) ion = CreateIon(Z, A, E, << 
510 #endif                                         << 
511                                                << 
512   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 }                                              << 
525                                                << 
526 G4ParticleDefinition* G4IonTable::GetIon(G4int << 
527                                          G4Ion << 
528 {                                              << 
529   if (LL == 0) return GetIon(Z, A, E, flb, J); << 
530                                                << 
531   if (A < 2 || Z < 0 || Z > A - LL || LL > A | << 
532 #ifdef G4VERBOSE                               << 
533     if (GetVerboseLevel() > 0) {               << 
534       G4cout << "G4IonTable::GetIon() : illega << 
535              << " Z =" << Z << "  A = " << A < << 
536     }                                          << 
537 #endif                                         << 
538     return nullptr;                            << 
539   }                                            << 
540   if (A == 2) {                                << 
541 #ifdef G4VERBOSE                                  172 #ifdef G4VERBOSE
542     if (GetVerboseLevel() > 0) {               << 173     if (GetVerboseLevel()>0) {
543       G4cout << "G4IonTable::GetIon() : No bou << 174       G4cout << "G4IonTable::GetIon() : illegal atomic number/mass" << G4endl;
544              << " Z =" << Z << "  A = " << A < << 175       G4cout << " Z =" << Z << "  A = " << A <<  "  E = " << E/keV << G4endl;
545     }                                             176     }
546 #endif                                            177 #endif
547     return nullptr;                            << 178     G4Exception("G4IonTable::GetIon : illegal atomic number/mass ");
548   }                                               179   }
549                                                   180 
550   // Search ions with A, Z                     << 181   // Search ions with A, Z 
551   G4ParticleDefinition* ion = FindIon(Z, A, LL << 182   G4ParticleDefinition* ion = FindIon(Z,A,E,J);
552                                                   183 
553   // create ion                                   184   // create ion
554 #ifdef G4MULTITHREADED                         << 185   if (ion == 0) {
555   if (ion == nullptr) {                        << 186     ion = CreateIon(Z, A, 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   }                                               187   }
567 #else                                          << 
568   if (ion == nullptr) ion = CreateIon(Z, A, LL << 
569 #endif                                         << 
570                                                << 
571   return ion;                                  << 
572 }                                              << 
573                                                   188 
574 G4ParticleDefinition* G4IonTable::GetIon(G4int << 189   return ion;  
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 }                                                 190 }
590                                                   191 
                                                   >> 192 ////////////////////
591 G4ParticleDefinition* G4IonTable::FindIon(G4in    193 G4ParticleDefinition* G4IonTable::FindIon(G4int Z, G4int A, G4double E, G4int J)
592 {                                                 194 {
593   return FindIon(Z, A, E, G4Ions::G4FloatLevel << 195   const G4double EnergyTorelance = 0.1 * keV;
594 }                                              << 
595                                                << 
596 G4ParticleDefinition* G4IonTable::FindIon(G4in << 
597 {                                              << 
598   return FindIon(Z, A, E, G4Ions::FloatLevelBa << 
599 }                                              << 
600                                                   196 
601 G4ParticleDefinition* G4IonTable::FindIon(G4in << 197   if ( (A<1) || (Z>numberOfElements) || (Z<=0) || (J<0) || (E<0.0)) {
602                                           G4Io << 
603 {                                              << 
604   if ((A < 1) || (Z <= 0) || (J < 0) || (E < 0 << 
605 #ifdef G4VERBOSE                                  198 #ifdef G4VERBOSE
606     if (GetVerboseLevel() > 0) {               << 199     if (GetVerboseLevel()>0) {
607       G4cout << "G4IonTable::FindIon(): illega << 200       G4cout << "G4IonTable::FindIon() : illegal atomic number/mass or excitation level " << G4endl;
608              << " or excitation level:" << G4e << 201       G4cout << " Z =" << Z << "  A = " << A <<  "  E = " << E/keV << G4endl;
609              << "  E = " << E / keV << G4endl; << 
610     }                                             202     }
611 #endif                                            203 #endif
612     G4Exception("G4IonTable::FindIon()", "PART << 204     return 0;
613     return nullptr;                            << 
614   }                                               205   }
615   // Search ions with A, Z ,E                     206   // Search ions with A, Z ,E
616   //  !! J is omitted now !!                   << 207   //  !! J is moitted now !!
617   const G4ParticleDefinition* ion = nullptr;   << 208   G4ParticleDefinition* ion;
618   G4bool isFound = false;                         209   G4bool isFound = false;
619                                                   210 
620   // check if light ion                        << 211   // -- loop over all particles in Ion table
621   ion = GetLightIon(Z, A);                     << 212 #ifdef G4USE_STL
622   if (ion != nullptr && E == 0.0) {            << 213   G4IonList::iterator idx;
623     // light ion                               << 214   for (idx = fIonList->begin(); idx!= fIonList->end(); ++idx) {
624     isFound = true;                            << 215     ion = *idx;
625   }                                            << 216 #else
626   else {                                       << 217   G4int idx;
627     // -- loop over all particles in Ion table << 218   for (idx= 0; idx < fIonList->entries() ; ++idx) {
628     G4int encoding = GetNucleusEncoding(Z, A); << 219     ion = (*fIonList)(idx);
629     const G4ParticleDefinition* ion1 = nullptr << 
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;                          << 
647       ion = ion1;                              << 
648     }                                          << 
649   }                                            << 
650                                                << 
651   if (isFound) {                               << 
652     return const_cast<G4ParticleDefinition*>(i << 
653   }                                            << 
654                                                << 
655   return nullptr;                              << 
656 }                                              << 
657                                                << 
658 G4ParticleDefinition* G4IonTable::FindIon(G4in << 
659 {                                              << 
660   return (LL == 0) ? FindIon(Z, A, E, G4Ions:: << 
661                    : FindIon(Z, A, LL, E, G4Io << 
662 }                                              << 
663                                                << 
664 G4ParticleDefinition* G4IonTable::FindIon(G4in << 
665                                           G4in << 
666 {                                              << 
667   return FindIon(Z, A, LL, E, G4Ions::FloatLev << 
668 }                                              << 
669                                                << 
670 G4ParticleDefinition* G4IonTable::FindIon(G4in << 
671                                           G4Io << 
672 {                                              << 
673   if (LL == 0) return FindIon(Z, A, E, flb, J) << 
674                                                << 
675   if (A < 2 || Z < 0 || Z > A - LL || LL > A | << 
676 #ifdef G4VERBOSE                               << 
677     if (GetVerboseLevel() > 0) {               << 
678       G4cout << "G4IonTable::FindIon(): illega << 
679              << " or excitation level:" << G4e << 
680              << "  E = " << E / keV << G4endl; << 
681     }                                          << 
682 #endif                                            220 #endif
683     G4Exception("G4IonTable::FindIon()", "PART << 
684     return nullptr;                            << 
685   }                                            << 
686   // Search ions with A, Z ,E                  << 
687   //  !! J is omitted now !!                   << 
688   const G4ParticleDefinition* ion = nullptr;   << 
689   G4bool isFound = false;                      << 
690                                                   221 
691   // -- loop over all particles in Ion table   << 222     // Z = Atomic Number 
692   G4int encoding = GetNucleusEncoding(Z, A, LL << 223     G4int anAtomicNumber = 0;
693   for (auto i = fIonList->find(encoding); i != << 224     // A = baryon number
694     ion = i->second;                           << 225     G4int anAtomicMass = 0;
695     if ((ion->GetAtomicNumber() != Z) || (ion- << 
696     if (ion->GetQuarkContent(3) != LL) break;  << 
697     // excitation level                           226     // excitation level
698     G4double anExcitaionEnergy = ((const G4Ion << 227     G4double anExcitaionEnergy =0.0;
699     if (std::fabs(E - anExcitaionEnergy) < pNu << 
700       if (((const G4Ions*)(ion))->GetFloatLeve << 
701         isFound = true;                        << 
702         break;                                 << 
703       }                                        << 
704     }                                          << 
705   }                                            << 
706                                                << 
707   if (isFound) {                               << 
708     return const_cast<G4ParticleDefinition*>(i << 
709   }                                            << 
710                                                << 
711   return nullptr;                              << 
712 }                                              << 
713                                                << 
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                                                << 
725 G4int G4IonTable::GetNucleusEncoding(G4int Z,  << 
726 {                                              << 
727   // PDG code for Ions                         << 
728   // Nuclear codes are given as 10-digit numbe << 
729   // For a nucleus consisting of np protons an << 
730   // A = np + nn and Z = np.                   << 
731   // I gives the isomer level, with I = 0 corr << 
732   // to the ground state and I >0 to excitatio << 
733                                                << 
734   if (Z == 1 && A == 1 && E == 0.0) return 221 << 
735                                                << 
736   G4int encoding = 1000000000;                 << 
737   encoding += Z * 10000;                       << 
738   encoding += A * 10;                          << 
739   if (lvl > 0 && lvl < 10)                     << 
740     encoding += lvl;  // isomer level          << 
741   else if (E > 0.0)                            << 
742     encoding += 9;  // isomer level            << 
743                                                << 
744   return encoding;                             << 
745 }                                              << 
746                                                << 
747 G4int G4IonTable::GetNucleusEncoding(G4int Z,  << 
748 {                                              << 
749   // Get PDG code for Hyper-Nucleus Ions       << 
750   // Nuclear codes are given as 10-digit numbe << 
751   // For a nucleus consisting of np protons an << 
752   // A = np + nn +nlambda and Z = np.          << 
753   // LL = nlambda                              << 
754   // I gives the isomer level, with I = 0 corr << 
755   // to the ground state and I >0 to excitatio << 
756                                                << 
757   G4int encoding = GetNucleusEncoding(Z, A, E, << 
758   if (LL == 0) return encoding;                << 
759   encoding += LL * 10000000;                   << 
760   if (Z == 1 && A == 1 && E == 0.0) encoding = << 
761                                                << 
762   return encoding;                             << 
763 }                                              << 
764                                                << 
765 G4bool G4IonTable::GetNucleusByEncoding(G4int  << 
766 {                                              << 
767   if (encoding <= 0) return false;  // anti pa << 
768                                                << 
769   if (encoding == 2212)  // proton             << 
770   {                                            << 
771     Z = 1;                                     << 
772     A = 1;                                     << 
773     E = 0.0;                                   << 
774     lvl = 0;                                   << 
775     return true;                               << 
776   }                                            << 
777                                                << 
778   encoding -= 1000000000;                      << 
779   Z = encoding / 10000;                        << 
780   encoding -= 10000 * Z;                       << 
781   A = encoding / 10;                           << 
782   lvl = encoding % 10;                         << 
783   return true;                                 << 
784 }                                              << 
785                                                << 
786 G4bool G4IonTable::GetNucleusByEncoding(G4int  << 
787                                         G4int& << 
788 {                                              << 
789   if (encoding <= 0) return false;  // anti pa << 
790                                                << 
791   if (encoding == 3122)  // Lambda             << 
792   {                                            << 
793     Z = 1;                                     << 
794     A = 1;                                     << 
795     LL = 1;                                    << 
796     E = 0.0;                                   << 
797     lvl = 0;                                   << 
798     return true;                               << 
799   }                                            << 
800                                                << 
801   if (encoding % 10 != 0) {                    << 
802     // !!!not supported for excitation states  << 
803     return false;                              << 
804   }                                            << 
805   if (encoding < 1000000000) {                 << 
806     // anti particle                           << 
807     return false;                              << 
808   }                                            << 
809                                                   228 
810   encoding -= 1000000000;                      << 229     if ( IsLightIon(ion) ) {
811   LL = encoding / 10000000;                    << 230       anAtomicNumber = int(ion->GetPDGCharge()/eplus);
812   encoding -= 10000000 * LL;                   << 231       anAtomicMass = ion->GetBaryonNumber();
813   Z = encoding / 10000;                        << 232       anExcitaionEnergy = 0.0;
814   encoding -= 10000 * Z;                       << 233 
815   A = encoding / 10;                           << 234     } else  {
816   lvl = encoding % 10;                         << 235       anAtomicNumber   = ((const G4Ions*)(ion))->GetAtomicNumber();
817   return true;                                 << 236       anAtomicMass    =  ((const G4Ions*)(ion))->GetAtomicMass();
818 }                                              << 237       anExcitaionEnergy = ((const G4Ions*)(ion))->GetExcitationEnergy();
819                                                << 238     }
820 G4String G4IonTable::GetIonName(G4int Z, G4int << 239 
821                                 G4Ions::G4Floa << 240     if ( (A == anAtomicMass) && 
822 {                                              << 241          (Z == anAtomicNumber ) && 
823   G4String name = GetIonName(Z, A, 0);         << 242    ( abs(E - anExcitaionEnergy ) < EnergyTorelance ) ) {
824                                                << 243       isFound = true;
825   // Excited energy or floating level          << 244       break;
826   if (E > 0 || flb != G4Ions::G4FloatLevelBase << 
827     std::ostringstream os;                     << 
828     os.setf(std::ios::fixed);                  << 
829     os.precision(3);                           << 
830     // Excited nucleus                         << 
831     os << '[' << E / keV;                      << 
832     if (flb != G4Ions::G4FloatLevelBase::no_Fl << 
833       os << G4Ions::FloatLevelBaseChar(flb);   << 
834     }                                             245     }
835     os << ']';                                 << 
836     name += os.str();                          << 
837   }                                               246   }
838                                                   247 
839   return name;                                 << 248   if ( isFound ){ 
840 }                                              << 249     return ion;
841                                                << 250   } else {
842 G4String G4IonTable::GetIonName(G4int Z, G4int << 251     return 0;
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   }                                               252   }
850   name += GetIonName(Z, A, E, flb);            << 
851   return name;                                 << 
852 }                                                 253 }
853                                                   254 
854 G4String G4IonTable::GetIonName(G4int Z, G4int << 255 /////////////////
855 {                                              << 256 G4String G4IonTable::GetIonName(G4int Z, G4int A, G4double E) const 
856   std::ostringstream os;                       << 257 {
857                                                << 258   G4String name;
858   // Atomic number                             << 259   if ( (0< Z) && (Z <=numberOfElements) ) {
859   if ((0 < Z) && (Z <= numberOfElements)) {    << 260     name = elementName[Z-1];
860     os << elementName[Z - 1];                  << 261   } else {
861   }                                            << 262     return "?";
862   else {                                       << 263   }
863     os << "E" << Z << "-";                     << 264   char val[50];
864   }                                            << 265   G4std::ostrstream os(val,50);
865   // Atomic Mass                               << 266   os.setf(G4std::ios::fixed);
866   os << A;                                     << 267   os << A << '[' << G4std::setprecision(1) << E/keV << ']' << '\0';
867                                                << 268   name += val;
868   if (lvl > 0) {                               << 
869     // Isomer level for Excited nucelus        << 
870     os << '[' << lvl << ']';                   << 
871   }                                            << 
872   G4String name = os.str();                    << 
873   return name;                                    269   return name;
874 }                                                 270 }
875                                                   271 
876 G4String G4IonTable::GetIonName(G4int Z, G4int << 
877 {                                              << 
878   if (LL == 0) return GetIonName(Z, A, lvl);   << 
879   G4String name = "";                          << 
880   for (G4int i = 0; i < LL; ++i) {             << 
881     name += "L";                               << 
882   }                                            << 
883   name += GetIonName(Z, A, lvl);               << 
884   return name;                                 << 
885 }                                              << 
886                                                   272 
887 G4bool G4IonTable::IsIon(const G4ParticleDefin << 273 /////////////////
                                                   >> 274 G4bool G4IonTable::IsIon(G4ParticleDefinition* particle)
888 {                                                 275 {
889   // Return true if the particle is ion        << 276   // return true if the particle is ion
890   static const G4String nucleus("nucleus");    << 
891   static const G4String proton("proton");      << 
892                                                << 
893   // Neutron is not ion                        << 
894   if ((particle->GetAtomicMass() > 0) && (part << 
895     return particle->GetBaryonNumber() > 0;    << 
896   }                                            << 
897                                                   277 
898   // Particles derived from G4Ions             << 278   //  particles derived from G4VIon and G4Ions
899   if (particle->GetParticleType() == nucleus)  << 279   G4bool value = (particle->GetParticleType() == "nucleus");
900                                                   280 
901   // Proton (Hydrogen nucleus)                 << 281   // proton (Hydrogen nucleus)
902   if (particle->GetParticleName() == proton) r << 282   value = value || (particle->GetParticleName() == "proton");
903                                                   283 
904   return false;                                << 284   return value;
905 }                                                 285 }
906                                                   286 
907 G4bool G4IonTable::IsAntiIon(const G4ParticleD << 287 /////////////////
                                                   >> 288 G4bool G4IonTable::IsLightIon(G4ParticleDefinition* particle) const
908 {                                                 289 {
909   // Return true if the particle is ion        << 290    // return true if the particle is pre-defined ion
910   static const G4String anti_nucleus("anti_nuc << 291    G4String name = particle->GetParticleName();
911   static const G4String anti_proton("anti_prot << 
912                                                << 
913   // Anti_neutron is not ion                   << 
914   if ((particle->GetAtomicMass() > 0) && (part << 
915     return particle->GetBaryonNumber() < 0;    << 
916   }                                            << 
917                                                << 
918   // Particles derived from G4Ions             << 
919   if (particle->GetParticleType() == anti_nucl << 
920                                                   292 
921   // Anti_proton (Anti_Hydrogen nucleus)       << 293    G4bool value  =  (name == "proton");
922   if (particle->GetParticleName() == anti_prot << 294    value = value || (name == "neutron");
923                                                << 295    value = value || (name == "alpha");
924   return false;                                << 296    value = value || (name == "deuteron");
925 }                                              << 297    value = value || (name == "triton") ;
926                                                << 298    value = value || (name == "He3");
927 G4bool G4IonTable::IsLightIon(const G4Particle << 299    value = value || (name == "GenericIon") ;
928 {                                              << 300    
929   static const std::string names[] = {"proton" << 301    return value;
930                                                << 302 } 
931   // Return true if the particle is pre-define << 
932   return std::find(names, names + 5, (particle << 
933 }                                              << 
934                                                << 
935 G4bool G4IonTable::IsLightAntiIon(const G4Part << 
936 {                                              << 
937   static const std::string names[] = {"anti_pr << 
938                                       "anti_He << 
939                                                << 
940   // Return true if the particle is pre-define << 
941   return std::find(names, names + 5, (particle << 
942 }                                              << 
943                                                   303 
                                                   >> 304 /////////////////
944 G4ParticleDefinition* G4IonTable::GetLightIon(    305 G4ParticleDefinition* G4IonTable::GetLightIon(G4int Z, G4int A) const
945 {                                                 306 {
946   // Returns pointer to pre-defined ions       << 307   // returns pointer to pre-defined ions 
947   const G4ParticleDefinition* ion = nullptr;   << 
948   if ((Z <= 2)) {                              << 
949 #ifndef G4MULTITHREADED                        << 
950     // In sequential use lazy-initialization   << 
951     lightions::Init();                         << 
952 #endif                                         << 
953     if ((Z == 1) && (A == 1)) {                << 
954       ion = lightions::p_proton;               << 
955     }                                          << 
956     else if ((Z == 1) && (A == 2)) {           << 
957       ion = lightions::p_deuteron;             << 
958     }                                          << 
959     else if ((Z == 1) && (A == 3)) {           << 
960       ion = lightions::p_triton;               << 
961     }                                          << 
962     else if ((Z == 2) && (A == 4)) {           << 
963       ion = lightions::p_alpha;                << 
964     }                                          << 
965     else if ((Z == 2) && (A == 3)) {           << 
966       ion = lightions::p_He3;                  << 
967     }                                          << 
968   }                                            << 
969   return const_cast<G4ParticleDefinition*>(ion << 
970 }                                              << 
971                                                   308 
972 G4ParticleDefinition* G4IonTable::GetLightAnti << 309   G4ParticleDefinition* ion=0;
973 {                                              << 310   G4double mass;
974   // Returns pointer to pre-defined ions       << 311   if ( (Z<=2) ) {
975   const G4ParticleDefinition* ion = nullptr;   << 312     if ( (Z==1)&&(A==1) ) {
976   if ((Z <= 2)) {                              << 313       ion = G4ParticleTable::GetParticleTable()->FindParticle("proton"); // proton 
977 #ifndef G4MULTITHREADED                        << 314 
978     // In sequential use lazy-initialization   << 315     } else if ( (Z==0)&&(A==1) ) {
979     antilightions::Init();                     << 316       ion = G4ParticleTable::GetParticleTable()->FindParticle("neutron"); // neutron 
980 #endif                                         << 317     } else if ( (Z==1)&&(A==2) ) {
981     if ((Z == 1) && (A == 1)) {                << 318       ion = G4ParticleTable::GetParticleTable()->FindParticle("deuteron"); // deuteron 
982       ion = antilightions::p_proton;           << 319     } else if ( (Z==1)&&(A==3) ) {
983     }                                          << 320       ion = G4ParticleTable::GetParticleTable()->FindParticle("triton"); // tritoon 
984     else if ((Z == 1) && (A == 2)) {           << 321     } else if ( (Z==2)&&(A==4) ) {
985       ion = antilightions::p_deuteron;         << 322       ion = G4ParticleTable::GetParticleTable()->FindParticle("alpha"); // alpha 
986     }                                          << 323 
987     else if ((Z == 1) && (A == 3)) {           << 324     } else if ( (Z==2)&&(A==3) ) {
988       ion = antilightions::p_triton;           << 325       ion = G4ParticleTable::GetParticleTable()->FindParticle("He3"); // He3 
989     }                                          << 
990     else if ((Z == 2) && (A == 4)) {           << 
991       ion = antilightions::p_alpha;            << 
992     }                                          << 
993     else if ((Z == 2) && (A == 3)) {           << 
994       ion = antilightions::p_He3;              << 
995     }                                             326     }
996   }                                               327   }
997   return const_cast<G4ParticleDefinition*>(ion << 328   return ion;
998 }                                                 329 }
999                                                   330 
1000 G4double G4IonTable::GetNucleusMass(G4int Z,  << 331 /////////////////
                                                   >> 332 // -- GetNucleusMass/GetIonMass ---
                                                   >> 333 /////////////////
                                                   >> 334 G4double  G4IonTable::GetNucleusMass(G4int Z, G4int A) const
1001 {                                                335 {
1002   if ((A < 1) || (Z < 0) || (LL < 0) || (lvl  << 336   if ( (A<1) || (Z>numberOfElements) || (Z<0)) {
1003 #ifdef G4VERBOSE                                 337 #ifdef G4VERBOSE
1004     if (GetVerboseLevel() > 0) {              << 338     if (GetVerboseLevel()>0) {
1005       G4cout << "G4IonTable::GetNucleusMass() << 339       G4cout << "G4IonTable::GetNucleusMass() : illegal atomic number/mass " << G4endl;
1006              << " Z =" << Z << "  A = " << A  << 340       G4cout << " Z =" << Z << "  A = " << A  << G4endl;
1007     }                                            341     }
1008 #endif                                           342 #endif
1009     G4Exception("G4IonTable::GetNucleusMass() << 343     G4Exception("G4IonTable::GetNucleusMass() : illegal atomic number/mass ");
1010                 "illegal atomic number/mass") << 
1011     return -1.0;                              << 
1012   }                                              344   }
1013                                                  345 
                                                   >> 346   // calculate nucleus mass
                                                   >> 347   G4ParticleDefinition* ion=GetLightIon(Z, A);
1014   G4double mass;                                 348   G4double mass;
1015   if (LL == 0) {                              << 
1016     // calculate nucleus mass                 << 
1017     const G4ParticleDefinition* ion = GetLigh << 
1018                                                  349 
1019     if (ion != nullptr) {                     << 350   if (ion!=0) {
1020       mass = ion->GetPDGMass();               << 351      mass = ion->GetPDGMass();
1021     }                                         << 352 
1022     else {                                    << 353   } else {
1023       // Use G4NucleiProperties::GetNuclearMa << 354 
1024       mass = G4NucleiProperties::GetNuclearMa << 355     // use G4NucleiProperties::GetNuclearMass
1025     }                                         << 356     mass = G4NucleiProperties::GetNuclearMass(A, Z);
1026                                                  357 
1027     // Isomer                                 << 
1028     if (lvl > 0) {                            << 
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   }                                              358   }
                                                   >> 359 
1055   return mass;                                   360   return mass;
1056 }                                                361 }
1057                                                  362 
1058 G4double G4IonTable::GetIsomerMass(G4int Z, G << 363 //////////////////
                                                   >> 364 G4double  G4IonTable::GetIonMass(G4int Z, G4int A) const
1059 {                                                365 {
1060   return GetNucleusMass(Z, A, 0, lvl);        << 366    return GetNucleusMass(Z,A);
1061 }                                                367 }
1062                                                  368 
1063 G4double G4IonTable::GetIonMass(G4int Z, G4in << 
1064 {                                             << 
1065   return GetNucleusMass(Z, A, LL, lvl);       << 
1066 }                                             << 
1067                                                  369 
1068 void G4IonTable::clear()                      << 370 /////////////////
                                                   >> 371 // -- Methods for handling conatiner  ---
                                                   >> 372 /////////////////
                                                   >> 373 void G4IonTable::Insert(G4ParticleDefinition* particle)
1069 {                                                374 {
1070   if (G4ParticleTable::GetParticleTable()->Ge << 375   if (IsIon(particle)) {
1071     G4Exception("G4IonTable::clear()", "PART1 << 376 #ifdef G4USE_STL
1072                 "No effects because readyToUs << 377     fIonList->push_back(particle);
1073     return;                                   << 378 #else
1074   }                                           << 379     fIonList->insert(particle);
1075                                               << 
1076 #ifdef G4VERBOSE                              << 
1077   if (GetVerboseLevel() > 2) {                << 
1078     G4cout << "G4IonTable::Clear() : number o << 
1079     G4cout << fIonList->size() << G4endl;     << 
1080   }                                           << 
1081 #endif                                           380 #endif
1082   fIonList->clear();                          << 381   } else {
                                                   >> 382     //#ifdef G4VERBOSE
                                                   >> 383     //if (GetVerboseLevel()>0) {
                                                   >> 384     //  G4cout << "G4IonTable::Insert :" << particle->GetParticleName() ;
                                                   >> 385     //  G4cout << " is not ions" << G4endl; 
                                                   >> 386     //}
                                                   >> 387     //#endif
                                                   >> 388   }
1083 }                                                389 }
1084                                                  390 
1085 void G4IonTable::Insert(const G4ParticleDefin << 391 /////////////////
                                                   >> 392 void G4IonTable::Remove(G4ParticleDefinition* particle)
1086 {                                                393 {
1087   if (!IsIon(particle)) return;               << 394   if (IsIon(particle)) {
1088   if (Contains(particle)) return;             << 395 #ifdef G4USE_STL
1089                                               << 396     G4IonList::iterator idx;
1090   G4int Z = particle->GetAtomicNumber();      << 397     for (idx = fIonList->begin(); idx!= fIonList->end(); ++idx) {
1091   G4int A = particle->GetAtomicMass();        << 398       if ( particle == *idx) {
1092   G4int LL = particle->GetQuarkContent(3);  / << 399         fIonList->erase(idx);
1093   G4int encoding = GetNucleusEncoding(Z, A, L << 
1094                                               << 
1095   // Register the ion with its encoding of th << 
1096   fIonListShadow->insert(std::pair<const G4in << 
1097 }                                             << 
1098                                               << 
1099 void G4IonTable::InsertWorker(const G4Particl << 
1100 {                                             << 
1101   if (particle == nullptr) return;            << 
1102                                               << 
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       }                                          400       }
1114     }                                            401     }
1115   }                                           << 402 #else
1116   if (found) return;                          << 403     fIonList->remove(particle);
1117                                               << 
1118   // Register the ion with its encoding of th << 
1119   fIonList->insert(std::pair<const G4int, con << 
1120 }                                             << 
1121                                               << 
1122 void G4IonTable::Remove(const G4ParticleDefin << 
1123 {                                             << 
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                                           404 #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                                                  405 
                                                   >> 406   } else {
1145 #ifdef G4VERBOSE                                 407 #ifdef G4VERBOSE
1146     if (GetVerboseLevel() > 0) {              << 408     if (GetVerboseLevel()>0) {
1147       G4cout << particle->GetParticleName() < << 409       G4cout << "G4IonTable::Remove :" << particle->GetParticleName() ;
                                                   >> 410       G4cout << " is not ions" << G4endl; 
1148     }                                            411     }
1149 #endif                                           412 #endif
1150   }                                              413   }
1151                                                  414 
1152   if (IsIon(particle)) {                      << 
1153     G4int Z = particle->GetAtomicNumber();    << 
1154     G4int A = particle->GetAtomicMass();      << 
1155     G4int LL = particle->GetQuarkContent(3);  << 
1156     G4int encoding = GetNucleusEncoding(Z, A, << 
1157     if (encoding != 0) {                      << 
1158       for (auto i = fIonListShadow->find(enco << 
1159         if (particle == i->second) {          << 
1160           fIonListShadow->erase(i);           << 
1161           break;                              << 
1162         }                                     << 
1163       }                                       << 
1164     }                                         << 
1165   }                                           << 
1166   else {                                      << 
1167 #ifdef G4VERBOSE                              << 
1168     if (GetVerboseLevel() > 1) {              << 
1169       G4cout << "G4IonTable::Remove :" << par << 
1170     }                                         << 
1171 #endif                                        << 
1172   }                                           << 
1173 }                                                415 }
1174                                                  416 
1175 void G4IonTable::DumpTable(const G4String& pa << 417 
                                                   >> 418 
                                                   >> 419 /////////////////
                                                   >> 420 // -- Dump Information 
                                                   >> 421 /////////////////
                                                   >> 422 void G4IonTable::DumpTable(const G4String &particle_name) const
1176 {                                                423 {
1177   const G4ParticleDefinition* ion;            << 424   G4ParticleDefinition* ion;
1178   for (const auto& idx : *fIonList) {         << 425 #ifdef G4USE_STL
1179     ion = idx.second;                         << 426   G4IonList::iterator idx;
1180     if ((particle_name == "ALL") || (particle << 427   for (idx = fIonList->begin(); idx!= fIonList->end(); ++idx) {
                                                   >> 428     ion = *idx;
                                                   >> 429 #else
                                                   >> 430   for (G4int idx= 0; idx < fIonList->entries() ; idx++) {
                                                   >> 431     ion = (*fIonList)(idx);
                                                   >> 432 #endif 
                                                   >> 433     if (( particle_name == "ALL" ) || (particle_name == "all")){
1181       ion->DumpTable();                          434       ion->DumpTable();
1182     }                                         << 435     } else if ( particle_name == ion->GetParticleName() ) {
1183     else if (particle_name == ion->GetParticl << 
1184       ion->DumpTable();                          436       ion->DumpTable();
1185     }                                            437     }
1186   }                                              438   }
1187 }                                                439 }
1188                                                  440 
1189 // ------------------------------------------ << 441 /////////////////
1190 //                                            << 442 const G4String G4IonTable::elementName[] = {
1191 // clang-format off                           << 
1192 const G4String G4IonTable::elementName[] =    << 
1193 {                                             << 
1194   "H",                                           443   "H",                                                                                                "He", 
1195   "Li", "Be",                                    444   "Li", "Be",                                                             "B",  "C",  "N",  "O", "F", "Ne", 
1196   "Na", "Mg",                                    445   "Na", "Mg",                                                             "Al", "Si", "P", "S", "Cl", "Ar", 
1197   "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe    446   "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    447   "Rb", "Sr", "Y", "Zr", "Nb", "Mo","Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I",  "Xe", 
1199   "Cs", "Ba",                                    448   "Cs", "Ba", 
1200               "La", "Ce", "Pr", "Nd", "Pm", "    449               "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", 
1201                    "Hf", "Ta", "W", "Re", "Os    450                    "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", 
1202   "Fr", "Ra",                                    451   "Fr", "Ra", 
1203               "Ac", "Th", "Pa",  "U", "Np", "    452               "Ac", "Th", "Pa",  "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr",
1204               "Rf", "Db", "Sg", "Bh", "Hs", " << 453               "Db", "Jl", "Rf", "Bh", "Hn", "Mt", "Xa"
                                                   >> 454   
1205 };                                               455 };
1206 // clang-format on                            << 
1207                                                  456 
                                                   >> 457 
                                                   >> 458 /////////////////
1208 G4int G4IonTable::GetVerboseLevel() const        459 G4int G4IonTable::GetVerboseLevel() const
1209 {                                                460 {
1210   return G4ParticleTable::GetParticleTable()-    461   return G4ParticleTable::GetParticleTable()->GetVerboseLevel();
1211 }                                                462 }
1212                                                  463 
1213 void G4IonTable::AddProcessManager(G4Particle << 464 /////////////////
                                                   >> 465 void  G4IonTable::AddProcessManager(const G4String& name)
1214 {                                                466 {
1215   if (ion->IsGeneralIon()) {                  << 467   // create command string for addProcManager
1216     // Check whether GenericIon has processes << 468   char cmdAdd[60];
1217     G4ParticleDefinition* genericIon = G4Part << 469   G4std::ostrstream osAdd(cmdAdd,60);
1218                                               << 470   osAdd << "/run/particle/addProcManager "<< name << '\0';
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                                                  471 
1230     ion->SetParticleDefinitionID(genericIon-> << 472   // set /control/verbose 0
1231   }                                           << 473   G4int tempVerboseLevel = G4UImanager::GetUIpointer()->GetVerboseLevel();
1232   else {                                      << 474   G4UImanager::GetUIpointer()->SetVerboseLevel(0);
1233     // Is this a MuonicAtom ?                 << 
1234     auto muatom = dynamic_cast<G4MuonicAtom*> << 
1235                                               << 
1236     if (muatom != nullptr) {                  << 
1237 #ifdef G4VERBOSE                              << 
1238       if (GetVerboseLevel() > 1) {            << 
1239         G4cout << "G4IonTable::AddProcessMana << 
1240                << "MuonicAtom dynamic_cast su << 
1241       }                                       << 
1242 #endif                                        << 
1243       // Check whether GenericMuonicAtom has  << 
1244       G4ParticleDefinition* genericMA = G4Par << 
1245                                                  475 
1246       G4ProcessManager* pman = nullptr;       << 476   // issue /run/particle/addProcManage
1247       if (genericMA != nullptr) pman = generi << 477   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                                                  478 
1257       ion->SetParticleDefinitionID(genericMA- << 479   // retreive  /control/verbose 
1258     }                                         << 480   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 }                                                481 }
1269                                               << 482  
1270 void G4IonTable::RegisterIsotopeTable(G4VIsot << 483 /////////////////
                                                   >> 484 void  G4IonTable::SetCuts(G4ParticleDefinition* ion)
1271 {                                                485 {
1272   // check duplication                        << 486   // Set cut value same as "GenericIon"
1273   G4String name = table->GetName();           << 487   G4ParticleDefinition* genericIon=G4ParticleTable::GetParticleTable()->FindParticle("GenericIon");
1274   for (const auto fIsotopeTable : *fIsotopeTa << 488   if (genericIon == 0) {
1275     if (name == fIsotopeTable->GetName()) ret << 489     G4Exception("G4IonTable::SetCuts : GenericIon is not defined !!");
1276   }                                           << 490   }  
1277   // register                                 << 
1278   fIsotopeTableList->push_back(table);        << 
1279 }                                             << 
1280                                               << 
1281 G4VIsotopeTable* G4IonTable::GetIsotopeTable( << 
1282 {                                             << 
1283   G4VIsotopeTable* fIsotopeTable = nullptr;   << 
1284   if (index < fIsotopeTableList->size()) {    << 
1285     fIsotopeTable = (*fIsotopeTableList)[inde << 
1286   }                                           << 
1287   return fIsotopeTable;                       << 
1288 }                                             << 
1289                                               << 
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                                               << 
1298   for (std::size_t i = 0; i < fIsotopeTableLi << 
1299     G4VIsotopeTable* fIsotopeTable = (*fIsoto << 
1300     property = fIsotopeTable->GetIsotope(Z, A << 
1301     if (property != nullptr) break;           << 
1302   }                                           << 
1303                                               << 
1304   return property;                            << 
1305 }                                             << 
1306                                               << 
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                                               << 
1324 void G4IonTable::CreateAllIon()               << 
1325 {                                             << 
1326   PreloadNuclide();                           << 
1327 }                                             << 
1328                                                  491 
1329 void G4IonTable::CreateAllIsomer()            << 492   if (genericIon->GetEnergyCuts() != 0) {
1330 {                                             << 493     ion->SetCuts( genericIon->GetLengthCuts());
1331   PreloadNuclide();                           << 494 #ifdef G4VERBOSE
1332 }                                             << 495     if (GetVerboseLevel()> 1) {
1333                                               << 496       G4cout << "G4IonTable::GetIon() : cut value =";
1334 void G4IonTable::PrepareNuclideTable()        << 497       G4cout << genericIon->GetLengthCuts()/mm << "[mm]" <<G4endl;
1335 {                                             << 498     } 
1336   if (pNuclideTable == nullptr) pNuclideTable << 499 #endif      
1337 }                                             << 
1338                                                  500 
1339 void G4IonTable::PreloadNuclide()             << 501     G4String name = ion->GetParticleName();
1340 {                                             << 
1341   if (isIsomerCreated || !G4Threading::IsMult << 
1342                                                  502 
1343   pNuclideTable->GenerateNuclide();           << 503     // Build Physics Tables for the ion
                                                   >> 504     // create command string for buildPhysicsTable
                                                   >> 505     char cmdBld[60];
                                                   >> 506     G4std::ostrstream osBld(cmdBld,60);
                                                   >> 507     osBld << "/run/particle/buildPhysicsTable "<< name << '\0';
                                                   >> 508  
                                                   >> 509     // set /control/verbose 0
                                                   >> 510     G4int tempVerboseLevel = G4UImanager::GetUIpointer()->GetVerboseLevel();
                                                   >> 511     G4UImanager::GetUIpointer()->SetVerboseLevel(0);
1344                                                  512 
1345   for (std::size_t i = 0; i != pNuclideTable- << 513     // issue /run/particle/buildPhysicsTable
1346     const G4IsotopeProperty* fProperty = pNuc << 514     G4UImanager::GetUIpointer()->ApplyCommand(cmdBld);
1347     G4int Z = fProperty->GetAtomicNumber();   << 
1348     G4int A = fProperty->GetAtomicMass();     << 
1349     G4double Eex = fProperty->GetEnergy();    << 
1350     GetIon(Z, A, Eex);                        << 
1351   }                                           << 
1352                                                  515 
1353   isIsomerCreated = true;                     << 516     // retreive  /control/verbose 
1354 }                                             << 517     G4UImanager::GetUIpointer()->SetVerboseLevel(tempVerboseLevel);
1355                                                  518 
1356 G4ParticleDefinition* G4IonTable::GetParticle << 519   } else {
1357 {                                             << 
1358   if ((index >= 0) && (index < Entries())) {  << 
1359     auto idx = fIonList->cbegin();            << 
1360     G4int counter = 0;                        << 
1361     while (idx != fIonList->cend())  // Loop  << 
1362     {                                         << 
1363       if (counter == index) {                 << 
1364         return const_cast<G4ParticleDefinitio << 
1365       }                                       << 
1366       ++counter;                              << 
1367       ++idx;                                  << 
1368     }                                         << 
1369   }                                           << 
1370 #ifdef G4VERBOSE                                 520 #ifdef G4VERBOSE
1371   if (GetVerboseLevel() > 1) {                << 521     if (GetVerboseLevel()> 1) {
1372     G4cout << " G4IonTable::GetParticle"      << 522       G4cout << "G4IonTable::GetIon() : ";
1373            << " invalid index (=" << index << << 523       G4cout << " cut value of GenericIon has not be defined yet";
1374            << " entries = " << Entries() << G << 524     } 
1375   }                                           << 525 #endif      
1376 #endif                                        << 
1377   return nullptr;                             << 
1378 }                                             << 
1379                                                  526 
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   }                                              527   }
1397   return found;                               << 
1398 }                                             << 
1399                                               << 
1400 G4int G4IonTable::Entries() const             << 
1401 {                                             << 
1402   return (G4int)fIonList->size();             << 
1403 }                                                528 }
1404                                                  529 
1405 G4int G4IonTable::size() const                << 530 ////////////////////
                                                   >> 531 void  G4IonTable::RegisterIsotopeTable(G4VIsotopeTable* table)
1406 {                                                532 {
1407   return (G4int)fIonList->size();             << 533   fIsotopeTable = table;
1408 }                                                534 }
1409                                                  535 
1410 G4ParticleDefinition* G4IonTable::FindIonInMa << 536 ////////////////////
1411                                               << 537 G4VIsotopeTable* G4IonTable::GetIsotopeTable() const
1412 {                                                538 {
1413   // Search ions with A, Z ,E                 << 539   return fIsotopeTable;
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 }                                                540 }
1439                                                  541 
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                                                  542 
1473 G4ParticleDefinition* G4IonTable::FindIonInMa << 543 ////////////////////
                                                   >> 544 G4IsotopeProperty* G4IonTable::FindIsotope(G4int Z, G4int A, G4double E, G4int J)
1474 {                                                545 {
1475   // Search ions with A, Z ,E                 << 546   G4IsotopeProperty* fProperty = new G4IsotopeProperty();   
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                                                  547 
1492   if (isFound) {                              << 548   // Set Isotope Property
1493     return const_cast<G4ParticleDefinition*>( << 549   fProperty->SetAtomicNumber(Z);
                                                   >> 550   fProperty->SetAtomicMass(A);
                                                   >> 551   fProperty->SetEnergy(E);
                                                   >> 552   fProperty->SetiSpin(J);
                                                   >> 553   fProperty->SetLifeTime(-1.0);
                                                   >> 554   fProperty->SetDecayTable(0);
                                                   >> 555 
                                                   >> 556   if (fIsotopeTable ==0) return 0;
                                                   >> 557 
                                                   >> 558   // ask IsotopeTable
                                                   >> 559   if (fIsotopeTable->FindIsotope(fProperty)) {
                                                   >> 560     return fProperty;
                                                   >> 561   } else {
                                                   >> 562     delete fProperty;
                                                   >> 563     return 0;
1494   }                                              564   }
1495                                               << 
1496   return nullptr;                             << 
1497 }                                                565 }
1498                                                  566 
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                                                  567 
1520   if (isFound) {                              << 
1521     return const_cast<G4ParticleDefinition*>( << 
1522   }                                           << 
1523                                                  568 
1524   return nullptr;                             << 
1525 }                                             << 
1526                                                  569 
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                                                  570 
1537 G4double G4IonTable::GetLifeTime(G4int Z, G4i << 
1538 {                                             << 
1539   return GetLifeTime(Z, A, E, G4Ions::FloatLe << 
1540 }                                             << 
1541                                                  571 
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                                                  572 
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                                                  573 
1558   // We're assuming here that we get a base t << 
1559   // constructed and unexcited ... strip exci << 
1560   // isomers from the encoding                << 
1561                                               << 
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                                               << 
1567   // We have to do all the MT manipulations m << 
1568   // convenience functions assume a G4Ions wi << 
1569   // they recalculate the encoding from parti << 
1570   // than using the carried member function v << 
1571   // do operations on the base ion, rather th << 
1572   // G4MuonicAtom                             << 
1573                                               << 
1574   auto i = fIonList->find(encoding);          << 
1575   if (i != fIonList->cend()) {                << 
1576     return const_cast<G4ParticleDefinition*>( << 
1577   }                                           << 
1578   // not in threadlocal list; check global li << 
1579 #ifdef G4MULTITHREADED                        << 
1580   if (G4Threading::IsWorkerThread()) {        << 
1581     G4MUTEXLOCK(&G4IonTable::ionTableMutex);  << 
1582     i = fIonListShadow->find(encoding);       << 
1583     auto end = fIonListShadow->cend();        << 
1584     G4MUTEXUNLOCK(&G4IonTable::ionTableMutex) << 
1585     if (i != end) {                           << 
1586       // we found it, stuff it into the threa << 
1587       fIonList->insert(*i);                   << 
1588       // and then return it ...               << 
1589       return const_cast<G4ParticleDefinition* << 
1590     }                                         << 
1591   }                                           << 
1592 #endif                                        << 
1593                                                  574 
1594   // not found in either list; create and pot << 
1595   auto const name = "Mu" + GetIonName(Z, A);  << 
1596                                                  575 
1597   G4MuonicAtom* muatom = G4MuonicAtomHelper:: << 
1598                                                  576 
1599   // Not sure this is doing the right thing.. << 
1600   AddProcessManager(muatom);                  << 
1601                                                  577 
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                                                  578 
1629   return muatom;                              << 
1630 }                                             << 
1631                                                  579 
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                                                  580