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 /// \file electromagnetic/TestEm3/src/RunActio << 26 // $Id: RunAction.cc,v 1.38 2010-01-24 17:25:07 vnivanch Exp $ 27 /// \brief Implementation of the RunAction cla << 27 // GEANT4 tag $Name: not supported by cvs2svn $ 28 // << 29 // 28 // 30 //....oooOO0OOooo........oooOO0OOooo........oo 29 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 31 //....oooOO0OOooo........oooOO0OOooo........oo 30 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 32 31 33 #include "RunAction.hh" 32 #include "RunAction.hh" 34 33 35 #include "DetectorConstruction.hh" << 36 #include "HistoManager.hh" << 37 #include "PrimaryGeneratorAction.hh" 34 #include "PrimaryGeneratorAction.hh" 38 #include "Run.hh" << 39 #include "RunActionMessenger.hh" 35 #include "RunActionMessenger.hh" >> 36 #include "HistoManager.hh" >> 37 #include "EmAcceptance.hh" 40 38 >> 39 #include "G4Run.hh" 41 #include "G4RunManager.hh" 40 #include "G4RunManager.hh" 42 #include "G4Timer.hh" << 41 #include "G4UnitsTable.hh" >> 42 >> 43 #include "G4ParticleTable.hh" >> 44 #include "G4ParticleDefinition.hh" >> 45 #include "G4Track.hh" >> 46 #include "G4Gamma.hh" >> 47 #include "G4Electron.hh" >> 48 #include "G4Positron.hh" >> 49 #include "G4ProductionCutsTable.hh" >> 50 #include "G4LossTableManager.hh" >> 51 43 #include "Randomize.hh" 52 #include "Randomize.hh" 44 53 45 //....oooOO0OOooo........oooOO0OOooo........oo 54 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 46 55 47 RunAction::RunAction(DetectorConstruction* det << 56 RunAction::RunAction(DetectorConstruction* det, PrimaryGeneratorAction* prim, 48 : fDetector(det), fPrimary(prim) << 57 HistoManager* hist) >> 58 :Detector(det), Primary(prim), histoManager(hist) 49 { 59 { 50 fRunMessenger = new RunActionMessenger(this) << 60 runMessenger = new RunActionMessenger(this); 51 fHistoManager = new HistoManager(); << 61 applyLimit = false; >> 62 >> 63 for (G4int k=0; k<MaxAbsor; k++) { edeptrue[k] = rmstrue[k] = 1.; >> 64 limittrue[k] = DBL_MAX; >> 65 } 52 } 66 } 53 67 54 //....oooOO0OOooo........oooOO0OOooo........oo 68 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 55 69 56 RunAction::~RunAction() 70 RunAction::~RunAction() 57 { 71 { 58 delete fRunMessenger; << 72 delete runMessenger; 59 } 73 } 60 74 61 //....oooOO0OOooo........oooOO0OOooo........oo 75 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 62 76 63 G4Run* RunAction::GenerateRun() << 77 void RunAction::BeginOfRunAction(const G4Run* aRun) 64 { 78 { 65 fRun = new Run(fDetector); << 79 G4cout << "### Run " << aRun->GetRunID() << " start." << G4endl; 66 return fRun; << 67 } << 68 80 69 //....oooOO0OOooo........oooOO0OOooo........oo << 81 // save Rndm status >> 82 // >> 83 G4RunManager::GetRunManager()->SetRandomNumberStore(true); >> 84 CLHEP::HepRandom::showEngineStatus(); 70 85 71 void RunAction::BeginOfRunAction(const G4Run*) << 86 //initialize cumulative quantities 72 { << 87 // 73 // keep run condition << 88 for (G4int k=0; k<MaxAbsor; k++) { 74 if (fPrimary) { << 89 sumEAbs[k] = sum2EAbs[k] = sumLAbs[k] = sum2LAbs[k] = 0.; 75 G4ParticleDefinition* particle = fPrimary- << 90 energyDeposit[k].clear(); 76 G4double energy = fPrimary->GetParticleGun << 77 fRun->SetPrimary(particle, energy); << 78 } 91 } 79 92 80 // histograms << 93 n_gamma = 0; >> 94 n_elec = 0; >> 95 n_pos = 0; >> 96 >> 97 //initialize Eflow >> 98 // >> 99 G4int nbPlanes = (Detector->GetNbOfLayers())*(Detector->GetNbOfAbsor()) + 2; >> 100 EnergyFlow.resize(nbPlanes); >> 101 lateralEleak.resize(nbPlanes); >> 102 for (G4int k=0; k<nbPlanes; k++) {EnergyFlow[k] = lateralEleak[k] = 0.; } >> 103 >> 104 //histograms 81 // 105 // 82 G4AnalysisManager* analysis = G4AnalysisMana << 106 histoManager->book(); 83 if (analysis->IsActive()) analysis->OpenFile << 107 >> 108 //example of print dEdx tables >> 109 // >> 110 ////PrintDedxTables(); >> 111 } 84 112 85 // save Rndm status and open the timer << 113 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 86 114 87 if (isMaster) { << 115 void RunAction::fillPerEvent(G4int kAbs, G4double EAbs, G4double LAbs) 88 // G4Random::showEngineStatus(); << 116 { 89 fTimer = new G4Timer(); << 117 //accumulate statistic with restriction 90 fTimer->Start(); << 118 // 91 } << 119 if(applyLimit) energyDeposit[kAbs].push_back(EAbs); >> 120 sumEAbs[kAbs] += EAbs; sum2EAbs[kAbs] += EAbs*EAbs; >> 121 sumLAbs[kAbs] += LAbs; sum2LAbs[kAbs] += LAbs*LAbs; 92 } 122 } 93 123 94 //....oooOO0OOooo........oooOO0OOooo........oo 124 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 95 125 96 void RunAction::EndOfRunAction(const G4Run*) << 126 >> 127 void RunAction::EndOfRunAction(const G4Run* aRun) 97 { 128 { 98 // compute and print statistic << 129 G4int nEvt = aRun->GetNumberOfEvent(); 99 if (isMaster) { << 130 G4double norm = G4double(nEvt); 100 fTimer->Stop(); << 131 if(norm > 0) norm = 1./norm; 101 if (!((G4RunManager::GetRunManager()->GetR << 132 G4double qnorm = std::sqrt(norm); 102 G4cout << "\n" << 133 103 << "Total number of events: " << << 134 //compute and print statistic 104 G4cout << "Master thread time: " << *fT << 135 // >> 136 G4double beamEnergy = Primary->GetParticleGun()->GetParticleEnergy(); >> 137 G4double sqbeam = std::sqrt(beamEnergy/GeV); >> 138 >> 139 G4double MeanEAbs,MeanEAbs2,rmsEAbs,resolution,rmsres; >> 140 G4double MeanLAbs,MeanLAbs2,rmsLAbs; >> 141 >> 142 std::ios::fmtflags mode = G4cout.flags(); >> 143 G4int prec = G4cout.precision(2); >> 144 G4cout << "\n------------------------------------------------------------\n"; >> 145 G4cout << std::setw(14) << "material" >> 146 << std::setw(17) << "Edep RMS" >> 147 << std::setw(33) << "sqrt(E0(GeV))*rmsE/Emean" >> 148 << std::setw(23) << "total tracklen \n \n"; >> 149 >> 150 for (G4int k=1; k<=Detector->GetNbOfAbsor(); k++) >> 151 { >> 152 MeanEAbs = sumEAbs[k]*norm; >> 153 MeanEAbs2 = sum2EAbs[k]*norm; >> 154 rmsEAbs = std::sqrt(std::abs(MeanEAbs2 - MeanEAbs*MeanEAbs)); >> 155 //G4cout << "k= " << k << " RMS= " << rmsEAbs >> 156 // << " applyLimit: " << applyLimit << G4endl; >> 157 if(applyLimit) { >> 158 G4int nn = 0; >> 159 G4double sume = 0.0; >> 160 G4double sume2 = 0.0; >> 161 // compute trancated means >> 162 G4double lim = rmsEAbs * 2.5; >> 163 for(G4int i=0; i<nEvt; i++) { >> 164 G4double e = (energyDeposit[k])[i]; >> 165 if(std::abs(e - MeanEAbs) < lim) { >> 166 sume += e; >> 167 sume2 += e*e; >> 168 nn++; >> 169 } >> 170 } >> 171 G4double norm1 = G4double(nn); >> 172 if(norm1 > 0.0) norm1 = 1.0/norm1; >> 173 MeanEAbs = sume*norm1; >> 174 MeanEAbs2 = sume2*norm1; >> 175 rmsEAbs = std::sqrt(std::abs(MeanEAbs2 - MeanEAbs*MeanEAbs)); >> 176 } >> 177 >> 178 resolution= 100.*sqbeam*rmsEAbs/MeanEAbs; >> 179 rmsres = resolution*qnorm; >> 180 >> 181 // Save mean and RMS >> 182 sumEAbs[k] = MeanEAbs; >> 183 sum2EAbs[k] = rmsEAbs; >> 184 >> 185 MeanLAbs = sumLAbs[k]*norm; >> 186 MeanLAbs2 = sum2LAbs[k]*norm; >> 187 rmsLAbs = std::sqrt(std::abs(MeanLAbs2 - MeanLAbs*MeanLAbs)); >> 188 >> 189 //print >> 190 // >> 191 G4cout >> 192 << std::setw(14) << Detector->GetAbsorMaterial(k)->GetName() << ": " >> 193 << std::setprecision(5) >> 194 << std::setw(6) << G4BestUnit(MeanEAbs,"Energy") << " : " >> 195 << std::setprecision(4) >> 196 << std::setw(5) << G4BestUnit( rmsEAbs,"Energy") >> 197 << std::setw(10) << resolution << " +- " >> 198 << std::setw(5) << rmsres << " %" >> 199 << std::setprecision(3) >> 200 << std::setw(10) << G4BestUnit(MeanLAbs,"Length") << " +- " >> 201 << std::setw(4) << G4BestUnit( rmsLAbs,"Length") >> 202 << G4endl; 105 } 203 } 106 delete fTimer; << 204 G4cout << "\n------------------------------------------------------------\n"; 107 fRun->EndOfRun(); << 205 >> 206 G4cout << " Beam particle " >> 207 << Primary->GetParticleGun()-> >> 208 GetParticleDefinition()->GetParticleName() >> 209 << " E = " << G4BestUnit(beamEnergy,"Energy") << G4endl; >> 210 G4cout << " Mean number of gamma " << (G4double)n_gamma*norm << G4endl; >> 211 G4cout << " Mean number of e- " << (G4double)n_elec*norm << G4endl; >> 212 G4cout << " Mean number of e+ " << (G4double)n_pos*norm << G4endl; >> 213 G4cout << "------------------------------------------------------------\n"; >> 214 >> 215 //Energy flow >> 216 // >> 217 G4int Idmax = (Detector->GetNbOfLayers())*(Detector->GetNbOfAbsor()); >> 218 for (G4int Id=1; Id<=Idmax+1; Id++) { >> 219 histoManager->FillHisto(2*MaxAbsor+1, (G4double)Id, EnergyFlow[Id]); >> 220 histoManager->FillHisto(2*MaxAbsor+2, (G4double)Id, lateralEleak[Id]); 108 } 221 } 109 // save histograms << 222 110 G4AnalysisManager* analysis = G4AnalysisMana << 223 //Energy deposit from energy flow balance 111 if (analysis->IsActive()) { << 224 // 112 analysis->Write(); << 225 G4double EdepTot[MaxAbsor]; 113 analysis->CloseFile(); << 226 for (G4int k=0; k<MaxAbsor; k++) EdepTot[k] = 0.; >> 227 >> 228 G4int nbOfAbsor = Detector->GetNbOfAbsor(); >> 229 for (G4int Id=1; Id<=Idmax; Id++) { >> 230 G4int iAbsor = Id%nbOfAbsor; if (iAbsor==0) iAbsor = nbOfAbsor; >> 231 EdepTot [iAbsor] += (EnergyFlow[Id] - EnergyFlow[Id+1] - lateralEleak[Id]); >> 232 } >> 233 >> 234 G4cout << "\n Energy deposition from Energy flow balance : \n" >> 235 << std::setw(10) << " material \t Total Edep \n \n"; >> 236 G4cout.precision(6); >> 237 >> 238 for (G4int k=1; k<=nbOfAbsor; k++) { >> 239 EdepTot [k] *= norm; >> 240 G4cout << std::setw(10) << Detector->GetAbsorMaterial(k)->GetName() << ":" >> 241 << "\t " << G4BestUnit(EdepTot [k],"Energy") << "\n"; >> 242 } >> 243 >> 244 G4cout << "\n------------------------------------------------------------\n" >> 245 << G4endl; >> 246 >> 247 G4cout.setf(mode,std::ios::floatfield); >> 248 G4cout.precision(prec); >> 249 >> 250 // Acceptance >> 251 EmAcceptance acc; >> 252 G4bool isStarted = false; >> 253 for (G4int j=1; j<=Detector->GetNbOfAbsor(); j++) { >> 254 if (limittrue[j] < DBL_MAX) { >> 255 if (!isStarted) { >> 256 acc.BeginOfAcceptance("Sampling Calorimeter",nEvt); >> 257 isStarted = true; >> 258 } >> 259 MeanEAbs = sumEAbs[j]; >> 260 rmsEAbs = sum2EAbs[j]; >> 261 G4String mat = Detector->GetAbsorMaterial(j)->GetName(); >> 262 acc.EmAcceptanceGauss("Edep"+mat, nEvt, MeanEAbs, >> 263 edeptrue[j], rmstrue[j], limittrue[j]); >> 264 acc.EmAcceptanceGauss("Erms"+mat, nEvt, rmsEAbs, >> 265 rmstrue[j], rmstrue[j], 2.0*limittrue[j]); >> 266 } >> 267 } >> 268 if(isStarted) acc.EndOfAcceptance(); >> 269 >> 270 //normalize histograms >> 271 // >> 272 for (G4int ih = MaxAbsor+1; ih < MaxHisto; ih++) { >> 273 histoManager->Normalize(ih,norm/MeV); 114 } 274 } >> 275 >> 276 //save histograms >> 277 histoManager->save(); 115 278 116 // show Rndm status 279 // show Rndm status 117 // if (isMaster) G4Random::showEngineStatu << 280 CLHEP::HepRandom::showEngineStatus(); 118 } 281 } 119 282 120 //....oooOO0OOooo........oooOO0OOooo........oo 283 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 121 284 122 void RunAction::SetEdepAndRMS(G4int i, G4doubl << 285 void RunAction::PrintDedxTables() >> 286 { >> 287 //Print dE/dx tables with binning identical to the Geant3 JMATE bank. >> 288 //The printout is readable as Geant3 ffread data cards (by the program g4mat). >> 289 // >> 290 const G4double tkmin=10*keV, tkmax=10*TeV; >> 291 const G4int nbin=90; >> 292 G4double tk[nbin]; >> 293 >> 294 const G4int ncolumn = 5; >> 295 >> 296 //compute the kinetic energies >> 297 // >> 298 const G4double dp = std::log10(tkmax/tkmin)/nbin; >> 299 const G4double dt = std::pow(10.,dp); >> 300 tk[0] = tkmin; >> 301 for (G4int i=1; i<nbin; ++i) tk[i] = tk[i-1]*dt; >> 302 >> 303 //print the kinetic energies >> 304 // >> 305 std::ios::fmtflags mode = G4cout.flags(); >> 306 G4cout.setf(std::ios::fixed,std::ios::floatfield); >> 307 G4int prec = G4cout.precision(3); >> 308 >> 309 G4cout << "\n kinetic energies \n "; >> 310 for (G4int j=0; j<nbin; ++j) { >> 311 G4cout << G4BestUnit(tk[j],"Energy") << "\t"; >> 312 if ((j+1)%ncolumn == 0) G4cout << "\n "; >> 313 } >> 314 G4cout << G4endl; >> 315 >> 316 //print the dE/dx tables >> 317 // >> 318 G4cout.setf(std::ios::scientific,std::ios::floatfield); >> 319 >> 320 G4ParticleDefinition* >> 321 part = Primary->GetParticleGun()->GetParticleDefinition(); >> 322 >> 323 G4ProductionCutsTable* theCoupleTable = >> 324 G4ProductionCutsTable::GetProductionCutsTable(); >> 325 size_t numOfCouples = theCoupleTable->GetTableSize(); >> 326 const G4MaterialCutsCouple* couple = 0; >> 327 >> 328 for (G4int iab=1;iab <= Detector->GetNbOfAbsor(); iab++) >> 329 { >> 330 G4Material* mat = Detector->GetAbsorMaterial(iab); >> 331 G4int index = 0; >> 332 for (size_t i=0; i<numOfCouples; i++) { >> 333 couple = theCoupleTable->GetMaterialCutsCouple(i); >> 334 if (couple->GetMaterial() == mat) {index = i; break;} >> 335 } >> 336 G4cout << "\nLIST"; >> 337 G4cout << "\nC \nC dE/dx (MeV/cm) for " << part->GetParticleName() >> 338 << " in " << mat ->GetName() << "\nC"; >> 339 G4cout << "\nKINE (" << part->GetParticleName() << ")"; >> 340 G4cout << "\nMATE (" << mat ->GetName() << ")"; >> 341 G4cout.precision(2); >> 342 G4cout << "\nERAN " << tkmin/GeV << " (ekmin)\t" >> 343 << tkmax/GeV << " (ekmax)\t" >> 344 << nbin << " (nekbin)"; >> 345 G4double cutgam = >> 346 (*(theCoupleTable->GetEnergyCutsVector(idxG4GammaCut)))[index]; >> 347 if (cutgam < tkmin) cutgam = tkmin; >> 348 if (cutgam > tkmax) cutgam = tkmax; >> 349 G4double cutele = >> 350 (*(theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut)))[index]; >> 351 if (cutele < tkmin) cutele = tkmin; >> 352 if (cutele > tkmax) cutele = tkmax; >> 353 G4cout << "\nCUTS " << cutgam/GeV << " (cutgam)\t" >> 354 << cutele/GeV << " (cutele)"; >> 355 >> 356 G4cout.precision(6); >> 357 G4cout << "\nG4VAL \n "; >> 358 for (G4int l=0;l<nbin; ++l) >> 359 { >> 360 G4double dedx = G4LossTableManager::Instance() >> 361 ->GetDEDX(part,tk[l],couple); >> 362 G4cout << dedx/(MeV/cm) << "\t"; >> 363 if ((l+1)%ncolumn == 0) G4cout << "\n "; >> 364 } >> 365 G4cout << G4endl; >> 366 } >> 367 >> 368 G4cout.precision(prec); >> 369 G4cout.setf(mode,std::ios::floatfield); >> 370 } >> 371 >> 372 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... >> 373 >> 374 void RunAction::AddSecondaryTrack(const G4Track* track) 123 { 375 { 124 if (fRun) fRun->SetEdepAndRMS(i, edep, rms, << 376 const G4ParticleDefinition* d = track->GetDefinition(); >> 377 if(d == G4Gamma::Gamma()) { ++n_gamma; } >> 378 else if (d == G4Electron::Electron()) { ++n_elec; } >> 379 else if (d == G4Positron::Positron()) { ++n_pos; } 125 } 380 } 126 381 127 //....oooOO0OOooo........oooOO0OOooo........oo 382 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 128 383 129 void RunAction::SetApplyLimit(G4bool val) << 384 void RunAction::SetEdepAndRMS(G4int i, G4double edep, G4double rms, G4double lim) 130 { 385 { 131 if (fRun) fRun->SetApplyLimit(val); << 386 if (i>=0 && i<MaxAbsor) { >> 387 edeptrue [i] = edep; >> 388 rmstrue [i] = rms; >> 389 limittrue[i] = lim; >> 390 } 132 } 391 } 133 392 134 //....oooOO0OOooo........oooOO0OOooo........oo 393 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 135 394