探测器构建

G4 探测器构建顺序

几何体 -> 逻辑体 -> 物理体

用户必须继承抽象基类 G4VUserDetectorConstruction 来实现探测器的定义

det1

det2

以下几点要求是多年经验的总结,目的在于提高代码可读性,方便修改。

为了代码的规范及可重复性,我们这里将材料的定义、探测器的定义分离成两个函数。

det3

参数的定义建议放在函数头部部分,方便对数值的修改。

det4

G4LogicalVolume,G4VPhysicalVolume 类对象的声明放在 hh 文件中。

det6

下面是可视化界面的颜色设置示例,只要修改 G4Colour 中 RGB 三原色的比例即可,数值均为 [0.0,1.0]。对哪一个探测器设置颜色就仿照示例进行修改即可。

det5

材料定义

参考 https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/material.html

在自然界中,一般材料(化合物、混合物)由元素构成,元素由同位素构成。因此,这是 Geant4 中设计的三个主要类(G4Isotope/G4Element/G4Material)。每个类都有一个表作为静态数据成员,用于跟踪各个类创建的实例。所有三个对象在构造时都会自动注册到相应的表中,并且永远不应该在用户代码中删除它们。

G4Isotope/G4Element/G4Material 这三个类 new 的对象,不需要 delete

G4Materrial 材料只要一定义,就放置在一个全局的容器内,随时可以拿来使用。

构造元素

//定义元素,方法一
G4Element *H = new G4Element("Hydrogen", "H" , 1., 1.01*g/mole);
//定义元素,方法二
G4NistManager *man = G4NistManager::Instance();
G4Element *N = man->FindOrBuildElement("N");//采用天然丰度
G4Element *O = man->FindOrBuildElement("O");

构造材料

单质

G4Material* lAr = new G4Material("liquidArgon", 18., 39.95*g/mole, 1.390*g/cm3);

分子/混合物

G4Material *pVacuum = new G4Material("Vacuum", 1.29e-10*mg/cm3, 2, kStateGas,
                                              0.1*kelvin, 1.e-19*pascal);

pVacuum->AddElement(N, 7);//注意这里是整型
pVacuum->AddElement(O, 3);//表示原子个数比

//或者

pVacuum->AddElement(N, 70.*perCent);//注意这里是浮点型
pVacuum->AddElement(O, 30.*perCent);//表示质量占比

//原子个数比还是质量比,设置方式需要非常小心!
// define a material from elements and/or others materials (mixture of mixtures)
density = 0.200*g/cm3;
G4Material* Aerog = new G4Material(name = "Aerogel", density, ncomponents = 3);
Aerog->AddMaterial(SiO2, fractionmass = 62.5*perCent);
Aerog->AddMaterial(H2O , fractionmass = 37.4*perCent);
Aerog->AddElement (elC , fractionmass = 0.1*perCent);
// examples of gas in non STP conditions
density     = 27.*mg/cm3;
pressure    = 50.*atmosphere;
temperature = 325.*kelvin;
G4Material* CO2 = new G4Material(name = "Carbonic gas", density, ncomponents = 2,
                                     kStateGas, temperature, pressure);
CO2->AddElement(elC, natoms=1);
CO2->AddElement(elO, natoms=2);

对于常见的材料,G4已经封装好,直接调用即可

更多材料信息可访问 https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Appendix/materialNames.html#g4matrdb

G4NistManager* man = G4NistManager::Instance();
G4Material * pAir = man->FindOrBuildMaterial("G4_AIR");
G4Material *pSi = man->FindOrBuildMaterial("G4_Si");

参考代码

void wuDetectorConstruction::DefineMaterials()
{ 
  //在这里先定义所有可能用到的材料
  // Get nist material manager
  G4NistManager* nist = G4NistManager::Instance();

  //注册G4自身定义好的材料
  nist->FindOrBuildMaterial("G4_Galactic");//真空
  nist->FindOrBuildMaterial("G4_Ge");//
  nist->FindOrBuildMaterial("G4_Pu");
  nist->FindOrBuildMaterial("G4_H");
  nist->FindOrBuildMaterial("G4_Al");
  nist->FindOrBuildMaterial("G4_lH2");//
  nist->FindOrBuildMaterial("G4_lN2");//
  nist->FindOrBuildMaterial("G4_lO2");//
  nist->FindOrBuildMaterial("G4_lAr");//Liquid argon
  nist->FindOrBuildMaterial("G4_Be");
  nist->FindOrBuildMaterial("G4_WATER");
  nist->FindOrBuildMaterial("G4_WATER_VAPOR");//水蒸气
  nist->FindOrBuildMaterial("G4_POLYETHYLENE");//聚乙烯
  nist->FindOrBuildMaterial("G4_BGO");//
  nist->FindOrBuildMaterial("G4_CARBON_DIOXIDE");//二氧化碳
  nist->FindOrBuildMaterial("G4_LEAD_OXIDE");//氧化铅
  nist->FindOrBuildMaterial("G4_MYLAR");//mylar膜
  nist->FindOrBuildMaterial("G4_PLEXIGLASS");//有机玻璃
  nist->FindOrBuildMaterial("G4_STAINLESS-STEEL");//不锈钢
  nist->FindOrBuildMaterial("G4_LUCITE");//透明合成树脂(有机玻璃)
  nist->FindOrBuildMaterial("G4_CONCRETE");//混凝土
  nist->FindOrBuildMaterial("G4_GRAPHITE");//石墨
  nist->FindOrBuildMaterial("G4_SILICON_DIOXIDE");//二氧化硅
  nist->FindOrBuildMaterial("G4_RUBBER_NATURAL");//天然橡胶
  nist->FindOrBuildMaterial("G4_PbWO4");//
  nist->FindOrBuildMaterial("G4_URANIUM_OXIDE");//氧化铀 
  nist->FindOrBuildMaterial("G4_URANIUM_MONOCARBIDE");//碳化铀
  nist->FindOrBuildMaterial("G4_URANIUM_DICARBIDE");//二碳化铀
  // 更多预定义材料请看说明书 https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Appendix/materialNames.html#g4matrdb


  // 注册G4自身定义好的 elements,采用天然丰度
  G4Element* H = nist->FindOrBuildElement("H",false);//1
  G4Element* Li = nist->FindOrBuildElement("Li",false);//3
  G4Element* C = nist->FindOrBuildElement("C",false);//6
  G4Element* N = nist->FindOrBuildElement("N",false);//7
  G4Element* O = nist->FindOrBuildElement("O",false);//8
  G4Element* Mg = nist->FindOrBuildElement("Mg",false);//12
  G4Element* Al = nist->FindOrBuildElement("Al",false);//13
  G4Element* Si = nist->FindOrBuildElement("Si",false);//14
  G4Element* P = nist->FindOrBuildElement("P",false);//15
  G4Element* S =  nist->FindOrBuildElement("S",false);//16
  G4Element* Cr = nist->FindOrBuildElement("Cr",false);//24
  G4Element* Mn = nist->FindOrBuildElement("Mn",false);//25
  G4Element* Fe = nist->FindOrBuildElement("Fe",false);//26
  G4Element* Ni = nist->FindOrBuildElement("Ni",false);//28
  G4Element* I = nist->FindOrBuildElement("I",false);//53
  G4Element* Cs = nist->FindOrBuildElement("Cs",false);//55
  G4Element* Ce = nist->FindOrBuildElement("Ce",false);//58

  // 同位素构建元素,用来调整材料丰度
  G4Isotope* U4 = new G4Isotope("U234",92,234,234.02*g/mole);
  G4Isotope* U5 = new G4Isotope("U235",92,235,235.01*g/mole);
  G4Isotope* U6 = new G4Isotope("U236",92,236,236.04*g/mole);
  G4Isotope* U8 = new G4Isotope("U238",92,238,238.03*g/mole);
  G4Element* HEU58 = new G4Element("Highly-enriched Uranium 58", "HEU58", 2);
  HEU58->AddIsotope(U5, 0.93);
  HEU58->AddIsotope(U8, 0.07);

  G4Element* HEU4568 = new G4Element("Highly-enriched Uranium 4568","HEU4568",4);
  HEU4568->AddIsotope(U4,0.0097);
  HEU4568->AddIsotope(U5,0.9315);
  HEU4568->AddIsotope(U6,0.0024);
  HEU4568->AddIsotope(U8,0.0564);

  //---------------------------------------------------------------------------------

  // Scintillator(BC408) 塑闪 
  G4Material* BC408 = new G4Material("BC408", 1.032*g/cm3, 2);
  BC408->AddElement(H, 11);BC408->AddElement(C, 10);
  // BC408->AddElement(H, 10);BC408->AddElement(C, 9);

  // LiquidScint(NE213) 液闪 
  G4Material* NE213 = new G4Material("NE213",0.874*g/cm3,2);
  NE213->AddElement(H,1212);
  NE213->AddElement(C,1000);

  // He-3 detector materials
  G4Material* matHe3  = new G4Material("He3",  2., 3.*g/mole, 0.00049*g/cm3, kStateGas);

  // Uranium material
  G4Material* matHEU58 = new G4Material("HEU58", 19.1*g/cm3, 1, kStateSolid);
  matHEU58->AddElement(HEU58, 1.00);

  G4Material* matHEU4568 = new G4Material("HEU4568",18.75*g/cm3,1);
  matHEU4568->AddElement(HEU4568, 1.0);


  G4Material* matSteel = new G4Material("Steel",7.788*g/cm3,9);
  matSteel->AddElement(Fe,62.1805*perCent);
  matSteel->AddElement(Cr,20.26*perCent);
  matSteel->AddElement(Mn,9.37*perCent);
  matSteel->AddElement(Ni,7.5*perCent);
  matSteel->AddElement(Si,0.34*perCent);
  matSteel->AddElement(N,0.29*perCent);
  matSteel->AddElement(C,0.04*perCent);
  matSteel->AddElement(P,0.018*perCent);
  matSteel->AddElement(S,0.0015*perCent);


  // Print materials,运行时在终端输出材料信息
  G4cout << *(G4Material::GetMaterialTable()) << G4endl;
}

构造几何体

参考 https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/Geometry/geomSolids.html

几何体的名字虽然允许出现相同的情况,但是不建议使用相同的名字。

查阅说明书,基本几何形状可直接创建,需要特别注意的地方:长度是全长还是半长表示。使用哪个几何体,则在 wuDetectorConstruction.cc 文件中添加相应的头文件。

以下是最常用的几何,长方体、柱状/管状、球/球壳等。

det7

G4Box *pSolidWorld= new G4Box("solidWorld",0.5*10*cm,0.5*10*cm,0.5*10*cm);

det8

det9

布尔运算生成几何体

简单几何体可以在说明书中直接找到它的使用方法。很多时候探测器的形状不在基本的几何体库中,这种情况就需要使用者通过布尔运算来构建所需要的几何体了。G4几何体构建中支持的布尔运算有:union, intersection, subtraction。参与运算中的第二个几何体可以进行平移、旋转等操作。

G4Box*  box =
  new G4Box("Box", 20*mm, 30*mm, 40*mm);
G4Tubs* cyl =
  new G4Tubs("Cylinder", 0, 50*mm, 50*mm, 0, twopi);  // r:     0 mm -> 50 mm
                                                 // z:   -50 mm -> 50 mm
                                                 // phi:   0 ->  2 pi
G4UnionSolid* union =
  new G4UnionSolid("Box+Cylinder", box, cyl);
G4IntersectionSolid* intersection =
  new G4IntersectionSolid("Box*Cylinder", box, cyl);
G4SubtractionSolid* subtraction =
  new G4SubtractionSolid("Box-Cylinder", box, cyl);

G4RotationMatrix* yRot = new G4RotationMatrix;  // Rotates X and Z axes only
yRot->rotateY(M_PI/4.*rad);                     // Rotates 45 degrees
G4ThreeVector zTrans(0, 0, 50);

G4UnionSolid* unionMoved =
  new G4UnionSolid("Box+CylinderMoved", box, cyl, yRot, zTrans);

G4RotationMatrix invRot = yRot->invert();
G4Transform3D transform(invRot, zTrans);
G4UnionSolid* unionMoved =
  new G4UnionSolid("Box+CylinderMoved", box, cyl, transform);

以上两种方法基本能满足大部分的探测器构建需要,特别大规模或者形状复杂的还可以通过三维软件构造,然后 STL 格式图纸导入的方式。

构造逻辑体

参考 https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/Geometry/geomLogical.html

G4LogicalVolume (
                  G4VSolid *pSolid, 
                  G4Material *pMaterial, 
                  const G4String &name, 
                  G4FieldManager *pFieldMgr=0, 
                  G4VSensitiveDetector *pSDetector=0, 
                  G4UserLimits *pULimits=0,
                  G4bool optimise=true)
// 参数:几何体,材料,逻辑体名字, 电磁场,灵敏探测器,截断,优化
// 其中 几何体,材料,逻辑体名字 三个必须指定

det10

这里要求每个逻辑体的名字必须唯一,这样方便后期的数据处理。

构造物理体

参考 https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/Geometry/geomPhysical.html

G4PVPlacement (
               G4RotationMatrix *pRot,
               const G4ThreeVector &tlate,
               G4LogicalVolume *pCurrentLogical,
               const G4String &pName, 
               G4LogicalVolume *pMotherLogical,
               G4bool pMany, 
               G4int pCopyNo, 
               G4bool pSurfChk=false)
// 参数:旋转,平移,逻辑体,本物理体名字,母体,(无用参数),拷贝号,重叠检查

det11

多个物理体可以共用同一个逻辑体,然后通过不同的拷贝号来区分。这在同一个型号的探测器有几千上万的情况下显得特别必要(因为重复 new 那么多对象需要占用非常大的内存,而且初始化它们所需要的时间也很长,而它们仅仅名字不一样)。但是对于我们一般的模拟来说,创建的逻辑体不会太多,为了方便后期的数据处理,建议每个探测器创建各自的逻辑体和物理体,且逻辑体和对应的物理体用相同的名字。

物理体之间的层级结构

det12

问题:如何将物理体A放入物理体B的内部?

物理体A与物理体B的重叠部分:?

Geant4:嵌套模型(盒子模型)

G4中,所有的物理体必须被指定母体。对于最外层的物理体,其母体为空,此物理体称为“World”。

思考

对于一个正面 48 条,条宽 1mm,条缝隙 0.1mm;背面 128 条,条宽 1mm,条缝隙 0.1mm 的双面硅微条。安装在束流方向 45度,探测器中心距离靶点 15 cm 的位置。

为了模拟粒子最终沉积在哪一个像素,因此在几何构造的时候,需要构造 48x128 个像素。如何构造?

阵列创建示例