解析Geant4的例子B4b
- B4bActionInitiaization.cc:
物理模型初始化。我认为就是个清单,对粒子出射枪,RunAction,EventAction和SteppingAction都要进行SetUserAction就可以了。
对于B4bActionInitialization::Build(),多线程模式下,每个线程的工作器都使用这种方法,这些工作器的动作类是本地线程。
void B4bActionInitialization::BuildForMaster() {
B4RunAction* runAction = new B4RunAction;
SetUserAction(runAction);
/* SetUserAction(new B4RunAction); */ //直接SetUserAction也可以
}
对于B4bActionInitialization::BuildForMaster(),多线程模式下,运行动作类实例化为全局线程。
void B4bActionInitialization::Build() {
SetUserAction(new B4PrimaryGeneratorAction);
SetUserAction(new B4RunAction);
SetUserAction(new B4EventAction);
B4DetectorConstruction* detectorConstruction = new B4DetectorConstruction;
SetUserAction(new B4SteppingAction(detectorConstruction));
}
- B4DetectorConstruction.cc:
G4VPhysicalVolume* B4DetectorConstruction::Construct() /*探测器创建类*/
{
// Define materials
DefineMaterials();
// Define volumes
return DefineVolumes();
}
先创建world,再创建轮廓形状Solid,再创建LogicalVolume,再创建PhysicalVolume.
最后总是返回PhysicalWorld.
- B4PrimaryGeneratorAction.cc:
建立粒子枪,设置默认粒子类型,动能,方向和初始位置。
- B4bRunAction.cc:
设置每个事例的打印ID。设置分析管理器,利用分析管理器创建直方图和元组。并在析构函数中将管理器删除(delete G4AnalysisManager::Instance();)。
在Run开始时,创建打开一个输出文件。
在Run结束时,判断是总线程还是局部线程,打印统计所得图表并写入输出文件中。关闭文件。
=>写一个返回值为G4Run类型(B4bRunData)的类,这个”值”可以画好图表。
- B4bEventAction.cc:
在Event开始时,将B4bRunData重置。fEdep和fTrackLength是两个二维数组(有两个元素)。所以这时fEdep = {0, 0},fTrackLength = {0, 0}。
fEdep[0]和fTrackLength[0]分别是Absorber(吸收体)的能量沉积和路程。fEdep[1]和fTrackLength[1]是Gap的…
在Event结束时,对fEdep[ ]和fTrackLength[ ]的元素进行直方图和元组的填充。
- B4bSteppingAction.cc:
获取B4bRunData中需要的探测器部分对应的体积,能量沉积和步长。
void B4bSteppingAction::UserSteppingAction(G4Step* step) {
auto volume = step->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
auto edep = step->GetTotalEnergyDeposit();
G4double steplength = 0.;
if(step->GetTrack()->GetDefinition()->GetPDGCharge()!= 0) {
steplength = step->GetStepLength();
}
判定step前后点之间的volume与Absorber还是与Gap相等,然后对fEdep[ ]和fTracklength[ ]的0列或1列元素进行迭加。
auto runData = static_cast<B4bRunData>(G4RunManager::GetRunManager()->GetNonConstCurrentRun());
if(volume == detectorConstruction->GetAbsorberPV()) {
runData->Add(kAbs,edep,tracklength);
}
if(volume==detectorConstruction->GetGapPV()) {
runData->Add(kGap,edep,tracklength);
}
- B4bRunData.cc:
规定了对fEdep[ ]和fTrackLength[ ]中各个元素的操作,包括初始化和直方图填充。
过程分析
Start:
由RunAction创建histogram,创建打开”B4”输出文件。
由EventAction将fEdep[ ]和fTrackLength[ ]各元素初始化为0。
由SteppingAction对fEdep[ ]和fTrackLength[ ]的第0列或第1列元素更新。
End:
由SteppingAction对fEdep[ ]和fTrackLength[ ]的两列元素进行n次更新(每次更新一列)
fEdep = {edep1, edep2} fTrackLength = {tracklength1, tracklength2}
由EventAction画出histgram:
(一次EndOfEvent)
FillH1(0, edep1) /*absorber能量沉积*/
FillH1(1, edep2) /*gap能量沉积*/
FillH1(2, tracklength1) /*absorber路程*/
FillH1(3, tracklength2) /*gap路程*/
(n次EndOfEvent后)
FillH1(0, edep3) FillH1(1, edep4) FillH1(2, tracklength3) FillH1(3, tracklength4)
FillH1(0, edep5) FillH1(1, edep6) FillH1(2, tracklength5) FillH1(3, tracklength6)
FillH1(0, edep7) FillH1(1, edep8) FillH1(2, tracklength7) FillH1(3, tracklength8)
.......
这样在0,1,2,3号图中分别都画好了histogram。
由RunAction判断是局部Run还是全局Run,输出各图的mean和rms值。
运行
创建exampleB4b可执行程序
$ cd $HOME/workdir/geant4/build-basic
$ mkdir build-B4 && cd build-B4
$ cmake ../../examples/basic/B4/B4b
$ make
$ ls
$ ./exampleB4b
Session:/run/beamOn 90
=>这样在B4b文件夹中就生成了B4.root
在B4.root所在的文件夹中打开一个命令窗口
$ root -l plotHisto.C
运行结果如下:
To Be Continued…