// // ******************************************************************** // * 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. * // ******************************************************************** // // $Id: RunAction.cc,v 1.10 2007/12/17 17:22:44 maire Exp $ // GEANT4 tag $Name: geant4-09-03-cand-01 $ // //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... #include "RunAction.hh" #include "DetectorConstruction.hh" #include "PrimaryGeneratorAction.hh" #include "G4Run.hh" #include "G4ProcessManager.hh" #include "G4UnitsTable.hh" #include "G4EmCalculator.hh" #include "G4Electron.hh" #include //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... RunAction::RunAction(DetectorConstruction* det, PrimaryGeneratorAction* kin) :detector(det), primary(kin) { } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... RunAction::~RunAction() { } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void RunAction::BeginOfRunAction(const G4Run*) { //set precision for printing G4int prec = G4cout.precision(6); //instanciate EmCalculator G4EmCalculator emCal; // emCal.SetVerbose(2); // get particle G4ParticleDefinition* particle = primary->GetParticleGun() ->GetParticleDefinition(); G4String partName = particle->GetParticleName(); G4double charge = particle->GetPDGCharge(); G4double energy = primary->GetParticleGun()->GetParticleEnergy(); // get material G4Material* material = detector->GetMaterial(); G4String matName = material->GetName(); G4double density = material->GetDensity(); G4double radl = material->GetRadlen(); G4cout << "\n " << partName << " (" << G4BestUnit(energy,"Energy") << ") in " << material->GetName() << " (density: " << G4BestUnit(density,"Volumic Mass") << "; radiation length: " << G4BestUnit(radl, "Length") << ")" << G4endl; // get cuts GetCuts(); if (charge != 0.) { G4cout << "\n Range cuts : \t gamma " << std::setw(8) << G4BestUnit(rangeCut[0],"Length") << "\t e- " << std::setw(8) << G4BestUnit(rangeCut[1],"Length"); G4cout << "\n Energy cuts : \t gamma " << std::setw(8) << G4BestUnit(energyCut[0],"Energy") << "\t e- " << std::setw(8) << G4BestUnit(energyCut[1],"Energy") << G4endl; } // max energy transfert if (charge != 0.) { G4double Mass_c2 = particle->GetPDGMass(); G4double moverM = electron_mass_c2/Mass_c2; G4double gamM1 = energy/Mass_c2, gam = gamM1 + 1., gamP1 = gam + 1.; G4double Tmax = (2*electron_mass_c2*gamM1*gamP1)/(1.+2*gam*moverM+moverM*moverM); G4double range = emCal.GetCSDARange(Tmax,G4Electron::Electron(),material); G4cout << "\n Max_energy _transferable : " << G4BestUnit(Tmax,"Energy") << " (" << G4BestUnit(range,"Length") << ")" << G4endl; } // get processList and extract EM processes (but not MultipleScattering) G4ProcessVector* plist = particle->GetProcessManager()->GetProcessList(); G4String procName; G4double cut; std::vector emName; std::vector enerCut; size_t length = plist->size(); for (size_t j=0; jGetProcessName(); cut = energyCut[1]; if ((procName == "eBrem")||(procName == "muBrems")) cut = energyCut[0]; if (((*plist)[j]->GetProcessType() == fElectromagnetic) && (procName != "msc")) { emName.push_back(procName); enerCut.push_back(cut); } } // print list of processes G4cout << "\n processes : "; for (size_t j=0; jGetNumberOfElements() == 1) { G4double Z = material->GetZ(); G4double A = material->GetA(); std::vector sigma0; G4double sig, sigtot = 0.; for (size_t j=0; j sigma1; std::vector sigma2; G4double Sig, Sigtot = 0.; for (size_t j=0; j 0.) lambda = 1/sigma1[j]; G4cout << "\t" << std::setw(13) << G4BestUnit( lambda, "Length"); } //mean free path (g/cm2) G4cout << "\n (g/cm2) : "; for (size_t j=0; j 0.) lambda = 1/sigma2[j]; G4cout << "\t" << std::setw(13) << G4BestUnit( lambda, "Mass/Surface"); } G4cout << G4endl; if (charge == 0.) { G4cout.precision(prec); G4cout << "\n-------------------------------------------------------------\n" << G4endl; return; } //get stopping power std::vector dedx1; std::vector dedx2; G4double dedx, dedxtot = 0.; for (size_t j=0; jGetTableSize(); const G4MaterialCutsCouple* couple = 0; G4int index = 0; for (size_t i=0; iGetMaterialCutsCouple(i); if (couple->GetMaterial() == detector->GetMaterial()) {index = i; break;} } rangeCut[0] = (*(theCoupleTable->GetRangeCutsVector(idxG4GammaCut)))[index]; rangeCut[1] = (*(theCoupleTable->GetRangeCutsVector(idxG4ElectronCut)))[index]; rangeCut[2] = (*(theCoupleTable->GetRangeCutsVector(idxG4PositronCut)))[index]; energyCut[0] = (*(theCoupleTable->GetEnergyCutsVector(idxG4GammaCut)))[index]; energyCut[1] = (*(theCoupleTable->GetEnergyCutsVector(idxG4ElectronCut)))[index]; energyCut[2] = (*(theCoupleTable->GetEnergyCutsVector(idxG4PositronCut)))[index]; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void RunAction::CriticalEnergy() { // compute e- critical energy (Rossi definition) and Moliere radius. // Review of Particle Physics - Eur. Phys. J. C3 (1998) page 147 // G4EmCalculator emCal; const G4Material* material = detector->GetMaterial(); const G4double radl = material->GetRadlen(); G4double ekin = 5*MeV; G4double deioni; G4double err = 1., errmax = 0.001; G4int iter = 0 , itermax = 10; while (err > errmax && iter < itermax) { iter++; deioni = radl* emCal.ComputeDEDX(ekin,G4Electron::Electron(),"eIoni",material); err = std::abs(deioni - ekin)/ekin; ekin = deioni; } G4cout << "\n \n critical energy (Rossi) : " << "\t" << std::setw(8) << G4BestUnit(ekin,"Energy"); //Pdg formula (only for single material) G4double pdga[2] = { 610*MeV, 710*MeV }; G4double pdgb[2] = { 1.24, 0.92 }; G4double EcPdg = 0.; if (material->GetNumberOfElements() == 1) { G4int istat = 0; if (material->GetState() == kStateGas) istat = 1; G4double Zeff = material->GetZ() + pdgb[istat]; EcPdg = pdga[istat]/Zeff; G4cout << "\t\t\t (from Pdg formula : " << std::setw(8) << G4BestUnit(EcPdg,"Energy") << ")"; } const G4double Es = 21.2052*MeV; G4double rMolier1 = Es/ekin, rMolier2 = rMolier1*radl; G4cout << "\n Moliere radius : " << "\t" << std::setw(8) << rMolier1 << " X0 " << "= " << std::setw(8) << G4BestUnit(rMolier2,"Length"); if (material->GetNumberOfElements() == 1) { G4double rMPdg = radl*Es/EcPdg; G4cout << "\t (from Pdg formula : " << std::setw(8) << G4BestUnit(rMPdg,"Length") << ")"; } } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......