
1. 为什么第一天的Geant4学习要“慢慢来”Day01Geant4。我猜正在读这篇文章的你要么是刚接到一个粒子物理、核技术或医学物理相关的课题要么是对蒙特卡洛模拟有强烈好奇心的自学者——总之你终于打开了一个在圈内鼎鼎大名、却也以“陡峭学习曲线”著称的C工具包。先简单交代背景。Geant4的定位是“基于蒙特卡洛方法的粒子输运模拟工具包”不是像Origin那样双击打开就能画图的软件而是由CERN等全球数十家高能物理实验室共同维护的、以C类库形式存在的“积木盒”。它能模拟中子、质子、电子、光子、各种介子乃至离子在物质中的输运、能量沉积、反应产物跟踪也能模拟探测器几何、灵敏体积内的响应。这意味着只要你的研究涉及“放射源照到某种材料上会发生什么”“粒子穿过这个屏蔽层后还剩多少能量”它都可以派上用场。但它真正折磨人的地方在于上手路径极窄。初学阶段大部分时间不是花在写物理分析上而是花在理解它的“抽象建模方式”和“强制代码组织规范”上。Day01如果上来就盯着海量源码试图读懂每一个函数大概率撑不过两个小时就会想放弃。所以第一天的最高优先级不是“我要写一个多么复杂的弹道模拟”而是“把环境搭好、把最小的可运行示例跑起来、把Geant4的核心对象关系在脑子里立住”。这篇文章就是记录我第一天是如何在“一头雾水”和“豁然开朗”之间反复横跳最终把Geant4的基本骨架跑通的全过程。2. Geant4的核心抽象模型第一天必须看懂的四层关系2.1 从Run到Step粒子模拟的“粒度”到底是怎么划分的第一次接触Geant4你会看到一堆以Run、Event、Track、Step为核心的关键词。这四个词看似抽象但用“拍摄一部纪录片”来理解就很直观Run一次完整拍摄整个模拟任务比如“向铅屏蔽层发射100万条10 MeV的γ射线”。Event每一个镜头一条入射粒子从出发到能量耗尽或离开世界边界的全过程对应一次“事件”。Track某个粒子的运动轨迹线段在输运过程中粒子可能发生散射、产生次级粒子每条新粒子都拥有自己的Track。Step轨迹上的一小段从当前位置到下一次物理相互作用发生位置之间的路径段。Geant4的做法是一个Run包含多个Event每个Event内部可能分裂出许多Track每个Track又由一串Step构成。模拟计算的核心就是在每个Step上比较各种物理过程的反应概率、随机决定“这段路径走了多远”“在终点地方发生了什么”。理解了这四层关系你才能看懂程序里各种类的行为。比如你写RunAction就是定义“一次运行开始前、结束后要统计什么”写SteppingAction则是“每走一个Step都要干点什么比如记录当前能量”。第一天读代码时经常被回调函数弄晕但只要抱着“我是在不同的粒度节点上插入自定义逻辑”这个思路就基本能顺着代码走下去了。2.2 G4RunManager控制一切的“导演”使用Geant4时几乎每个main函数里都会看到一段模板式的初始化代码#include G4RunManager.hh #include G4UImanager.hh #include QGSP_BERT.hh int main(int argc, char** argv) { // 创建RunManager它是整个模拟的控制中心 G4RunManager* runManager new G4RunManager(); // 设置必须的三个“核心零件” runManager-SetUserInitialization(new DetectorConstruction()); runManager-SetUserInitialization(new QGSP_BERT()); runManager-SetUserInitialization(new ActionInitialization()); // 运行一次初始化 runManager-Initialize(); // 执行宏命令 G4UImanager* UI G4UImanager::GetUIpointer(); UI-ApplyCommand(/run/beamOn 10); delete runManager; return 0; }这段代码里的顺序很关键。Geant4要求你在调用Initialize之前把“探测器几何”“物理列表”“粒子源动作”三个对象都挂载好。缺少任何一个后面运行会直接报错。G4RunManager在整个模拟中负责调取几何、初始化物理过程、调度事件循环、统管随机数是名副其实的“总控导演”。第一天不要求你能完全读懂它内部的源码但要养成一个习惯每打开一个示例项目先在main函数里找这三样东西是谁、在哪定义、注册顺序是什么。2.3 几何、物理与源铁三角的关系逻辑Geant4把模拟过程拆成了三个独立的维度几何世界长什么样、物理粒子与物质之间会发生哪些反应、源什么样的粒子从哪个方向来。这个拆分是它最大的设计优点——在实际科研中研究“某探测器在不同结构下的响应”时只需要改几何文件研究“不同物理模型对剂量分布的影响”时只需要换一个物理列表。代码模块互为解耦改一处不会牵动你不想动的地方。DetectorConstruction负责构建世界体积、材料定义、探测器敏感区域。它继承自G4VUserDetectorConstruction。PhysicsList选择要加载的物理过程。常用有QGSP_BERT、FTFP_BERT、QGSP_BIC之外不同粒子能量范围对应不同推荐列表这让新手很晕。其实大部分“探测量能沉积”类的模拟用QGSP_BERT就能覆盖绝大多数电磁与强子过程第一天先不要纠结。PrimaryGeneratorAction设置入射粒子的类型、能量、位置、方向。最基础的是G4ParticleGun进阶的有GPSGeneral Particle Source模块。三个维度互不干扰是Geant4对用户最友好的部分。作为第一天只要你能分清这三个类的职责再去看B1/B4系列的示例两个月后你写自定义几何也不会觉得困难。3. 环境搭建从源码编译到跑通第一个示例的完整过程3.1 系统依赖与前置工具的检查Geant4对操作系统没有严格限制目前官方同时支持Linux、macOS和Windows。但我要直说在Linux环境特别是Ubuntu系下踩坑最少、性能最好绝大多数粒子物理和核物理课题组也是基于CentOS/Ubuntu服务器运行的。第一条经验就是如果是为了学习或科研请优先选择Linux省去后续很多路径、动态库、图形库的麻烦。Ubuntu 22.04下先把基础工具装齐sudo apt update sudo apt install cmake g make libx11-dev libxerces-c-dev libmotif-dev \ libgl1-mesa-dev libglu1-mesa-dev libxt-dev libxi-dev libxmu-dev \ freeglut3-dev libboost-all-dev libssl-dev用cmake编译时缺哪个包就补哪个但要特别注意Qt支持相关的模块。如果后续想用可视化界面配置时需要加上-DGEANT4_USE_QTON并确保系统里装了Qt5开发组件sudo apt install qtbase5-dev qt5-qmake libqt5opengl5-dev我第一天因为没有提前安装mesa和GLU库导致编译时Geant4的可视化模块直接禁用后面跑示例只能用文本输出失去了一半的乐趣。这类基础依赖问题虽然不致命但非常打击初学积极性。3.2 下载源码与数据文件从Geant4官网下载页面获取Source和Data文件。强烈建议不要用git clone方式获取最新的开发分支而是老老实实下载稳定发布版的源代码压缩包。默认的主干代码偶尔会引入新的实验特性第一天不适合去挑战不稳定因素。数据文件方面Geant4运行不同的物理过程和粒子类型时需要调用一系列核数据文件包括G4NDL中子数据、G4EMLOW低能电磁数据、G4PhotonEvaporation光子蒸发、G4RadioactiveDecay放射性衰变、G4PARTICLEXS粒子反应截面、G4SAIDDATA等。这些数据以.tar.gz压缩包提供体积加起来超过3GB直接解压到一个目录。比如我放在mkdir -p ~/Geant4/geant4-v11.2.0 mkdir -p ~/Geant4/data cd ~/Geant4/data tar -xzf ../G4NDL-4.7.tar.gz tar -xzf ../G4EMLOW-8.2.tar.gz # ... 其余数据包类似编译阶段不会用到数据文件但运行模拟时会去读取环境变量Geant4_DATA_DIR需要指向这个数据目录稍后在环境配置里讲。3.3 源码编译过程中的三个关键参数假设源码位于~/Geant4/geant4-v11.2.0/source建议的构建流程是cd ~/Geant4 mkdir -p build cd build cmake -DCMAKE_INSTALL_PREFIX~/Geant4/geant4-v11.2.0 \ -DGEANT4_USE_QTON \ -DGEANT4_USE_OPENGL_X11ON \ -DGEANT4_INSTALL_DATAOFF \ ../geant4-v11.2.0/source make -j8 make install这里的三个参数值得说清楚DCMAKE_INSTALL_PREFIX指定安装目录。若不设置默认会装到/usr/local后续卸载、换版本会比较痛苦。设置成见名知义的目录方便并存多个版本。DGEANT4_USE_QTON激活Qt界面支持。这样运行示例时可以通过/control/execute vis.mac打开可视化窗口观察粒子径迹。DGEANT4_INSTALL_DATAOFF让cmake不自动下载数据。数据包太大且下载源在国外服务器国内网络环境下经常失败建议手动下载解压后填对路径反而更可控。编译耗时和CPU核心数成正比。我使用make -j8大约花了20分钟。如果你机器的内存小于4GB建议降低并行数否则容易编译到一半内存不足导致进程被kill。初次接触的同学最容易在这里失去耐心务必给自己留出充足的时间。3.4 环境变量设置与验证安装安装完成后需要在用户的.bashrc或.zshrc中写入export G4ROOT$HOME/Geant4/geant4-v11.2.0 export PATH$G4ROOT/bin:$PATH export LD_LIBRARY_PATH$G4ROOT/lib:$LD_LIBRARY_PATH export G4DATA$HOME/Geant4/data export G4NDLDATA$G4DATA/G4NDL-4.7 export G4EMLOWDATA$G4DATA/G4EMLOW-8.2 # ... 每一项数据包都需要单独设置手动设置这么多环境变量确实繁琐Geant4帮我们准备了一个“一键加载”脚本。在安装后的bin目录下执行source ~/Geant4/geant4-v11.2.0/bin/geant4.sh这个脚本会自动将运行的库路径、数据路径配置好。前提是你要把数据包解压到cmake配置时识别的默认路径或者在脚本里手动修改路径。验证是否安装成功ls $G4ROOT/bin如果bin目录下出现geant4-config命令可以执行geant4-config --version which geant4-config输出版本号后说明安装工作完成。这一步看似简单但很多人的坑在于source geant4.sh之后马上新开一个终端忘记重新加载环境变量导致运行示例时找不到Geant4动态库。每次新开终端都要先source一遍环境脚本这是Geant4新手最先遇到的“阴间操作”。4. 跑通B1示例最容易“照抄成功”的第一个模拟程序4.1 B1是什么一个“γ射线打铅板和闪烁体”的最小模型编译安装好Geant4之后第一时间当然是找一个自带示例练手。Geant4安装包里自带了大量examples目录其中B1、B2、B3、B4属于入门级基础示例。B1的结构极简一个平行板几何前方是铅屏蔽层后面是一个“闪烁体探测器”一束单能γ射线从外侧射向铅板一部分γ光子被吸收或散射一部分穿透并进入闪烁体产生能量沉积。B1的意义不是模拟复杂的医学物理问题而是让你一次性看全Geant4项目必须的几个文件DetectorConstruction.cc几何、PhysicsList在B1里其实通过QGSP_BERT设置、PrimaryGeneratorAction.cc粒子源、RunAction.cc统计结果、EventAction.cc单事件处理、SteppingAction.cc每步处理。4.2 逐文件拆解几何构建中逻辑与物理体积的差别整个Geant4的几何体系遵循一套固定逻辑先定义材料再建立实心几何体Solid然后给实心体赋上材料形成逻辑体积Logical Volume最后将逻辑体积放置到母体积中成为物理体积Physical Volume。第一次接触会疑惑“为什么要绕这么大一圈”。举个大家都能懂的比喻实心几何体是“毛坯房的户型图”逻辑体积是“装修方案”物理体积才是“真正坐落于小区某栋某层的房间”。Geant4需要这种多级区分是因为蒙特卡洛模拟必须在几何层面回答“当前Step在哪个体积内”“边界在哪”“体积之间如何嵌套”等问题。逻辑体积只负责定义形状和材料物理体积才负责描述位置和层级关系这和游戏引擎里“预制体”和“场景实例”的关系异曲同工。B1的DetectorConstruction核心代码大概是这样的结构// 定义材料铅和闪烁体 G4Material* lead new G4Material(Lead, 82.0, 207.2, 11.35*g/cm3); G4Material* scint new G4Material(Scintillator, 1.0, 1.01, 1.032*g/cm3); // 定义世界几何体 G4double worldSize 3.0*m; G4Box* worldSolid new G4Box(WorldSolid, worldSize/2, worldSize/2, worldSize/2); G4LogicalVolume* worldLog new G4LogicalVolume(worldSolid, vacuum, WorldLog); G4VPhysicalVolume* worldPhys new G4PVPlacement( nullptr, G4ThreeVector(), worldLog, WorldPhys, nullptr, false, 0); // 定义铅板 G4Box* leadSolid new G4Box(LeadSolid, 5.0*cm, 5.0*cm, 2.0*cm); G4LogicalVolume* leadLog new G4LogicalVolume(leadSolid, lead, LeadLog); new G4PVPlacement(nullptr, G4ThreeVector(0,0,-5.0*cm), leadLog, LeadPhys, worldLog, false, 0);读懂这段代码你会发现每一步都有一个“名字字符串”参数例如WorldSolid、“WorldLog”、“WorldPhys”。这些名字不是摆设后续通过G4LogicalVolumeStore或G4PhysicalVolumeStore可以按名字查找体积对象在写可视化、统计或步进判断时非常有用。第一天不需要背API但一定要搞懂这串“几何四兄弟”的先后顺序否则自己加块体时总会报“逻辑体未放置”或“物理体指针悬空”的错。在B1里还有一段非常关键的定义就是“哪个体积是灵敏探测器”。你必须手动将闪烁体逻辑体积“登记”为SDSensitive DetectorG4SDManager* SDman G4SDManager::GetSDMpointer(); G4VSensitiveDetector* det new SensitiveDetector(ScintSD); SDman-AddNewDetector(det); scintLog-SetSensitiveDetector(det);如果忘了这一步即使粒子真的穿过探测器代码也不会记录任何能量沉积后面统计结果就是零。这是初学阶段最容易踩的坑之一。4.3 PrimaryGeneratorAction与粒子枪设置B1中的粒子源设置在PrimaryGeneratorAction.cc中核心是G4ParticleGun。初始化时确定粒子种类如gamma、e-、proton之后在GeneratePrimaries(G4Event* evt)函数中设置每次事件粒子产生的位置、方向和动能G4ParticleGun* gun new G4ParticleGun(1); // 每次发射1个粒子 G4ParticleDefinition* particle G4ParticleTable::GetParticleTable()-FindParticle(gamma); gun-SetParticleDefinition(particle); gun-SetParticleEnergy(6.0*MeV); gun-SetParticlePosition(G4ThreeVector(0.0*cm, 0.0*cm, -20.0*cm)); gun-SetParticleMomentumDirection(G4ThreeVector(0.0, 0.0, 1.0));注意Geant4是个坚持使用“带单位”数字的框架能量写成6.0MeV位置写成-20.0cm这不是为了矫情而是内部统一将单位变换成标准单位制。如果你直接写6.0那么物理量的数值是多少只能靠猜。Geant4内部默认使用毫米、纳秒、兆电子伏特、兆电子伏特等单位作为内核单位所有界面参数都要显式乘上CLHEP封装好的常量如cm、MeV、s等。这种设计大幅减少了不同模块之间单位混乱的问题但是对第一次接触的人来说会觉得到处乘单位很麻烦。我的建议是从第一天起就老老实实按规范写单位慢慢你会发现它的好处——跨项目、跨机器复制代码时几乎不会出现“这个长度到底意味着什么”的困惑。粒子束的方向也不要忘了归一化。如果你直接设置G4ThreeVector(0.0, 0.0, 100.0)虽然概率上能运行但在复杂几何下方向向量不归一会导致几何边界判断异常。Geant4其实会在内部做归一化但第一天就养成“给方向向量设为模长为1”的好习惯后面写GPS多束源时会省很多事。4.4 物理列表与RunAction的配对B1的main函数里用的是QGSP_BERT物理列表它通过组合Quark-Gluon String Precompound模型与Bertini级联模型覆盖了几十MeV到几百GeV的强子输运以及基于标准电磁模型的电子、光子、μ子相互作用。为什么选择题经常用这个而不是纯电磁模型因为即使是100 MeV以下的质子其输运过程中也可能产生次级中子和π介子如果只用纯电磁物理次级粒子无法跟踪模拟结果就缺少完整性。QGSP_BERT在计算速度和物理完备性上平衡得很好是圈内公认的“默认选择”。第一天可以直接用它不要擅自改。RunAction的作用是“运行开始前初始化统计量运行结束后输出结果”。在B1中RunAction里设置了G4int nColl fpDetector-GetNumberOfCollections(); G4double sumE 0; // 遍历每个event中记录的Hit集合累加能量沉积这里涉及Hit与Digit两个概念但第一天不需要彻查。只要知道当粒子穿过灵敏探测器时SensitiveDetector会创建能量沉积HitRunAction在Event结束时汇总所有Hit信息最后打印出“总能量沉积”“平均每个事件沉积”等统计量。如果想修改输出格式或在运行结束时生成直方图改的就是RunAction。5. 可视化与终端运行怎么看懂粒子径迹5.1 交互式UI操作与常用命令编译B1示例时CMakeLists.txt中会根据Geant4是否启用了Qt/OpenGL模块自动决定是否生成带可视化界面的可执行文件。用cmake编译示例cd examples/B1 mkdir build cd build cmake .. make -j4 ./exampleB1运行后会启动Qt图形界面左侧是3D视角右侧是命令控制台。控制台中可以逐条输入Geant4宏命令。最常用的几个/run/initialize /run/printProgress 100 /run/beamOn 1000“/run/initialize”在修改几何或物理列表之后必须重新执行否则改动不会生效。初学者常常改了探测器的某个尺寸然后直接beamOn结果发现结果毫无变化——就是因为没有重新初始化。/run/beamOn 1000代表连续模拟1000个primary粒子。这里要理解“primary粒子”不一定等于“最终粒子”一个高能γ在铅板中产生电子对电子又轫致辐射出光子这串级联反应中产生的所有粒子都归属于同一个Event。Geant4的“事件”概念是以入射粒子为单位的而不是以最终产物为单位的。如果你想看到粒子在几何中“飞”的效果可以执行/vis/open OGL 600x600-00 /vis/viewer/set/autoRefresh true /vis/scene/add/volume /vis/scene/add/trajectories rich /vis/modeling/trajectories/create/drawByCharge轨迹显示开启后鼠标滚轮可以缩放、拖拽旋转视角。我个人第一天的直观感受是当看到10 MeVγ射线在铅板中被散射、吸收、产生次级电子的轨迹全画在眼前时之前所有关于“Track/Step”的抽象疑问瞬间落地了。5.2 .mac宏文件的编写与批量运行在实际科研中你不会每一次都敲命令更多时候是写好一个宏文件之后通过命令行批量执行。比如创建一个run_gamma.mac/run/initialize /process/had/inelastic/verbose 0 /process/em/verbose 0 /gun/particle gamma /gun/energy 10 MeV /gun/direction 0 0 1 /analysis/setFileName gamma_10MeV.root /analysis/h1/set 1 100 0 10 MeV /run/printProgress 10000 /run/beamOn 1000000然后一次性运行./exampleB1 run_gamma.mac这种方式比交互式界面稳定、高效得多尤其是在服务器上跑批量模拟时。传感器、能量点、粒子种类都可以通过宏命令动态改变而不用重新编译。这是Geant4项目从入门走向实际应用必须学会的技能。5.3 输出统计与能量沉积的单位检查第一次跑通B1后终端会输出类似Total energy deposit in detector : 0.452 MeV Number of events generating hits : 187如果你看到探测器能量沉积结果全为0先不要急着怀疑物理模型。绝大多数情况下原因是“灵敏探测器没有正确设置”或者“粒子根本没有到达探测器”。快速分辨的方法是开启轨迹可视化观察粒子是否打到了闪烁体上。如果打到了但沉积为0检查SetSensitiveDetector是否调用成功如果根本没打到检查粒子枪的方向和位置有没有设对。也不能排除单位设置的坑。比如将粒子能量设置成10没有单位在Geant4内部会被当作10 MeV还是10 GeV就无法保证了。这直接决定了粒子输运路径长度、穿过铅板的比例等结果。所以无论何时看到数值异常第一反应都该是“检查单位”这句话在Geant4里值得重复一百遍。6. 第一天常见问题排查与避坑经验6.1 数据文件未加载导致的运行崩溃运行示例时如果出现类似G4Data and/or hadronic data are not available for Z82说明G4NDL等中子截面数据没有正确加载。多数情况下是因为“新开了一个终端但source环境脚本只对当前终端生效”。解决方法是source ~/Geant4/geant4-v11.2.0/bin/geant4.sh或者把环境变量写进~/.bashrc避免每次都要手动执行。如果你确认数据文件存在但Geant4仍找不到可以用系统文件查找命令确认G4NDLDATA路径是否精确指向数据包解压完之后的“G4NDL-4.7”目录而不是多一层或少一层。这种数据路径错误出现得极多因为解压一次.tar.gz通常会生成一个上层文件夹不同包解压行为略有差异最常见的是写了两个嵌套的同名目录。6.2 编译时找不到头文件或动态库装完Geant4后第一时间编译示例时如果出现fatal error: G4RunManager.hh: No such file or directory绝大多数原因是cmake配置时没有正确调用Geant4的CMake模块。示例的CMakeLists.txt里必须包含一行find_package(Geant4 REQUIRED) include(${Geant4_USE_FILE})执行cmake时如果提示找不到Geant4Config.cmake可以手动指定Geant4_DIRcmake -DGeant4_DIR$G4ROOT/lib/cmake/Geant4 ..新版本Geant4安装后这个cmake模块的路径一般是“$G4ROOT/lib/cmake/Geant4”。如果还不确定用find命令搜一下“Geant4Config.cmake”的具体位置把对应的父目录填进去即可。这种问题常见但解决过程非常简单属于一眼能看明白的低级错误。6.3 可视化黑屏或崩溃的处理Qt界面打开后只有几何轮廓、没有粒子径迹或者画面全黑大多数情况是OpenGL驱动或QT兼容问题。在检查代码之前先测试系统本身的OpenGL是否可用glxinfo | grep OpenGL renderer如果没有安装用mesa-utils包补齐sudo apt install mesa-utils如果是远程登录服务器通过SSH转发X11观看可视化OpenGL的支持经常会受限这是远程环境的常见痛点。此时建议改用TurboVNC或直接放弃可视化用文本输出结果。在服务器上跑批量计算时可视化本来就不是必需品很多大型模拟全程在后台无窗口运行。6.4 线程数过高导致的内存溢出Geant4从10.0版本开始默认支持多线程Multithreading每个线程会复制部分全局数据。如果你使用默认线程数运行B1可能会看到G4MT_... Running x24 threads在大数据包的场景下24线程可能占用数十GB内存。在个人笔记本上最好限制线程数./exampleB1 -t 2或者在代码里通过G4MTRunManager设置线程数。我第一天的实训环境就是一台16GB内存的笔记本默认24线程直接OOM内存不足加了-t 2之后顺利跑通。这条经验对大多数用户都适用先单线程或双线程跑通逻辑再上多线程提升效率而不是反过来。7. 第一天的收尾与后续学习路线建议第一天能把环境搭好、B1示例跑通、核心的四层抽象模型在心中成形就已经是很大的进展。如果还有余力我的建议是打开B1的每个源文件从头到尾读一遍代码注释重点看DetectorConstruction和RunAction然后模仿它的结构把几何尺寸改大改小、把铅板换成铁板、把入射粒子改成质子重新编译运行。这一步的意义在于让你从“抄代码”过渡到“理解代码”。我在第一天结束时做了三件事整理出来送给你第一写了一份属于自己的“最小Geant4项目备忘录”内容包括环境变量路径、常用宏命令、几何构建套路、数据包路径。以后无论在什么机器上部署只要照着这份备忘录操作就能快速构建环境。第二在纸上画了一张“Run-Event-Track-Step”关系图和“几何构建四兄弟”流程图把类与类之间的调用关系标注清楚。不要觉得画图幼稚这种抽象模型关系图是你后面理解更复杂物理模拟项目的最有力武器。第三跑通了两个不同能量下的模拟10 MeV和100 MeV的γ并记录下能量沉积的差别。这让我直观理解了“能量越高穿透率越大”这个物理图像和“Geant4模拟结果到底在表达什么”。如果你也想系统学习Geant4我给的第一天建议就一句话别急着追求功能复杂度先把最小示例吃透。然后在B2/B3/B4涉及电磁场、诊疗模拟、探测器响应中逐步扩展自己的认知边界。有任何一步跑不通先检查单位、再检查数据路径、最后检查几何结构——这三板斧能解决90%的初学问题。祝你的Geant4之路顺顺利利。Day01跑通之后你会发现这个工具包一旦上手是真的能让你看到微观世界深处的神奇景象。