B3 案例实现了的使用方法有:
- 利用 MultiFunctionalDetector + PrimitiveScorer + HitMap 而不是MySensitiveDetector + ProcessHit获取输出
- 利用 PhysicsList 实现自定义涉及的物理反应类型
- 利用 StackingAction 实现忽略作为二次粒子的中子
注:1处My**强调为用户自定义类以区别,即后者需要更多的自定义代码,前者都是使用程序定义好的类
HitMap的使用
HitCollection是Hit的容器类,HitMap是HitCollection的子类,相比于使用MySensitiveDetector + ProcessHit在每一个Step进行灵活输出,使用HitMap能够更方便地获取Event中的统计结果,两者各有取舍。
HitMap由MultiFunctionalDetector创建,准确的来说,对于一个MultiFunctionalDetector,每一个需要测量的物理量对应一个PrimitiveScorere,而HitMap是由PrimitiveScoerer创建的,存在着对应的关系。
// DetectorConstruction::ConstructSDandField
G4SDManager::GetSDMpointer()->AddNewDetector(cryst);
auto cryst = new G4MultiFunctionalDetector("crystal");
G4VPrimitiveScorer* primitiv1 = new G4PSEnergyDeposit("edep");
cryst->RegisterPrimitive(primitiv1);
SetSensitiveDetector("CrystalLV",cryst);
// EventAction::EndOfEventAction
G4HCofThisEvent* HCE = evt->GetHCofThisEvent(); // 获取HitMap
G4SDManager* SDMan = G4SDManager::GetSDMpointer();
fCollID_cryst = SDMan->GetCollectionID("crystal/edep");
auto evtMap = (G4THitsMap<G4double>*)(HCE->GetHC(fCollID_cryst));
std::map<G4int,G4double*>::iterator itr; // 遍历能量沉积
for (itr = evtMap->GetMap()->begin(); itr != evtMap->GetMap()->end(); itr++) {
///G4int copyNb = (itr->first);
G4double edep = *(itr->second);
}
PhysicsList的使用
如图
// PhysicsList::PhysicsList
RegisterPhysics(new G4DecayPhysics()); // Default physics
RegisterPhysics(new G4EmStandardPhysics()); // EM physics
RegisterPhysics(new G4RadioactiveDecayPhysics()); // Radioactive decay
StackingAction的使用
如代码所示
G4ClassificationOfNewTrack StackingAction::ClassifyNewTrack(const G4Track* track)
{
//keep primary particle
if (track->GetParentID() == 0) return fUrgent;
//kill secondary neutrino
if (track->GetDefinition() == G4NeutrinoE::NeutrinoE()) return fKill;
else return fUrgent;
}