// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // /// \file electromagnetic/TestEm18/src/RunAction.cc /// \brief Implementation of the RunAction class // // $Id: RunAction.cc 67268 2013-02-13 11:38:40Z ihrivnac $ // //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... #include "RunAction.hh" #include "DetectorConstruction.hh" #include "PrimaryGeneratorAction.hh" #include "HistoManager.hh" #include "G4Run.hh" #include "G4RunManager.hh" #include "G4UnitsTable.hh" #include "G4EmCalculator.hh" #include "Randomize.hh" #include //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... RunAction::RunAction(DetectorConstruction* det, PrimaryGeneratorAction* kin) :G4UserRunAction(),fDetector(det), fPrimary(kin), fHistoManager(0) { fHistoManager = new HistoManager(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... RunAction::~RunAction() { delete fHistoManager; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void RunAction::BeginOfRunAction(const G4Run* run) { G4cout << "### Run " << run->GetRunID() << " start." << G4endl; //initialisation // fEnergyDeposit = 0.; fNbCharged = fNbNeutral = 0; fEnergyCharged = fEnergyNeutral = 0.; fEmin[0] = fEmin[1] = DBL_MAX; fEmax[0] = fEmax[1] = 0.; fNbSteps = 0; fTrackLength = 0.; //histograms // G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); if ( analysisManager->IsActive() ) { analysisManager->OpenFile(); } // do not save Rndm status G4RunManager::GetRunManager()->SetRandomNumberStore(false); CLHEP::HepRandom::showEngineStatus(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void RunAction::EndOfRunAction(const G4Run* aRun) { G4int nbEvents = aRun->GetNumberOfEvent(); if (nbEvents == 0) return; G4Material* material = fDetector->GetMaterial(); G4double length = fDetector->GetSize(); G4double density = material->GetDensity(); G4ParticleDefinition* particle = fPrimary->GetParticleGun() ->GetParticleDefinition(); G4String partName = particle->GetParticleName(); G4double ePrimary = fPrimary->GetParticleGun()->GetParticleEnergy(); G4int prec = G4cout.precision(3); G4cout << "\n ======================== run summary ======================\n"; G4cout << "\n The run was " << nbEvents << " " << partName << " of " << G4BestUnit(ePrimary,"Energy") << " through " << G4BestUnit(length,"Length") << " of " << material->GetName() << " (density: " << G4BestUnit(density,"Volumic Mass") << ")"; G4cout << "\n ===========================================================\n"; G4cout << G4endl; //save histograms G4AnalysisManager* analysisManager = G4AnalysisManager::Instance(); if ( analysisManager->IsActive() ) { analysisManager->Write(); analysisManager->CloseFile(); } if (particle->GetPDGCharge() == 0.) return; G4cout.precision(5); //track length // G4double trackLPerEvent = fTrackLength/nbEvents; G4double nbStepPerEvent = double(fNbSteps)/nbEvents; G4double stepSize = fTrackLength/fNbSteps; G4cout << "\n TrackLength= " << G4BestUnit(trackLPerEvent, "Length") << "\t nb of steps= " << nbStepPerEvent << " stepSize= " << G4BestUnit(stepSize, "Length") << G4endl; //charged secondaries (ionization, direct pair production) // G4double energyPerEvent = fEnergyCharged/nbEvents; G4double nbPerEvent = double(fNbCharged)/nbEvents; G4double meanEkin = 0.; if (fNbCharged) meanEkin = fEnergyCharged/fNbCharged; G4cout << "\n d-rays : eLoss/primary= " << G4BestUnit(energyPerEvent, "Energy") << "\t nb of d-rays= " << nbPerEvent << " = " << G4BestUnit(meanEkin, "Energy") << " Tmin= " << G4BestUnit(fEmin[0], "Energy") << " Tmax= " << G4BestUnit(fEmax[0], "Energy") << G4endl; //neutral secondaries (bremsstrahlung, pixe) // energyPerEvent = fEnergyNeutral/nbEvents; nbPerEvent = double(fNbNeutral)/nbEvents; meanEkin = 0.; if (fNbNeutral) meanEkin = fEnergyNeutral/fNbNeutral; G4cout << "\n gamma : eLoss/primary= " << G4BestUnit(energyPerEvent, "Energy") << "\t nb of gammas= " << nbPerEvent << " = " << G4BestUnit(meanEkin, "Energy") << " Tmin= " << G4BestUnit(fEmin[1], "Energy") << " Tmax= " << G4BestUnit(fEmax[1], "Energy") << G4endl; G4EmCalculator emCal; //local energy deposit // energyPerEvent = fEnergyDeposit/nbEvents; // G4double r0 = emCal.GetRangeFromRestricteDEDX(ePrimary,particle,material); G4double r1 = r0 - trackLPerEvent; G4double etry = ePrimary - energyPerEvent; G4double efinal = 0.; if (r1 > 0.) efinal = GetEnergyFromRestrictedRange(r1,particle,material,etry); G4double dEtable = ePrimary - efinal; G4double ratio = 0.; if (dEtable > 0.) ratio = energyPerEvent/dEtable; G4cout << "\n deposit : eLoss/primary= " << G4BestUnit(energyPerEvent, "Energy") << "\t table= " << G4BestUnit(dEtable, "Energy") << " ---> simul/reference= " << ratio << G4endl; //total energy transferred // G4double energyTotal = fEnergyDeposit + fEnergyCharged + fEnergyNeutral; energyPerEvent = energyTotal/nbEvents; // r0 = emCal.GetCSDARange(ePrimary,particle,material); r1 = r0 - trackLPerEvent; etry = ePrimary - energyPerEvent; efinal = 0.; if (r1 > 0.) efinal = GetEnergyFromCSDARange(r1,particle,material,etry); dEtable = ePrimary - efinal; ratio = 0.; if (dEtable > 0.) ratio = energyPerEvent/dEtable; G4cout << "\n total : eLoss/primary= " << G4BestUnit(energyPerEvent, "Energy") << "\t table= " << G4BestUnit(dEtable, "Energy") << " ---> simul/reference= " << ratio << G4endl; G4cout.precision(prec); // show Rndm status CLHEP::HepRandom::showEngineStatus(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4double RunAction::GetEnergyFromRestrictedRange(G4double range, G4ParticleDefinition* particle, G4Material* material, G4double Etry) { G4EmCalculator emCal; G4double Energy = Etry, dE = 0., dEdx; G4double r, dr; G4double err = 1., errmax = 0.00001; G4int iter = 0 , itermax = 10; while (err > errmax && iter < itermax) { iter++; Energy -= dE; r = emCal.GetRangeFromRestricteDEDX(Energy,particle,material); dr = r - range; dEdx = emCal.GetDEDX(Energy,particle,material); dE = dEdx*dr; err = std::abs(dE)/Energy; } if (iter == itermax) { G4cout << "\n ---> warning: RunAction::GetEnergyFromRestRange() did not converge" << " Etry = " << G4BestUnit(Etry,"Energy") << " Energy = " << G4BestUnit(Energy,"Energy") << " err = " << err << " iter = " << iter << G4endl; } return Energy; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4double RunAction::GetEnergyFromCSDARange(G4double range, G4ParticleDefinition* particle, G4Material* material, G4double Etry) { G4EmCalculator emCal; G4double Energy = Etry, dE = 0., dEdx; G4double r, dr; G4double err = 1., errmax = 0.00001; G4int iter = 0 , itermax = 10; while (err > errmax && iter < itermax) { iter++; Energy -= dE; r = emCal.GetCSDARange(Energy,particle,material); dr = r - range; dEdx = emCal.ComputeTotalDEDX(Energy,particle,material); dE = dEdx*dr; err = std::abs(dE)/Energy; } if (iter == itermax) { G4cout << "\n ---> warning: RunAction::GetEnergyFromCSDARange() did not converge" << " Etry = " << G4BestUnit(Etry,"Energy") << " Energy = " << G4BestUnit(Energy,"Energy") << " err = " << err << " iter = " << iter << G4endl; } return Energy; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......