蒙特卡洛方法GEANT4工具包B1例子解读.docx

上传人:b****3 文档编号:5295328 上传时间:2022-12-15 格式:DOCX 页数:25 大小:2.19MB
下载 相关 举报
蒙特卡洛方法GEANT4工具包B1例子解读.docx_第1页
第1页 / 共25页
蒙特卡洛方法GEANT4工具包B1例子解读.docx_第2页
第2页 / 共25页
蒙特卡洛方法GEANT4工具包B1例子解读.docx_第3页
第3页 / 共25页
蒙特卡洛方法GEANT4工具包B1例子解读.docx_第4页
第4页 / 共25页
蒙特卡洛方法GEANT4工具包B1例子解读.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

蒙特卡洛方法GEANT4工具包B1例子解读.docx

《蒙特卡洛方法GEANT4工具包B1例子解读.docx》由会员分享,可在线阅读,更多相关《蒙特卡洛方法GEANT4工具包B1例子解读.docx(25页珍藏版)》请在冰豆网上搜索。

蒙特卡洛方法GEANT4工具包B1例子解读.docx

蒙特卡洛方法GEANT4工具包B1例子解读

简单对example/B1做一个源码解读。

我用的是虚拟机,Ubuntu16.04,GEANT4.10.06版本,ROOT6.06版本

对于Geant4模拟,我们关心它到底是怎样使用的,到底是怎样获取我们想要的信息,即信息抽取。

Geant4的模拟流程中从信息流的整合来看,物理过程框架可从大到小分为Run、Event、(Track)、Step

先放两张图,第一张展现了他们之间的组合关系:

一个Run包含多个Event,每个Event包含多个Track,每个Track包含多个Step。

从B1例子来看,如果我们想知道每个Event总共沉积多少能量,只需要在SteppingAction中调用一个Event的储值变量,将该Event下的每个Step沉积能量累加到Event的储值变量中便可。

每个Event由很多Track及Step组成,其中,Track用来表征一个不变的粒子,并描述其径迹,Step是Geant4中最基本的蒙卡抽样概念,用以“试探”当前粒子的物理过程,当发生能量交换时,便会衍生出新的粒子即径迹,比如,一个gamma射线在某一Step发生康普顿效应时,便产生一个新粒子-->一个吸收了能量的新电子,然后再各自描述其径迹。

三者间的联系见下图:

Include、source文件夹

首先打开B1例子文件夹,其中,两个子文件夹,一个是include头文件,另一个是source源文件,初学者可以简单认为,include里面是对类的描述,比如我们用到的成员对象、函数等,而source是对类中函数进行功能填充、定义。

所以我们可以认为,include是声明,source是定义,source在定义过程中需要调用include文件,详细的源码在后面解读。

CMakeList.txt文件

G4的编译是通过cmake,这里说一下,推荐大家手动安装高版本cmake,我用的cmake版本是3.16,下载网址:

https:

//cmake.org/

打开CMakeList.txt文件,大部分不需要改动,其中需要注意的是project(B1)代表项目名称是B1。

.mac文件

.mac文件是控制文件,相当于写了一个脚本外部控制、改变G4中的一些初始条件,例如发射粒子的类别、能量、方向等等;另外有些还能改变探测器的几何、角度等,具有较强的可操作性:

/run/initialize//run管理初始化,可以认为初始化程序

/gun/particlegamma//定义出射粒子,这里用的是ParticleGun,若GPS则换成/gps/具体可查表

/gun/energy6MeV//定义出射能量

/run/beamOn1000//跑1000个粒子

 

exampleB1.cc文件

首先是调用一系列的头文件,例如,B1DetectorConstruction.hh是调用探测器B1ActionInitialization.hh是调用用户管理初始化,这两个后续会在include文件夹和source文件夹分别讲解,这里我们先知道我们调用了他们。

G4MTRunManager.hh是多线程运行管理类,在多线程模式下调用,相应的G4RunManager.hh则是一般模式运行管理类,G4UImanage.hh是UI界面管理类,用于交互式,QBBC.hh是G4模块化物理过程调用,G4VisExecutive.hh是可视化操作,G4UIExecutive.hh是UI操作,Randomize.hh是随机数调用。

在main()函数中,输入两个参数(intargc,char*argv),在VS中,argc代表输入的参数个数,这个参数指的是我们在终端输入的字符串个数,例如输入./examplerun.mac则argc等于2。

接下来我们定义了一个UI操作指针(NULL),用于用户交互操作的。

接着给了一个判断,若argc==1给ui指针申请新内存空间,即不再是NULL指针。

接下来定义运行管理器runManager,可以认为是一个大脑能够管理程序的运行。

然后运行管理指针调用SetUserInitialization()函数,分辟内存空间初始化B1DetectorConstruction的对象,同理,定义模块化物理过程QBBC对象physicsList,对该对象进行初始化;对B1ActionInitialization的对象初始化。

需要注意的是,这里的B1DetectorConstruction和physicsList是强制类,也就是你必须设置他们,还有一个强制类包含在B1ActionInitialization当中,后续会提到。

可视化管理初始化,通过该类和UI操作类的结合,运行程序时能够看到几何模型和粒子输运过程。

定义UI管理类,前面定义的ui为null,则执行if语句,此时为批处理模式,由UI管理类指针指向命令行,输入"/control/execute/run.mac"(假设输入run.mac,则argv[1]代表程序名后第一个字符串run.mac)。

若前面定义的ui不为null,则不执行if语句,此时为交互式模式,UI管理类会默认执行"/control/executeinit_vis.mac"。

我们可以打开init_vis.mac看看文件中内容,run指的是运行管理器,/run/initialize即运行初始化,这里最后一行调用执行了另一个控制文件vis.mac,类似于嵌套,再打开vis.mac,发现一直在使用/vis/..命令,这里的vis是我们前面定义的可视化管理器,通过该管理器,我们能够打开可视化界面观察几何等等,需要注意的是这里有两种界面,一种是OGL;一种是OGLIX,后者几何固定不可旋转平移观察,建议使用前者。

ui->SessionStart();则是打开对话框,如图所示,若注释掉这一句,可视化一闪就关闭了,因此有点像”pause”的作用。

最后删除ui,释放内存。

init_vis.mac和vis.mac文件

最后删除两个管理器。

 

B1Analysison.hh文件

Root数据存储头文件

 

B1DetectorConstruction.hh文件

首先G4VUserDetectorConstruction是基类,B1DetectorConstruction是其派生类,文件涉及到逻辑体、物理体指针变量,所以添加上G4VPhysicalVolume和G4LogicalVolume两个大类,至于逻辑体和物理体的意义,在source文件中会讲,简单的说就是在G4里,定义几何模型需要通过solid—logical—physical三步,solid是构建几何框架,logical是填充材料,physical是放置、copy等。

在B1DetectorConstruction类中,我们声明了构造函数、析构函数,分别用于初始化、内存释放。

另外声明了一个返回值是物理体指针G4VPhysicalVolume的Contruct()函数,这是我们定义探测器的函数,一般返回值是world物理体指针,所谓world是G4定义的几何世界母体,可以认为是虚拟的实验大厅。

接下来是自定义了一个GetScoringVolume()的函数,返回一个fScoringVolume的指针,指针类型是G4LogicalVolume逻辑体。

而这个fScoringVolume指针我们在protect中定义了,他是一个逻辑体指针,保护成员变量,仅在该类中允许调用。

B1DetectorConstruction.cc文件

调用头文件,其中包括了G4RunManager类,G4NistManager材料库,这个类是G4内置材料数据库。

G4Box类,长方体几何框架构建,还有柱、球、三角等就不一一列了。

还有G4LogicalVolume、G4PVPlacement、G4SystemOfUnits分别是逻辑体、放置形成物理体、系统单位。

在构造函数中,对fScoringVolume指针初始化赋值,析构函数没有内容。

在construct()函数中,我们定义一个nist指针,他是G4NistManager的实例化,通过指向FindOrBuildMaterial()函数可以在库中寻找材料。

接下来构造world世界母体,先定义一个长方体solidWorld名称为”World”半长宽高分别由对应参数带入。

随后构建逻辑体logicWorld,将wold_mat材料填充到solidWorld中。

最后,定义物理体physWorld,将逻辑体放在world中。

checkOverlaps是用于检查几何是否有重叠,其余几何建模一样,不一一列举了。

最后将逻辑体logicShape2传递给fScoringVolume,于是此时fScoringVolume指针地址与logicShape2一致。

B1ActionInitialization.hh文件

B1ActionInitialization类继承于G4VUserActionInitialization基类,包括构造、析构函数,以及BuildForMaster()函数和Build()函数,分别对应多线程模式下用户行为初始化和单线程模式用户行为初始化

 

B1ActionInitialization.cc文件

B1ActionInitialization类的Build()函数,分别通过SetUserAction()函数对粒子发射器、run、event、step设置用户行为,其中,在B1SteppingAction构造函数中有一个形式参数,说明用到了eventAction指针变量。

 

B1PrimaryGeneratorAction.hh文件

B1PrimaryGeneratorAction类继承于G4VUserPrimaryGeneratorAction基类,是G4的一个强制类,用于定义粒子发生器,这里用到了G4ParticleGun类的粒子枪,另外,派生类还用到了G4Event类以及G4Box类。

在类体里,声明了构造、析构函数,另外在GeneratePrimaries()函数中用到了G4Event类型指针,代表每一次event都会调用一次粒子发生器。

自定义GetParticleGun()函数返回一个G4ParticleGun类型的指针fParticleGun,该指针在私有成员变量中定义,另外还定义了一个fEnvelopeBox的指针,至于这个指针有什么用,得看后面程序。

 

B1PrimaryGeneratorAction.cc文件

写入需要的头文件,在构造函数中进行初始化,给fParticleGun和fEnvelopeBox赋值null,定义一个fParticleGun每次event释放粒子数为1。

定义G4ParticleTable类对象particleTable,用于获取粒子列表,然后定义一个G4ParticleDefinition类的对象particle,然后通过particleTable在粒子列表中寻找“gamma”粒子,赋值给particle。

fParticleGun通过函数,设置粒子种类(gamma)动量(方向)以及粒子的动能,至此,构造函数的初始化完成。

在析构函数中,删除了fParticleGun,这是因为fParticleGunnew了一个新的内存空间,在粒子射出后要删除这部分内存。

GeneratePrimaries(G4Event*anEvent)函数每次event都调用一次,用于发射粒子,在此处用户可以设置粒子能谱分布、角度分布、源的位置分布等等。

首先,if语句判断fEnvelopeBox真假,前面构造函数给fEnvelopeBox赋初值null因此,第一个event到来时,该语句执行为真,则在逻辑题容器G4LogicalVolumeStore(先实例化)中找到名称是“Envelope”的逻辑体,定义一个指针envLV指向其地址,再通过envLV的GetSolid()函数抽取“Envelope”的solid实体,并强制G4Box类,指针fEnvelopeBox指向其地址,注意,第二个event到来的时候就不执行了,因为以后fEnvelopeBox!

=null了,以后每次event循环,一直执行下面if(fEnvelopeBox)的内容,即得到fEnvelopeBox几何参数。

为了保护程序的完整性,给了一个else,指的是如果找不到fEnvelopeBox,输出提示语。

之后把得到的fEnvelopeBox几何参数给到x0,y0,z0变量,通过fParticleGun设置粒子位置分布......做了这么多绕到粒子位置分布其实挺无聊的。

最后,fParticleGun调用了一个GeneratePrimaryVertex(anEvent)函数,这个很重要,大意就是开关,每个event过来,这个粒子发生器就发射一次。

B1RunAction.hh文件

B1RunAction继承于G4UserRunAction,声明了构造、析构函数,另外,给了一个BeginOfRunAction(constG4Run*)和EndOfRunAction(constG4Run*),指的是Run开始的时候以及Run结束的时候,其中const将run指针所指向的内存空间的值设为定值,也就是说每一个run所指向的内容是不变的,而每个run指针的地址是能够变的(可以理解成每次run中各种信息被保存在run指针中,是一个快照信息固定住了,但是多次run指针各自独立,ID是不同的)。

随后又定义了一个AddEdep()函数,把它定义成了一个累加函数。

私有成员变量fEdep和fEdep2,这里注释掉了模板类G4Accumulable。

因为觉得没有必要,B1是算入射粒子在材料中的总能量沉积,用全局变量直接输出,所以注释掉了。

B1RunAction.cc文件(Begin)

在RunAction.cc中,我们在后面EndOfRunAction()函数中调用了探测器几何以及粒子发生器,所以在抬头添加对应的头文件,另外,与B1官方例子不同的是,我添加了root格式数据存储及输出,于是要加上B1Analysis.hh头文件,相当于调用G4root,在头文件中,我注释掉了G4AccumulableManager.hh,因为实在觉得没有必要......B1例子是算入射粒子在材料中的总能量沉积,可以用全局变量直接输出就好,所以我直接注释掉了,后面相应用到这部分的我也注释掉了。

首先在构造函数中,给fEdep和fEdep2进行初始化,另外,定义了一批新的剂量单位。

实例化分析管理器,给管理器中创造两个H1直方图,分别是“fEdep”和“fEdep2”,后面给出bin和x轴范围,同时还创造了tree分支。

BeginOfRunAcrion(constG4Run*)函数在每次run的时候调用一次,实例化分析管理器,打开文件“Mydata”(没有的话会自动创建)。

至于,.cc文件中的EndOfRunAcrion(constG4Run*)函数是在该run结束的时候返回来调用,因此,接下来执行该run下的一个个event事件。

 

B1EventAction.hh文件

B1EventAction继承于G4UserEventAction基类,在构造函数中有形参runAction,同样的有两个虚方法BeginOfEventAction()和EndOfEventAction(),用于循环各个event。

自定义一个AddEdep()函数,该函数与前面runaction中函数不同,用于fEventAction->AddEdep(),对每个step累加,最后一个step输出一个event的能量沉积。

定义了三个私有变量,分别是fRunAction以及两个double型数据。

 

B1EventAction.cc文件(Begin)

构造函数初始化,将runAction指针地址赋给fRunAction,用于后面EndOfEventAction()函数中,fRunAction->AddEdep(),对每一个event做累加,最后一个event输出整个run的总能量沉积。

fEdep赋值0。

BeginOfEventAction()中,fEdep=0,意味着每个event到来时fEdep都将清零,有利于记录每一个event的fEdep累积值。

 

B1SteppingAction.hh文件

B1SteppingAction继承于G4UserSteppingAction基类,在构造函数中有形参eventAction,有一个虚方法UserSteppingAction(constG4Step*)用于循环每个step,其中step指针指向的内存空间值无法改变,相当于这个step已经快照好了,我们只是去取用它。

 

B1SteppingAction.cc文件

在构造函数中,fScoringVolume赋值null,当前event下的eventAction地址赋给fEventAction指针。

UserSteppingAction(constG4Step*)中,在第一次step到来时,此时fScoringVolume为假,则执行第一个if(!

fScoringVolume)语句,语句中,定义了一个detectorConstrction对象,通过运行管理器,得到用户定义的探测器构造,detectorConstrction调用类体函数GetScoringVolume(),获取logicShape2的逻辑体(在B1DetectorConstruction.cc中定义),并将它的地址赋给指针fScoringVolmue(这个fScoringVolmue是B1SteppingAction类的私有变量与B1DetectorConstruction类中私有变量fScoringVolmue,是通过指针传递建立联系)。

可以简单认为此时的fScoringVolmue已经是指代logicShape2了。

在下一个step开始以及以后的循环中,if语句不再执行直至下一个event到来。

接下来定义了一个逻辑体指针volume,获取该step的逻辑体(确定该step的位置),通过if(volume!

=fScoringVolume)return;判断step是否则shap2中,若不在跳出循环,若在继续执行下一行命令,获取该step的能量沉积,并赋给一个临时变量edepStep。

执行fEventAction->AddEdep(edepStep);即一个event下step不断循环,fEdep则不断累加。

直至最后一个step结束,fEdep代表了该event的能量沉积。

B1EventAction.cc文件(End)

一个event结束后会回到EndOfEventAction()函数,此时fEdep代表了该event的能量沉积,通过分析管理器,将数据fill填充到表格和tree中。

最后fRunAction调用成员函数AddEdep(fEdep)对fEdep累加(event开始循环,fEdep累加代表了多个event的能量沉积)直至最后一个event到来,这时fEdep代表了整个run的总能量沉积,再退回到RunAction.cc的EndOfRunAction()函数中。

 

BRunAction.cc文件(End)

首先,到这一步意味着一个run结束了。

通过run->GetNumberOfEvent()获取这个run有多少个event。

根据fEdep和fEdep2定义一个rms变量,rms大于0开根号,否则赋值0。

和UserSteppingAction(constG4Step*)中一样,我们定义了一个detectorConstruction对象,获取Shape2的逻辑体,通过GetMass()得到逻辑体的单位质量赋值给mass,定义dose和rmsDose。

再定义一个generateAction对象,获取particleGun指针的信息,用于打印信息。

 

打印信息,写入文件,关闭文件。

 

运行结果1:

./exampleB1

可以通过UI界面输入指令,例如/control/execute/run.mac或者/run/beamOn100等

运行结果2:

./exampleB1run2.mac生产root文件存储

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1