// // ******************************************************************** // * 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.4 2008/03/31 10:22:59 vnivanch 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 "HistoManager.hh" #include "MuCrossSections.hh" #include "G4Run.hh" #include "G4RunManager.hh" #include "G4UnitsTable.hh" #include "Randomize.hh" #ifdef G4ANALYSIS_USE #include "AIDA/AIDA.h" #endif //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... RunAction::RunAction(DetectorConstruction* det, PrimaryGeneratorAction* prim, HistoManager* HistM) : detector(det), primary(prim), ProcCounter(0), histoManager(HistM) {} //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... RunAction::~RunAction() {} //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void RunAction::BeginOfRunAction(const G4Run* aRun) { G4cout << "### Run " << aRun->GetRunID() << " start." << G4endl; // save Rndm status G4RunManager::GetRunManager()->SetRandomNumberStore(true); CLHEP::HepRandom::showEngineStatus(); ProcCounter = new ProcessesCount; histoManager->book(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void RunAction::CountProcesses(G4String procName) { //does the process already encounted ? size_t nbProc = ProcCounter->size(); size_t i = 0; while ((iGetName()!=procName)) i++; if (i == nbProc) ProcCounter->push_back( new OneProcessCount(procName)); (*ProcCounter)[i]->Count(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void RunAction::EndOfRunAction(const G4Run* aRun) { G4int NbOfEvents = aRun->GetNumberOfEvent(); if (NbOfEvents == 0) return; std::ios::fmtflags mode = G4cout.flags(); G4int prec = G4cout.precision(2); G4Material* material = detector->GetMaterial(); G4double length = detector->GetSize(); G4double density = material->GetDensity(); G4String particle = primary->GetParticleGun()->GetParticleDefinition() ->GetParticleName(); G4double energy = primary->GetParticleGun()->GetParticleEnergy(); G4cout << "\n The run consists of " << NbOfEvents << " "<< particle << " of " << G4BestUnit(energy,"Energy") << " through " << G4BestUnit(length,"Length") << " of " << material->GetName() << " (density: " << G4BestUnit(density,"Volumic Mass") << ")" << G4endl; //total number of process calls G4double countTot = 0.; G4cout << "\n Number of process calls --->"; for (size_t i=0; i< ProcCounter->size();i++) { G4String procName = (*ProcCounter)[i]->GetName(); if (procName != "Transportation") { G4int count = (*ProcCounter)[i]->GetCounter(); G4cout << "\t" << procName << " : " << count; countTot += count; } } G4cout << G4endl; //compute totalCrossSection, meanFreePath and massicCrossSection // G4double totalCrossSection = countTot/(NbOfEvents*length); G4double MeanFreePath = 1./totalCrossSection; G4double massCrossSection =totalCrossSection/density; G4cout.precision(5); G4cout << "\n Simulation: " << "total CrossSection = " << totalCrossSection*cm << " /cm" << "\t MeanFreePath = " << G4BestUnit(MeanFreePath,"Length") << "\t massicCrossSection = " << massCrossSection*g/cm2 << " cm2/g" << G4endl; //compute theoritical predictions // if(particle == "mu+" || particle == "mu-") { totalCrossSection = 0.; for (size_t i=0; i< ProcCounter->size();i++) { G4String procName = (*ProcCounter)[i]->GetName(); if (procName != "Transportation") totalCrossSection += ComputeTheory(procName, NbOfEvents); } MeanFreePath = 1./totalCrossSection; massCrossSection = totalCrossSection/density; G4cout << " Theory: " << "total CrossSection = " << totalCrossSection*cm << " /cm" << "\t MeanFreePath = " << G4BestUnit(MeanFreePath,"Length") << "\t massicCrossSection = " << massCrossSection*g/cm2 << " cm2/g" << G4endl; } G4cout.setf(mode,std::ios::floatfield); G4cout.precision(prec); // delete and remove all contents in ProcCounter while (ProcCounter->size()>0){ OneProcessCount* aProcCount=ProcCounter->back(); ProcCounter->pop_back(); delete aProcCount; } delete ProcCounter; histoManager->save(); // show Rndm status CLHEP::HepRandom::showEngineStatus(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4double RunAction::ComputeTheory(G4String process, G4int NbOfMu) { G4Material* material = detector->GetMaterial(); G4double length = detector->GetSize(); G4double ekin = primary->GetParticleGun()->GetParticleEnergy(); MuCrossSections crossSections; G4int id = 0; G4double cut = 0.; if (process == "muIoni") {id = 1; cut = GetEnergyCut(material,1);} else if (process == "muPairProd") {id = 2; cut = 2*(GetEnergyCut(material,1) + electron_mass_c2); } else if (process == "muBrems") {id = 3; cut = GetEnergyCut(material,0);} else if (process == "muNucl") id = 4; else if (process == "hIoni") {id = 5; cut = GetEnergyCut(material,1);} else if (process == "hPairProd") {id = 6; cut = 2*(GetEnergyCut(material,1) + electron_mass_c2); } else if (process == "hBrems") {id = 7; cut = GetEnergyCut(material,0);} if (id == 0) return 0.; G4int nbOfBins = 100; G4double binMin = -10., binMax = 0., binWidth = (binMax-binMin)/nbOfBins; #ifdef G4ANALYSIS_USE //create histo for theoritical crossSections, with same bining as simulation // const G4String label[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}; AIDA::IHistogram1D* histoMC = 0; AIDA::IHistogram1D* histoTh = 0; if (histoManager->HistoExist(id)) { histoMC = histoManager->GetHisto(id); nbOfBins = histoManager->GetNbins(id); binMin = histoManager->GetVmin (id); binMax = histoManager->GetVmax (id); binWidth = histoManager->GetBinWidth(id); G4String labelTh = label[MaxHisto + id]; G4String titleTh = histoManager->GetTitle(id) + " (Th)"; histoTh = histoManager->GetHistogramFactory() ->createHistogram1D(labelTh,titleTh,nbOfBins,binMin,binMax); } #endif //compute and plot differential crossSection, as function of energy transfert. //compute and return integrated crossSection for a given process. //(note: to compare with simulation, the integrated crossSection is function // of the energy cut.) // G4double lgeps, etransf, sigmaE, dsigma, NbProcess; G4double sigmaTot = 0.; const G4double ln10 = std::log(10.); for (G4int ibin=0; ibin cut) sigmaTot += dsigma; NbProcess = NbOfMu*length*dsigma; #ifdef G4ANALYSIS_USE if (histoTh) histoTh->fill(lgeps,NbProcess); #endif } #ifdef G4ANALYSIS_USE //compare simulation and theory // if (histoMC && histoTh) histoManager->GetHistogramFactory() ->divide(label[2*MaxHisto+id], *histoMC, *histoTh); #endif //return integrated crossSection // return sigmaTot; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... #include "G4ProductionCutsTable.hh" G4double RunAction::GetEnergyCut(G4Material* material, G4int idParticle) { G4ProductionCutsTable* table = G4ProductionCutsTable::GetProductionCutsTable(); size_t index = 0; while ( (table->GetMaterialCutsCouple(index)->GetMaterial() != material) && (index < table->GetTableSize())) index++; return (*(table->GetEnergyCutsVector(idParticle)))[index]; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......