TrackingAction

1234

StackingAction 中介绍了如何判选一个粒子是否进行模拟。而 G4UserTrackingAction 则对每个粒子模拟的开始和结束提供用户操纵接口。PreUserTrackingAction() 在一个 Tarck 开始时被调用, PostUserTrackingAction() 在一个 Track 结束之后被调用。

GEANT4 的机制中,一个 tracking 中的多个 step 中均可能产生新的粒子,只有在当前粒子(track)完成模拟,才会进行下一个粒子的模拟。

class G4UserTrackingAction
{
   public:

     // Constructor & Destructor
     G4UserTrackingAction(){};
     virtual ~G4UserTrackingAction(){}

     // Member functions
     virtual void PreUserTrackingAction(const G4Track*){}
     virtual void PostUserTrackingAction(const G4Track*){}

   protected:

     G4TrackingManager* fpTrackingManager;
};

RunAction 中函数 BeginOfRunAction()/EndOfRunAction() 类似,PreUserTrackingAction()/PostUserTrackingAction() 可以用来提取数据。下面介绍通过这两个函数进行遗传信息的标记。

TrackInformation 标记示例

wuTrackingActionAll.cc

// 添加头文件
#include "wuTrackInformation.hh"
void wuTrackingAction::PreUserTrackingAction(const G4Track* aTrack)
{

  wuTrackInformation* trackInformation;
  if(!aTrack->GetUserInformation()) 
    {
      trackInformation = new wuTrackInformation();
      fpTrackingManager->SetUserTrackInformation(trackInformation);
    }
  else
    {
      trackInformation = (wuTrackInformation*)(aTrack->GetUserInformation());
    }

  if (aTrack->GetParentID()==0)//入射粒子 
    {
      trackInformation->AddFlag(0);//初始中子为第0代
      fpTrackingManager->SetUserTrackInformation(trackInformation);
    } 
  else {

    //fpTrackingManager->SetUserTrackInformation(trackInformation);
  }

}

// 标记第几代裂变中子
// 其它粒子虽然也被标记了,但是对最终的数据分析没有影响

void wuTrackingAction::PostUserTrackingAction(const G4Track* aTrack)
{

  G4TrackVector* secondaries = fpTrackingManager->GimmeSecondaries();
  if(secondaries)//如果当前 tracking 中产生了次级粒子
    {
      wuTrackInformation* info = (wuTrackInformation*)(aTrack->GetUserInformation());//当前 track 的信息

      size_t nSeco = secondaries->size();
      if(nSeco>0)//对次级粒子进行遍历
      {
      for(size_t i=0;i<nSeco;i++)
        { 
          wuTrackInformation* infoNew = new wuTrackInformation(info);
          if((*secondaries)[i]->GetCreatorProcess()->GetProcessName()=="nFission")
             infoNew->AddFlag(infoNew->PrintFlag()+1);//fission产生的中子才加一,非弹散的中子虽然ID也变了,但是并不是新的中子

          //G4cout<<infoNew->PrintFlag()<<G4endl;
          // G4cout<<"###  "<<(*secondaries)[i]->GetCreatorProcess()->GetProcessName()<<"  "<<(*secondaries)[i]->GetParticleDefinition()->GetParticleName()<<G4endl;

          (*secondaries)[i]->SetUserInformation(infoNew);
        }
      }
    }

}

数据提取示例

wuStackingActionAll.cc

// 根据遗传标记进行判选
// 不模拟三代以上的中子

// 添加头文件
#include "wuTrackInformation.hh"

G4ClassificationOfNewTrack wuStackingActionAll::ClassifyNewTrack(const G4Track* aTrack)
{
  if(aTrack->GetUserInformation())
    {
      wuTrackInformation* trackInformation = (wuTrackInformation*)(aTrack->GetUserInformation());
      if(trackInformation->PrintFlag() > 3) return fKill;
    }

  return fUrgent;
}

wuSteppingAction.cc

// 添加头文件
#include "wuTrackInformation.hh"

void wuSteppingAction::UserSteppingAction(const G4Step* step)
{
  // 这部分省略
  // G4Track* aTrack = step->GetTrack();  


  wuTrackInformation* trackInfo = 
    (wuTrackInformation*)(aTrack->GetUserInformation());
  int Info = trackInfo->PrintFlag();

  // 这部分省略
  // 将 Info 填充到 tree 中
}