Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 /// \file electromagnetic/TestEm18/src/RunActi 27 /// \brief Implementation of the RunAction cla 28 // 29 // 30 //....oooOO0OOooo........oooOO0OOooo........oo 31 //....oooOO0OOooo........oooOO0OOooo........oo 32 33 #include "RunAction.hh" 34 35 #include "DetectorConstruction.hh" 36 #include "HistoManager.hh" 37 #include "PrimaryGeneratorAction.hh" 38 39 #include "G4EmCalculator.hh" 40 #include "G4Run.hh" 41 #include "G4UnitsTable.hh" 42 #include "Randomize.hh" 43 44 #include <iomanip> 45 46 //....oooOO0OOooo........oooOO0OOooo........oo 47 48 RunAction::RunAction(DetectorConstruction* det 49 : fDetector(det), fPrimary(kin) 50 { 51 fHistoManager = new HistoManager(); 52 } 53 54 //....oooOO0OOooo........oooOO0OOooo........oo 55 56 RunAction::~RunAction() 57 { 58 delete fHistoManager; 59 } 60 61 //....oooOO0OOooo........oooOO0OOooo........oo 62 63 void RunAction::BeginOfRunAction(const G4Run*) 64 { 65 // initialisation 66 // 67 fNbSteps = 0; 68 fTrackLength = 0.; 69 fStepMin = DBL_MAX; 70 fStepMax = 0.; 71 72 fEdepPrimary = fEdepSecondary = fEdepTotal = 73 fEdepPrimMin = fEdepSecMin = fEdepTotMin = D 74 fEdepPrimMax = fEdepSecMax = fEdepTotMax = 0 75 76 fEnergyTransfered = 0.; 77 fEtransfMin = DBL_MAX; 78 fEtransfMax = 0.; 79 80 fEnergyLost = 0.; 81 fElostMin = DBL_MAX; 82 fElostMax = 0.; 83 84 fEnergyBalance = 0.; 85 fEbalMin = DBL_MAX; 86 fEbalMax = 0.; 87 88 // histograms 89 // 90 G4AnalysisManager* analysisManager = G4Analy 91 if (analysisManager->IsActive()) { 92 analysisManager->OpenFile(); 93 } 94 95 // show Rndm status 96 CLHEP::HepRandom::showEngineStatus(); 97 } 98 99 //....oooOO0OOooo........oooOO0OOooo........oo 100 101 void RunAction::CountProcesses(G4String procNa 102 { 103 std::map<G4String, G4int>::iterator it = fPr 104 if (it == fProcCounter.end()) { 105 fProcCounter[procName] = 1; 106 } 107 else { 108 fProcCounter[procName]++; 109 } 110 } 111 112 //....oooOO0OOooo........oooOO0OOooo........oo 113 114 void RunAction::TrackLength(G4double step) 115 { 116 fTrackLength += step; 117 fNbSteps++; 118 if (step < fStepMin) fStepMin = step; 119 if (step > fStepMax) fStepMax = step; 120 } 121 122 //....oooOO0OOooo........oooOO0OOooo........oo 123 124 void RunAction::EnergyDeposited(G4double edepP 125 { 126 fEdepPrimary += edepPrim; 127 if (edepPrim < fEdepPrimMin) fEdepPrimMin = 128 if (edepPrim > fEdepPrimMax) fEdepPrimMax = 129 130 fEdepSecondary += edepSecond; 131 if (edepSecond < fEdepSecMin) fEdepSecMin = 132 if (edepSecond > fEdepSecMax) fEdepSecMax = 133 } 134 135 //....oooOO0OOooo........oooOO0OOooo........oo 136 137 void RunAction::EnergyTransferedByProcess(G4St 138 { 139 std::map<G4String, MinMaxData>::iterator it 140 if (it == fEtransfByProcess.end()) { 141 fEtransfByProcess[process] = MinMaxData(1, 142 } 143 else { 144 MinMaxData& data = it->second; 145 data.fCount++; 146 data.fVsum += energy; 147 // update min max 148 G4double emin = data.fVmin; 149 if (energy < emin) data.fVmin = energy; 150 G4double emax = data.fVmax; 151 if (energy > emax) data.fVmax = energy; 152 } 153 } 154 155 //....oooOO0OOooo........oooOO0OOooo........oo 156 157 void RunAction::EnergyTransfered(G4double ener 158 { 159 fEnergyTransfered += energy; 160 if (energy < fEtransfMin) fEtransfMin = ener 161 if (energy > fEtransfMax) fEtransfMax = ener 162 } 163 164 //....oooOO0OOooo........oooOO0OOooo........oo 165 166 void RunAction::TotalEnergyLost(G4double energ 167 { 168 fEnergyLost += energy; 169 if (energy < fElostMin) fElostMin = energy; 170 if (energy > fElostMax) fElostMax = energy; 171 } 172 173 //....oooOO0OOooo........oooOO0OOooo........oo 174 175 void RunAction::EnergyBalance(G4double energy) 176 { 177 fEnergyBalance += energy; 178 if (energy < fEbalMin) fEbalMin = energy; 179 if (energy > fEbalMax) fEbalMax = energy; 180 } 181 182 //....oooOO0OOooo........oooOO0OOooo........oo 183 184 void RunAction::TotalEnergyDeposit(G4double en 185 { 186 fEdepTotal += energy; 187 if (energy < fEdepTotMin) fEdepTotMin = ener 188 if (energy > fEdepTotMax) fEdepTotMax = ener 189 } 190 191 //....oooOO0OOooo........oooOO0OOooo........oo 192 193 void RunAction::EnergySpectrumOfSecondaries(G4 194 { 195 std::map<G4String, MinMaxData>::iterator it 196 if (it == fEkinOfSecondaries.end()) { 197 fEkinOfSecondaries[particle] = MinMaxData( 198 } 199 else { 200 MinMaxData& data = it->second; 201 data.fCount++; 202 data.fVsum += energy; 203 // update min max 204 G4double emin = data.fVmin; 205 if (energy < emin) data.fVmin = energy; 206 G4double emax = data.fVmax; 207 if (energy > emax) data.fVmax = energy; 208 } 209 } 210 211 //....oooOO0OOooo........oooOO0OOooo........oo 212 213 void RunAction::EndOfRunAction(const G4Run* aR 214 { 215 G4int nbEvents = aRun->GetNumberOfEvent(); 216 if (nbEvents == 0) return; 217 218 G4Material* material = fDetector->GetMateria 219 G4double length = fDetector->GetSize(); 220 G4double density = material->GetDensity(); 221 222 G4ParticleDefinition* particle = fPrimary->G 223 G4String partName = particle->GetParticleNam 224 G4double ePrimary = fPrimary->GetParticleGun 225 226 G4int prec = G4cout.precision(3); 227 G4cout << "\n ======================== run s 228 G4cout << "\n The run was " << nbEvents << " 229 << G4BestUnit(ePrimary, "Energy") << 230 << material->GetName() << " (density: 231 G4cout << G4endl; 232 233 if (particle->GetPDGCharge() == 0.) return; 234 235 G4cout.precision(4); 236 237 // frequency of processes 238 // 239 G4cout << "\n Process defining step :" << G4 240 G4int index = 0; 241 for (const auto& procCounter : fProcCounter) 242 G4String procName = procCounter.first; 243 G4int count = procCounter.second; 244 G4String space = " "; 245 if (++index % 4 == 0) space = "\n"; 246 G4cout << " " << std::setw(15) << procName 247 } 248 G4cout << G4endl; 249 250 // track length 251 // 252 G4double trackLPerEvent = fTrackLength / nbE 253 G4double nbStepPerEvent = double(fNbSteps) / 254 G4double stepSize = fTrackLength / fNbSteps; 255 256 G4cout << "\n TrackLength = " << G4BestUnit( 257 << " nb of steps = " << nbStepPerEve 258 << " stepSize = " << G4BestUnit(step 259 << G4BestUnit(fStepMin, "Length") << 260 << G4endl; 261 262 // continuous energy deposited by primary tr 263 // 264 G4double energyPerEvent = fEdepPrimary / nbE 265 266 G4cout << "\n Energy continuously deposited 267 << " (restricted dE/dx) dE1 = " << G 268 << G4BestUnit(fEdepPrimMin, "Energy") 269 << ")" << G4endl; 270 271 // eveluation of dE1 from reading restricted 272 // 273 G4EmCalculator emCal; 274 275 G4double r0 = emCal.GetRangeFromRestricteDED 276 G4double r1 = r0 - trackLPerEvent; 277 G4double etry = ePrimary - energyPerEvent; 278 G4double efinal = 0.; 279 if (r1 > 0.) efinal = GetEnergyFromRestricte 280 G4double dEtable = ePrimary - efinal; 281 G4double ratio = 0.; 282 if (dEtable > 0.) ratio = energyPerEvent / d 283 284 G4cout << "\n Evaluation of dE1 from reading 285 << G4BestUnit(dEtable, "Energy") << " 286 287 // energy transfered to secondary particles 288 // 289 G4cout << "\n Energy transfered to secondary 290 std::map<G4String, MinMaxData>::iterator it1 291 for (it1 = fEtransfByProcess.begin(); it1 != 292 G4String name = it1->first; 293 MinMaxData data = it1->second; 294 energyPerEvent = data.fVsum / nbEvents; 295 G4double eMin = data.fVmin; 296 G4double eMax = data.fVmax; 297 298 G4cout << " " << std::setw(17) << "due to 299 << G4BestUnit(energyPerEvent, "Ener 300 << G4BestUnit(eMax, "Energy") << ") 301 } 302 303 // total energy tranfered : dE3 = sum of dE2 304 // 305 energyPerEvent = fEnergyTransfered / nbEvent 306 307 G4cout << "\n Total energy transfered to sec 308 << G4BestUnit(energyPerEvent, "Energy 309 << " --> " << G4BestUnit(fEtransfMax, 310 311 // total energy lost by incident particle : 312 // 313 energyPerEvent = fEnergyLost / nbEvents; 314 315 G4cout << "\n Total energy lost by incident 316 << G4BestUnit(energyPerEvent, "Energy 317 << " --> " << G4BestUnit(fElostMax, " 318 319 // calcul of energy lost from energy balance 320 // 321 energyPerEvent = fEnergyBalance / nbEvents; 322 323 G4cout << "\n calcul of dE4 from energy bala 324 << G4BestUnit(energyPerEvent, "Energy 325 << " --> " << G4BestUnit(fEbalMax, "E 326 327 // eveluation of dE4 from reading full Range 328 // 329 r0 = emCal.GetCSDARange(ePrimary, particle, 330 r1 = r0 - trackLPerEvent; 331 etry = ePrimary - energyPerEvent; 332 efinal = 0.; 333 if (r1 > 0.) efinal = GetEnergyFromCSDARange 334 dEtable = ePrimary - efinal; 335 ratio = 0.; 336 if (dEtable > 0.) ratio = energyPerEvent / d 337 338 G4cout << "\n Evaluation of dE4 from reading 339 << G4BestUnit(dEtable, "Energy") << " 340 341 // energy spectrum of secondary particles 342 // 343 G4cout << "\n Energy spectrum of secondary p 344 std::map<G4String, MinMaxData>::iterator it2 345 for (it2 = fEkinOfSecondaries.begin(); it2 ! 346 G4String name = it2->first; 347 MinMaxData data = it2->second; 348 G4int count = data.fCount; 349 G4double eMean = data.fVsum / count; 350 G4double eMin = data.fVmin; 351 G4double eMax = data.fVmax; 352 353 G4cout << " " << std::setw(13) << name << 354 << " Emean = " << std::setw(6) << 355 << G4BestUnit(eMin, "Energy") << " 356 } 357 G4cout << G4endl; 358 359 // continuous energy deposited by secondary 360 // (only if secondary particles are tracked 361 // 362 if (fEdepSecondary > 0.) { 363 energyPerEvent = fEdepSecondary / nbEvents 364 365 G4cout << "\n Energy continuously deposite 366 << " (restricted dE/dx) dE5 = " << 367 << G4BestUnit(fEdepSecMin, "Energy" 368 << ")" << G4endl; 369 370 // total energy deposited : dE6 = dE1 + dE 371 // 372 energyPerEvent = fEdepTotal / nbEvents; 373 374 G4cout << "\n Total energy deposited : dE6 375 << G4BestUnit(energyPerEvent, "Ener 376 << " --> " << G4BestUnit(fEdepTotMa 377 << G4endl; 378 } 379 380 G4cout.precision(prec); 381 382 // clear maps 383 // 384 fProcCounter.clear(); 385 fEtransfByProcess.clear(); 386 fEkinOfSecondaries.clear(); 387 388 // save histograms 389 G4AnalysisManager* analysisManager = G4Analy 390 if (analysisManager->IsActive()) { 391 analysisManager->Write(); 392 analysisManager->CloseFile(); 393 } 394 395 // show Rndm status 396 CLHEP::HepRandom::showEngineStatus(); 397 } 398 399 //....oooOO0OOooo........oooOO0OOooo........oo 400 401 G4double RunAction::GetEnergyFromRestrictedRan 402 403 { 404 G4EmCalculator emCal; 405 406 G4double Energy = Etry, dE = 0., dEdx; 407 G4double r, dr; 408 G4double err = 1., errmax = 0.00001; 409 G4int iter = 0, itermax = 10; 410 while (err > errmax && iter < itermax) { 411 iter++; 412 Energy -= dE; 413 r = emCal.GetRangeFromRestricteDEDX(Energy 414 dr = r - range; 415 dEdx = emCal.GetDEDX(Energy, particle, mat 416 dE = dEdx * dr; 417 err = std::abs(dE) / Energy; 418 } 419 if (iter == itermax) { 420 G4cout << "\n ---> warning: RunAction::Ge 421 << " Etry = " << G4BestUnit(Etry, 422 << " Energy = " << G4BestUnit(Ene 423 << " iter = " << iter << G4endl; 424 } 425 426 return Energy; 427 } 428 429 //....oooOO0OOooo........oooOO0OOooo........oo 430 431 G4double RunAction::GetEnergyFromCSDARange(G4d 432 G4M 433 { 434 G4EmCalculator emCal; 435 436 G4double Energy = Etry, dE = 0., dEdx; 437 G4double r, dr; 438 G4double err = 1., errmax = 0.00001; 439 G4int iter = 0, itermax = 10; 440 while (err > errmax && iter < itermax) { 441 iter++; 442 Energy -= dE; 443 r = emCal.GetCSDARange(Energy, particle, m 444 dr = r - range; 445 dEdx = emCal.ComputeTotalDEDX(Energy, part 446 dE = dEdx * dr; 447 err = std::abs(dE) / Energy; 448 } 449 if (iter == itermax) { 450 G4cout << "\n ---> warning: RunAction::Ge 451 << " Etry = " << G4BestUnit(Etry, 452 << " Energy = " << G4BestUnit(Ene 453 << " iter = " << iter << G4endl; 454 } 455 456 return Energy; 457 } 458 459 //....oooOO0OOooo........oooOO0OOooo........oo 460