G4-ExampleB1/src/RunAction.cc

105 lines
3.6 KiB
C++

#include "RunAction.hh"
#include "DetectorConstruction.hh"
#include "G4AccumulableManager.hh"
#include "G4LogicalVolume.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4Run.hh"
#include "G4RunManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "PrimaryGeneratorAction.hh"
namespace B1 {
RunAction::RunAction() {
// 定义剂量的单位,以 Gy 为准
const G4double milligray = 1.e-3 * gray;
const G4double microgray = 1.e-6 * gray;
const G4double nanogray = 1.e-9 * gray;
const G4double picogray = 1.e-12 * gray;
new G4UnitDefinition("milligray", "mGy", "Dose", milligray);
new G4UnitDefinition("microgray", "uGy", "Dose", microgray);
new G4UnitDefinition("nanogray", "nGy", "Dose", nanogray);
new G4UnitDefinition("picogray", "pGy", "Dose", picogray);
// 将累加的数据注册到累加管理器
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->RegisterAccumulable(fEdep);
accumulableManager->RegisterAccumulable(fEdep2);
}
RunAction::~RunAction() {}
// 每次 run 调用一次
void RunAction::BeginOfRunAction(const G4Run*) {
// 保存随机数种子
G4RunManager::GetRunManager()->SetRandomNumberStore(false);
// 初始化累加的值
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->Reset();
}
void RunAction::EndOfRunAction(const G4Run* run) {
// event 的数目
G4int nofEvents = run->GetNumberOfEvent();
if (nofEvents == 0) return;
// 合并累加的值
G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
accumulableManager->Merge();
// 计算剂量与方差
// 一次 run 中的总沉积能量
G4double edep = fEdep.GetValue();
G4double edep2 = fEdep2.GetValue();
G4double rms = edep2 - edep * edep / nofEvents;
if (rms > 0.)
rms = std::sqrt(rms);
else
rms = 0.;
// 剂量 = 总沉积能量 / 质量
const DetectorConstruction* detConstruction =
static_cast<const DetectorConstruction*>(G4RunManager::GetRunManager()->GetUserDetectorConstruction());
G4double mass = detConstruction->GetScoringVolume()->GetMass();
G4double dose = edep / mass;
G4double rmsDose = rms / mass;
// Run conditions
// note: There is no primary generator action object for "master" run manager for multi-threaded mode.
G4String runCondition;
const PrimaryGeneratorAction* generatorAction =
static_cast<const PrimaryGeneratorAction*>(G4RunManager::GetRunManager()->GetUserPrimaryGeneratorAction());
if (generatorAction) {
const G4ParticleGun* particleGun = generatorAction->GetParticleGun();
runCondition += particleGun->GetParticleDefinition()->GetParticleName();
runCondition += " of ";
G4double particleEnergy = particleGun->GetParticleEnergy();
runCondition += G4BestUnit(particleEnergy, "Energy");
}
// Print
if (IsMaster()) {
G4cout << G4endl << "--------------------End of Global Run-----------------------";
} else {
G4cout << G4endl << "--------------------End of Local Run------------------------";
}
G4cout << G4endl << " The run consists of " << nofEvents << " " << runCondition << G4endl
<< " Cumulated dose per run, in scoring volume : " << G4BestUnit(dose, "Dose")
<< " rms = " << G4BestUnit(rmsDose, "Dose") << G4endl
<< "------------------------------------------------------------" << G4endl << G4endl;
}
void RunAction::AddEdep(G4double edep) {
// 累加沉积能量
fEdep += edep;
fEdep2 += edep * edep;
}
} // namespace B1