EventAction

与 G4UserRunAction、G4UserSteppingAction 类似,G4UserEventAction 也是提取物理量的一个重要接口,主要通过 ndOfEventAction 函数来实现。该函数在每个 Event 之后之后调用一次,用户可以通过这个接口提取灵敏探测器的数据。

class G4UserEventAction 
{
  public:

    G4UserEventAction();
    virtual ~G4UserEventAction() = default;
    virtual void SetEventManager(G4EventManager* value);

    virtual void BeginOfEventAction(const G4Event* anEvent);
    virtual void EndOfEventAction(const G4Event* anEvent);
      // Two virtual method the user can override.

    virtual void MergeSubEvent(G4Event* masterEvent, const G4Event* subEvent);
      // A virtual method to merge the results of a sub-event into the master
      // event. The ownership of "subEvent" and its contents blong to the
      // worker thread. 
      // Merging trajectories and scores are taken care by G4Event and
      // G4ScoringManager so the user does not need to take care of them.
      // But merging hits collections and UserEventInformation must be taken 
      // care by this method.
      // This method is invoked only for the case of sub-event parallelism.

  protected:

      G4EventManager* fpEventManager = nullptr; // not owned
};

以下是我们提供示例代码中的截图

picevent1

在函数 EndOfEventAction(const G4Event* anEvent) 中,通过遍历灵敏探测器,获得每个灵敏探测器里面的数据。

void wuEventActionAll::EndOfEventAction(const G4Event* anEvent)
{
  // // 读取该事件SD中记录的数据
  G4HCofThisEvent *HCE = anEvent->GetHCofThisEvent();//SD  (hits collections of this event)
  if(HCE)
    {
      size_t nHCinHCE = HCE->GetCapacity();//SD个数
      // 
      for(size_t i = 0; i < nHCinHCE; i++)//遍历SD
    {
      // 拿到HitCollection
      wuHitCollection* HC = 0;
      HC = (wuHitCollection*)(HCE->GetHC(i)); 
      if(HC) OneHitOrder(HC);//写数据
    }
    }
}

这里数据筛选以及数据存储被封装到函数 OneHitOrder

picevent2

该函数遍历一个灵敏探测器的数据(step),在存储数据之前,可先对数据进行简单的筛选,降低数据量。具体可参考 StepingAction 中的方式。

示例代码中,我们对两个探测器都设置为灵敏探测器。下图为典型的 steping 和 SD 同时数据输出,我们可以看到 EventID 为 14 的事件,高亮部分是灵敏探测器输出的数据。

picevent3

通常情况下,我们只需要通过一种方式进行数据输出即可,文件 wuActionInitialization.cc 可控制数据输出方式。

void wuActionInitialization::Build() const
{
  //源的设置
  SetUserAction(new wuPrimaryGeneratorActionAll);

#if G4VERSION_NUMBER >= 1030

  G4MultiRunAction* actsRun = new G4MultiRunAction;
  G4MultiEventAction* actsEvent = new G4MultiEventAction;
  G4MultiTrackingAction* actsTrack = new G4MultiTrackingAction;
  G4MultiSteppingAction* actsStep = new G4MultiSteppingAction;

  //...0123456789876543210...0123456789876543210...

  actsRun->push_back(G4UserRunActionUPtr(new wuRunActionAll));
  actsEvent->push_back(G4UserEventActionUPtr(new wuEventActionAll));
  actsTrack->push_back(G4UserTrackingActionUPtr(new wuTrackingActionAll));
  actsStep->push_back(G4UserSteppingActionUPtr(new wuSteppingActionAll));

  SetUserAction(new wuStackingActionAll);


  //...0123456789876543210...0123456789876543210...

  SetUserAction(actsRun);
  SetUserAction(actsTrack);
  // 数据输出,根据需要开启  
  SetUserAction(actsEvent);// save SD data 
  SetUserAction(actsStep);// save step data

#else
  G4cout<<"It need G4VERSION_NUMBER >= 1030"<<G4endl;
#endif 
}