GATE是国际OpenGATE协作开发的高级开源软件,致力于医学成像和放射治疗的数值模拟。支持PET、SPECT、CT、光学成像(荧光成像和生物发光)以及放射治疗。
gate不使用c++语言,用户可以交互输入宏命令进行操作,或者写一个宏文件(扩展名.mac ,一堆宏命令)来控制,宏命令按照树形结构进行组织。例如,所有的几何控制命令都以几何开头,它们都可以在树结构的几何分支下找到。比如geometry控制命令可以在geometry下找到。
每次图像应用仿真用户都要:①定义扫描仪几何 ②定义模体几何 ③设置物理过程 ④初始化仿真
/gate/run/initialize
⑤设置探测器模型 ⑥定义源 ⑦指定数据输出格式 ⑧开始数据采集
注:步骤①到④涉及模拟的初始化,初始化之后,几何结构就不能再被更改了。
用户文档中还介绍了剂量学和放射治疗应用的仿真架构,先不介绍。
宏文件是 ASCII 文件(带有“.mac”扩展名),其中每一行都包含一个命令或注释( 命令是 Geant4或Gate的脚本命令,注释以字符“#”开头)。 一个宏或一组宏必须包括以正确的顺序模拟不同组件的所有命令, 这些组件往往包括可视化脚本、体积(几何)定义脚本、系统、扫描仪仪脚本、物理过程脚本、初始化、源定义脚本、输出和采集。一个模拟可以被分成几个宏,通常,有一个主宏调用更具体的宏。
用Linux 提示符执行宏(本例中为 benchPET.mac),需键入:
Gate benchPET.mac
要在Gate 环境中执行宏(在“Idle>”提示符后键入)或者要在主宏内部执行宏,需键入:
/control/execute benchPET.mac
(1)指定材料库文件Materials.db的位置
用户需要定义模拟对象(volume,不知道这么理解对不对,用户说明中给所有的物体都叫volume)的几何形状。所有对象(volume)都按照树状结构链接在一起,每个分支代表了一个对象(volume)。每个对象(volume)都由形状、大小、位置和材料组成。分配给新对象的默认材料是空气, 可用材料在 Gate的Materials.db 文件中定义,需要使用以下命令指定材料数据库的位置:
/gate/geometry/setMaterialDatabase MyMaterialDatabase.db
#最后面的MyMaterialDatabase.db是电脑中的MaterialDatabase.db材料定义文件的位置,比如:
/gate/geometry/setMaterialDatabase ../../GateMaterials.db
#../../GateMaterials.db的意思是当前脚本所在位置的上级目录的上级目录
(2)设置世界volume和系统全局子volume(柱状环)
图 1 world volume
树结构的根部是世界volume(图 1),它设置了模拟的实验框架。 在 Defining a geometry 章节中详细介绍了与几何构建相关的所有gate命令。 世界volume是一个以原点为中心的盒子,它必须足够大以包含整个模拟体积。 任何粒子从世界volume中逸出时都会停止被跟踪,此处给出的示例模拟了一个适合 40 x 40 x 40 cm3 立方体空间大小的系统。 因此,世界volume可以定义如下:
# W O R L D
/gate/world/geometry/setXLength 40. cm
/gate/world/geometry/setYLength 40. cm
/gate/world/geometry/setZLength 40. cm
世界volume中包含了一个或多个子volume,称为 daughter volumes :
/gate/world/daughters/name vol_name
#vol_name是子volume的名称
世界第一个子volume的名字vol_name有特定的含义和名称,它指定了要模拟的扫描仪的类型。 Defining a system 章节中会给出每种类型的扫描仪(也称为系统,PET,SPECT,CT等等这些)的详细信息。在当前示例中,系统是柱形PET系统,该系统假设扫描仪是基于矩形模块的圆柱形配置(图 2),每个模块包含一组晶体:
# S Y S T E M
/gate/world/daughters/name cylindricalPET #设置子volume的名字
/gate/world/daughters/insert cylinder #设置子volume形状
/gate/cylindricalPET/setMaterial Water #设置材料,但是设置成水是什么鬼
/gate/cylindricalPET/geometry/setRmax 100 mm #外径
/gate/cylindricalPET/geometry/setRmin 86 mm #内径
/gate/cylindricalPET/geometry/setHeight 18 mm #高
/gate/cylindricalPET/vis/forceWireframe #可视化为线框
/vis/viewer/zoom 3 #缩放因子,允许用户缩放几何图形
#以上命令是设置扫描仪的形状为一个外径100mm,内径86mm,长度18mm的装满水的圆柱体。然后将其可视化设置为线框。
图2 cylindricalPET系统
(3)设置柱状环内部结构:矩阵模块和晶体探测器
我们假设扫描仪由30个矩形模块(box1)组成,每个块包含8*8个LSO晶体(box2)。下面的命令行描述了这个扫描仪(请参阅 Defining a geometry 以找到这些命令的详细解释)。首先,每个矩形模块需要定义为系统(圆柱PET系统)的子volume:
# FIRST LEVEL OF THE SYSTEM
/gate/cylindricalPET/daughters/name box1 #设置矩形模块的名字为box1
/gate/cylindricalPET/daughters/insert box #设置box1的形状为矩形
/gate/box1/placement/setTranslation 91. 0 0 mm #位置???
/gate/box1/geometry/setXLength 10. mm #设置box1的X方向长度为10mm
/gate/box1/geometry/setYLength 17.75 mm #设置box1的Y方向长度为17.75mm
/gate/box1/geometry/setZLength 17.75 mm #设置box1的Z方向长度为17.75mm
/gate/box1/setMaterial Water #设置box1材料是水
/gate/box1/vis/setColor yellow #可视化颜色设置为黄色
/gate/box1/vis/forceWireframe #设置使用框线
图 3 矩形模块box1 图 4 探测器晶体结构box2
创建矩形模块后(图 3),8*8的晶体结构可以定义为矩形模块box1的子volume(图 4)
# C R Y S T A L
/gate/box1/daughters/name box2
/gate/box1/daughters/insert box
/gate/box2/geometry/setXLength 10. mm
/gate/box2/geometry/setYLength 2. mm
/gate/box2/geometry/setZLength 2. mm
/gate/box2/setMaterial LSO
/gate/box2/vis/setColor red
/gate/box2/vis/forceWireframe
# Z O O M
/vis/viewer/zoom 4
/vis/viewer/panTo 60 -40 mm #将查看器窗口平移水平右移60mm,垂直下移40mm,(默认为世界原点 (0,0,0))
# R E P E A T C R Y S T A L
/gate/box2/repeaters/insert cubicArray
/gate/box2/cubicArray/setRepeatNumberX 1
/gate/box2/cubicArray/setRepeatNumberY 8
/gate/box2/cubicArray/setRepeatNumberZ 8
/gate/box2/cubicArray/setRepeatVector 0. 2.25 2.25 mm #????
为了获得完整的晶体矩阵,需要在 Y 和 Z 方向上重复box2(图 5)。为了获得完整的环形检测器,原始块重复 30 次(图 6):
图 5 box2重复8*8次形成矩阵晶体 图 6 box1重复30次形成探测器环
(4)将对象链接到系统
现在已经指定了一个简单的 PET 扫描仪的几何形状。下一步是将这个几何体连接到系统,以便在代表探测器(敏感检测器)的对象体积内存储来自粒子相互作用的数据。 Gate 只存储连接到敏感检测器的那些volume的相互作用,而发生在非敏感volume中的相互作用将丢失。volume也必须属于系统,才能连接到敏感检测器。系统和敏感检测器的概念分别在 Defining a system 和 Attaching the sensitive detectors 中详细讨论。
以下命令用于将volume连接到系统:
# R E P E A T R S E C T O R
/gate/box1/repeaters/insert ring
/gate/box1/ring/setRepeatNumber 30
# Z O O M
/vis/viewer/zoom 0.25
/vis/viewer/panTo 0 0 mm
# A T T A C H V O L U M E S T O A S Y S T E M
/gate/systems/cylindricalPET/rsector/attach box1
/gate/systems/cylindricalPET/module/attach box2
rsector 和module是专用名称,对应于 CylindricalPET 系统的第一层和第二层(参见 Defining a system)。
为了在与晶体对应的体积中保存相互作用(参见数字化仪和读出参数),在本例中,适当的命令是:
# D E F I N E A S E N S I T I V E D E T E C T O R
/gate/box2/attachCrystalSD vglue 1cm #还不清楚什么意思
在宏文件中,用户可以实现探测器移动。 Gate 最显着的特点之一是对时间相关现象的管理,例如探测器移动和源衰减,从而对采集过程进行连贯的描述。 为简单起见,本教程中描述的模拟没有考虑探测器或体模的运动。 Defining a geometry 详细描述了物体的运动。
被扫描对象volume是使用与构建扫描仪相同的原理构建的。以下命令行描述了一个半径为 10 mm、长度为 30 mm的圆柱体。 圆柱体充满水,显示为灰色。
# P H A N T O M
/gate/world/daughters/name my_phantom
/gate/world/daughters/insert cylinder
/gate/my_phantom/setMaterial Water
/gate/my_phantom/vis/setColor grey
/gate/my_phantom/geometry/setRmax 10. mm
/gate/my_phantom/geometry/setHeight 30. mm
图 7 柱状模体
要检索有关体模内康普顿和瑞利相互作用的信息,使用以下命令行将敏感检测器 (phantomSD) 与volume相关联:
# P H A N T O M D E F I N E D A S S E N S I T I V E
/gate/my_phantom/attachPhantomSD
现在将为相互作用集合中的每个相互作用 ,记录两种类型的信息:
· 在连接到 phantomSD探测器上的所有物理volume中,产生的散射相互作用的数量。
· 连接在探测器上,最近一次发生相互作用的物理volume的名称。
这些概念在 Attaching the sensitive detectors中进一步讨论。
一旦描述了volume和相应的敏感探测器,就必须指定模拟中感兴趣的相互作用过程,Gate 使用 Geant4 中的物理过程。 用户必须为每个粒子选择相应的物理过程,然后,用户可以通过设置生产阈值、切割、电磁选项来自定义模拟……
目录 examples/PhysicsLists 中提供了一些典型物理过程的列表:
egammaStandardPhys.mac (光子,e- 和 e+ 的物理列表,采用标准过程和推荐的 Geant4 “option3”)
egammaLowEPhys.mac(光子、e- 和 e+ 低能量过程的物理列表)
egammaStandardPhysWithSplitting.mac(具有选择性轫致辐射分裂的替代 egammaStandardPhys.mac)
hadrontherapyStandardPhys.mac(具有标准流程和推荐的Geant4“option3”的强子治疗的物理列表)
hadrontherapyLowEPhys.mac(低能量过程强子治疗的物理列表)
Gate中的相互作用过程、切割和选项的细节在Setting up the physics 中进行了描述。
当前面的3个步骤完成后,对应Geant4的预初始化模式,应使用:
# I N I T I A L I Z E
/gate/run/initialize
这里的初始化实际上触发了横截面表的计算, 在这一步之后,不能再修改物理列表,也不能在几何体中插入新的volume。
Gate 的基本输出是一个命中集合(即相互作用集合),其中存储了每次相互作用的位置、时间和能量等数据。因此,通过沿其轨迹产生的所有相互作用记录了粒子的历史。 数字化仪的目标是根据相互作用建立物理可观察量,并对读出方案和触发逻辑进行建模。 Gate digitizer 对象下有几个功能,它由不同的模块组成,这些模块可以插入到线性信号处理序列中。 例如,以下命令行插入一个加法器,以求和每个基本体积(在我们的示例中定义为 box2 的单晶)生成的命中数:
/gate/digitizer/Singles/insert adder
另一个模块可以描述仿真的读出方案。除了用一个光电探测器读出一个晶体外,读出的分割可能与探测器的基本几何结构不同。读出几何是一种人工几何,通常与一组灵敏的探测器相关联。在本例中,这个组是box1:
/gate/digitizer/Singles/insert readout
/gate/digitizer/Singles/readout/setDepth 1
在这个例子中,读出模块将块内所有晶体中沉积的能量相加,并确定具有最高能量沉积的晶体的位置。 setDepth 命令指定在哪个几何级别(称为“深度”)执行读出功能。 在当前示例中:
基础水平(CylindricalPET)=depth 0
系统的第一个子volume (box1) = depth 1
系统的下一个子volume (box2) = depth 2
等等 …
为了考虑探测器的能量分辨率并仅在预定义的能量窗口内收集信号,可以使用其他模块:
# E N E R G Y B L U R R I N G
/gate/digitizer/Singles/insert blurring
/gate/digitizer/Singles/blurring/setResolution 0.19
/gate/digitizer/Singles/blurring/setEnergyOfReference 511. keV
# E N E R G Y W I N D O W
/gate/digitizer/Singles/insert thresholder
/gate/digitizer/Singles/thresholder/setThreshold 350. keV
/gate/digitizer/Singles/insert upholder
/gate/digitizer/Singles/upholder/setUphold 650. keV
这里,考虑了 551 KeV 下 19% 的能量分辨率,此外,能量窗口设置为 350 keV 至 600 keV。对于 PET 模拟,符合分辨器也在数字化仪级别实施:
# C O I N C I D E N C E S O R T E R
/gate/digitizer/Coincidences/setWindow 10. ns
Gate 中提供了其他数字化仪模块,并在 Digitizer and readout parameters中进行了描述。
在Gate中,源由发射粒子(正电子、伽马、离子、质子等)的volume表示。 用户可以定义源的几何形状及其特性,例如发射方向、能量分布和活动。 不稳定源(放射性离子)的寿命通常从 Geant4 数据库中获得,但也可以由用户设置。
体素化体模或患者数据集也可用于定义源(PET和SPECT中),以模拟真实的采集。 有关定义源的所有函数的完整说明,请参阅 Voxelized source and phantom。
在当前示例中,源是 1 MBq 线源,定义为半径为 0.5 mm、长度为 50 mm 的圆柱体。 源生成“背对背”发射的 511 keV 伽马粒子对(对于更真实的源的模型,还可以考虑正电子的范围和两个伽马的非共线性):
# S O U R C E
/gate/source/addSource twogamma #添加一个源
/gate/source/twogamma/setActivity 1000000. becquerel #源的活性
/gate/source/twogamma/setType backtoback #源产生的粒子类型
# POSITION
/gate/source/twogamma/gps/centre 0. 0. 0. cm #源的中心位置
# PARTICLE
/gate/source/twogamma/gps/particle gamma #源发射的粒子类型
/gate/source/twogamma/gps/energytype Mono
/gate/source/twogamma/gps/monoenergy 0.511 MeV
# TYPE = Volume or Surface
/gate/source/twogamma/gps/type Volume #
# SHAPE = Sphere or Cylinder
/gate/source/twogamma/gps/shape Cylinder #源的形状
/gate/source/twogamma/gps/radius 0.5 mm #源半径
/gate/source/twogamma/gps/halfz 25 mm #源半高
# SET THE ANGULAR DISTRIBUTION OF EMISSION
/gate/source/twogamma/gps/angtype iso
# SET MIN AND MAX EMISSION ANGLES
/gate/source/twogamma/gps/mintheta 0. deg
/gate/source/twogamma/gps/maxtheta 180. deg
/gate/source/twogamma/gps/minphi 0. deg
/gate/source/twogamma/gps/maxphi 360. deg
/gate/source/list
默认情况下,Gate所使用的所有系统的数据输出格式为ASCII和ROOT,如下命令行所述:
# ASCII OUTPUT FORMAT
/gate/output/ascii/enable
/gate/output/ascii/setFileName test
/gate/output/ascii/setOutFileHitsFlag 0
/gate/output/ascii/setOutFileSinglesFlag 1
/gate/output/ascii/setOutFileCoincidencesFlag 1
# ROOT OUTPUT FORMAT
/gate/output/root/enable
/gate/output/root/setFileName test
/gate/output/root/setRootSinglesFlag 1
/gate/output/root/setRootCoincidencesFlag 1
给定这个脚本,将创建几个ASCII文件(.dat扩展名)和一个根文件(test.root)。 Data output 解释了如何读取结果文件。
Data output 中给出了所有可用输出的完整描述。
在最后一步中,定义了采集。 采集的开始和结束被定义为现实中的一次实验。 此外,Gate 需要一个时间片参数,该参数假定模拟系统在一个时间段内为静态。在每个时间片的开始,根据请求更新几何图,在每个时间片中,几何体保持静态,粒子传输和数据采集的模拟继续进行。 每个切片对应一个 Geant4 运行。
如果模拟中涉及的源没有放射性,或者活性没有定义,用户可以修改事件的总数。在这种情况下,粒子的数量在每个切片的时间函数间被分割:
/gate/application/setTotalNumberOfPrimaries [N]
用户还可以确定每个切片相同数量的事件。 在这种情况下,每个事件由时间片与总模拟时间之间的比率加权:
/gate/application/setNumberOfPrimariesPerRun [N]
为每次运行设置不同数量的初级粒子也很有用。 这可以使用包含初级粒子数量的文件和命令来完成:
/gate/application/readNumberOfPrimariesInAFile [path/to/filename]