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