ROOT

GEANT4 与 ROOT 一些版本存在冲突,通常是 ROOT 发布完于 GEANT4 的版本可以耦合运行。

按照我们的测试,GEANT4.10.07 及以下版本 与 ROOT6.24.02及以上能够通过编译。 GEANT4.11 与 ROOT6.26.16 及以上版本能够编译通过。入股

GEANT4 模拟使用的输入量有时是实验测量的信息,例如能谱、位置分布等。而这些信息通常以 TH1/TH2 等 ROOT 的形式保存。

GEANT4 耦合 ROOT 程序进行模拟在很多情况下是必要的,这里我们简单介绍如何调用 ROOT。

注意:当前 GEANT4 多线程模式下采用 ROOT TFile/TTree 方式保存数据存在问题。单线程下没问题。

修改 CMakeLists.txt 文件

G4 中调用 ROOT 库,首先需要修改 CMakeLists.txt 文件,

CMakeLists.txt

## 添加以下代码
## 在 include_directories 之前

find_package(ROOT REQUIRED)
if(ROOT_FOUND)
  # message("ROOT find...")
  include(${ROOT_DIR}/ROOTUseFile.cmake)
  message(${ROOT_INCLUDE_DIRS})
  message(${ROOT_LIBRARIES})
endif()


## 修改以下两行如下:

# 添加 ${ROOT_INCLUDE_DIRS}
include_directories(${PROJECT_SOURCE_DIR}/include ${Geant4_INCLUDE_DIR} ${ROOT_INCLUDE_DIRS})
# 添加 ${ROOT_LIBRARIES}
target_link_libraries(${PROJ_NAME} ${Geant4_LIBRARIES} ${ROOT_LIBRARIES})

cmake

执行 cmake 指令之后,可以看到 ROOT 头文件以及动态连接库。 显示的动态链接库是变量 ${ROOT_LIBRARIES} 中默认的,额外的可通过以下方式进行添加

## 添加 MathMore
target_link_libraries(${PROJ_NAME} ${Geant4_LIBRARIES} ${ROOT_LIBRARIES} MathMore)

完成以上配置,基本上与前面课程中介绍的 ROOT 使用没有区别。

示例代码

作业 5.0 部分提供的代码生成 TH1/TH2 分布。这里展示如何使用该分布进行抽样

main.cc

//
#include "TROOT.h"

// main 中添加以下代码
ROOT::EnableThreadSafety(); // 这一行非常重要,少了程序就崩溃

// 太老版本的 ROOT 可能没有该函数,可通过使用单线程模式来规避线程安全问题

wuPrimaryGeneratorActionAll.hh

// 添加头文件
#include "TFile.h"
#include "TH1.h"
#include "TH2.h"


// wuPrimaryGeneratorActionAll 类中添加三个变量
  TFile *filer;
  TH1I *h1;
  TH2I *h2;

wuPrimaryGeneratorActionAll.cc

wuPrimaryGeneratorActionAll::wuPrimaryGeneratorActionAll()
  : G4VUserPrimaryGeneratorAction(),particleGun(NULL)
{
  // 这里省略    

  // 打开文件,读取 TH1/TH2   
  filer = new TFile("dis.root","READ");
  if(!filer->IsOpen())
    {
      std::cout<<"Can't open root file"<<std::endl;
    }
  h1 = (TH1I*)filer->Get("h1");
  h2 = (TH2I*)filer->Get("h2");

}    


wuPrimaryGeneratorActionAll::~wuPrimaryGeneratorActionAll()
{
  // 这里省略    

  // 关闭文件
  filer->Close();
}



void wuPrimaryGeneratorActionAll::GeneratePrimaries(G4Event* anEvent)
{
  // 这里省略    

  // 抽取数据  
  double depz = h1->GetRandom();
  double depx, depy;
  h2->GetRandom2(depx, depy);   
  G4cout<<depx<<" "<<depy<<" "<<depz<<G4endl;        

  // 这里省略        
}