GEANT4学习 第三节 B2中的SD 敏感探测器 1

GEANT4学习 第三节 B2中的SD 敏感探测器 1

SD探测器是G4里面比较常用的一个类,在我们领域还是非常重要的。

在之前,read-out的工作都是通过自己写step发生点的判断,然后计算event的能量沉积来输出沉积能量谱(实质上就是自己写的SD探测器)。

这一部分呢,我们尝试通过B2a这个例子,来使用SD探测器read-out。

1. B2 README固定靶实验

README中大概讲了这么几个事情:

1.1几何:

一个靶和六个电离室,都是圆柱体。
这个粒子包涵磁场(这一部分我不懂),通过交互命令可以来设置场强。
在B2中,使用了B2TrackerSD类,并注册了一个逻辑体作为探测器。
同样的,靶和电离室的材料也可以通过交互命令来更改。

1.2物理列表

和B1不同,B2使用的是FTFP_BERT

1.3用户初始化

没啥可讲的

1.4初始粒子产生

还是G4ParticleGun这个类,这个和B1一样。这里提一句,我们组用的比较多的还是GPS来写源,更改更加方便。GPS在G4别的例子里面也有。

1.5探测器响应

使用 HIT 来记录能量的沉积

在这个例子中,电离室被定义成了SD,

那么,某一step中的一个 HIT 就是4个信息的集合:
1.track ID
2.电离室号
3.step内的能量沉积
4.能量沉积位置。

B2TrackSD::ProcessHits()会在粒子输运过程中的每一个step来实例化B2TrackHit的对象,即一个HIT。然后这个HIT会被收集到HitsCollection里面,

HitsCollection会在event结束时被打印在日志文件中。

2.main函数

和B1的区别只有一个物理列表是不同的。

运行还是一样,进入init_vis.mac,然后vis.mac,然后beamon

还是跟着代码的逻辑来,第一个类是B2aDetectorConstruction

3.B2aDetectorConstruction

我们先列一下这个类里面所有的参数和函数,这里我们稍微粗糙点,不管他们是公有还是私有的了。

序号函数备注
1B2aDetectorConstruction构造函数
2~B2aDetectorConstruction析构函数
3Construct
4ConstructSDandField
5SetTargetMaterial
6SetChamberMaterial
7SetMaxStep
8SetCheckOverlaps
9DefineMaterials
10DefineVolumes
序号参数备注
1fNbOfChambers电离室的个数
2fLogicTarget靶的逻辑体指针
3fLogicChamber电离室逻辑体指针
4fTargetMaterial靶材料指针
5fChamberMaterial电离室材料指针
6fStepLimitstep limits 的指针
7fMessengerB2aDetectorMessenger的对象
8fMagFieldMessenger磁场Messenger对象
9fCheckOverlapsoverlap检查选项

构造函数和析构函数就不想说了。

B2a为了使用交互命令来修改探测器的几何结构,特意写了一个B2aDetectorMessenger,几何结构通过fMessenger来实现,这也让B2aDetectorConstruction显得有一点复杂,仔细梳理应该还是没问题的。

主要的还是 B2aDetectorConstruction::ConstructSDandField这个函数。首先,这个函数在G4VUserDetectorConstruction里面也有,猜测G4VUserDetectorConstruction的构造函数会首先检查并调用该函数。

我们把这个函数拿出来看一下:

void B2aDetectorConstruction::ConstructSDandField()
{
  // Sensitive detectors

  G4String trackerChamberSDname = "B2/TrackerChamberSD";
  B2TrackerSD* aTrackerSD = new B2TrackerSD(trackerChamberSDname,
                                            "TrackerHitsCollection");        //实例化了一个TrackSD对象
  G4SDManager::GetSDMpointer()->AddNewDetector(aTrackerSD);   //添加探测器
  // Setting aTrackerSD to all logical volumes with the same name 
  // of "Chamber_LV".
  SetSensitiveDetector("Chamber_LV", aTrackerSD, true);      //设置探测器
// 这三个参数分别为 SD的逻辑体名字,一个G4VSensitiveDetector对象指针,以及是否多线程运行;最后一个参数可以省略
  // Create global magnetic field messenger.
  // Uniform magnetic field is then created automatically if
  // the field value is not zero.
  G4ThreeVector fieldValue = G4ThreeVector();
  fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue);
  fMagFieldMessenger->SetVerboseLevel(1);
  
  // Register the field messenger for deleting
  G4AutoDelete::Register(fMagFieldMessenger);
}

在这个类里面,需要将探测器设置一下,即

SetSensitiveDetector("Chamber_LV", aTrackerSD, true);

这一句话。而这一句话的aTrackerSD是B2TrackerSD的一个对象,我们需要去看这个类写了些什么。

4.B2TrackerSD

这个类里面的函数和参数如下:

序号函数备注
1B2TrackerSD构造函数
2~B2TrackerSD析构函数
3Initialize
4ProcessHits这个函数需要返回bool
5EndOfEvent
序号参数备注
1fHitsCollectionB2TrackerHitsCollection类的指针

4.1 B2TrackerSD 构造函数

B2TrackerSD::B2TrackerSD(const G4String& name,
                         const G4String& hitsCollectionName) 
 : G4VSensitiveDetector(name),
   fHitsCollection(NULL)
{
  collectionName.insert(hitsCollectionName);
}

构造的时候插了一个hitsCollectionName到collectionName里面

但我没找到collectionName在哪里定义的。

4.2 Initialize()

void B2TrackerSD::Initialize(G4HCofThisEvent* hce)
{
  // Create hits collection

  fHitsCollection 
    = new B2TrackerHitsCollection(SensitiveDetectorName, collectionName[0]); 
  //这里实例化了B2TrackerHitsCollection
  // Add this collection in hce

  G4int hcID 
    = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
  hce->AddHitsCollection( hcID, fHitsCollection ); 
}

4.3 ProcessHits()

G4bool B2TrackerSD::ProcessHits(G4Step* aStep, 
                                     G4TouchableHistory*)
{  
  // energy deposit
  G4double edep = aStep->GetTotalEnergyDeposit();

  if (edep==0.) return false;

  B2TrackerHit* newHit = new B2TrackerHit();

  newHit->SetTrackID  (aStep->GetTrack()->GetTrackID());
  newHit->SetChamberNb(aStep->GetPreStepPoint()->GetTouchableHandle()
                                               ->GetCopyNumber());
  newHit->SetEdep(edep);
  newHit->SetPos (aStep->GetPostStepPoint()->GetPosition());

  fHitsCollection->insert( newHit );

  //newHit->Print();

  return true;
}

4.4 EndOfEvent()

这个是输出信息了

void B2TrackerSD::EndOfEvent(G4HCofThisEvent*)
{
  if ( verboseLevel>1 ) { 
     G4int nofHits = fHitsCollection->entries();
     G4cout << G4endl
            << "-------->Hits Collection: in this event they are " << nofHits 
            << " hits in the tracker chambers: " << G4endl;
     for ( G4int i=0; i<nofHits; i++ ) (*fHitsCollection)[i]->Print();
  }
}

在4.2Initialize()里面,即58-59行,实例化了B2TrackerHitsCollection,
另外在ProcessHits()里面,即78行,实例化了B2TrackerHit,
这两个类都在B2TrackerHit.hh文件里面,下面就看这个。

5. B2TrackerHit

序号函数备注
1B2TrackerHit构造函数
2B2TrackerHit(const B2TrackerHit&)
3~B2TrackerHit析构函数
4operator=
5operator==
6new
7delete
8Draw
9Print
10SetTrackID
11SetChamberNb
12SetEdep
13SetPos
10GetTrackID
11GetChamberNb
12GetEdep
13GetPos
序号参数备注
1fTrackIDTrackID
1fChamberNb
1fEdep
1fPos

其他的先不关注,大概和字面意思是差不多的

print这个函数里面,打印出了四个信息:

void B2TrackerHit::Print()
{
  G4cout
     << "  trackID: " << fTrackID << " chamberNb: " << fChamberNb
     << "Edep: "
     << std::setw(7) << G4BestUnit(fEdep,"Energy")
     << " Position: "
     << std::setw(7) << G4BestUnit( fPos,"Length")
     << G4endl;
}

6. B2ActionInitialization及B2PrimaryGeneratorAction

我们回到main函数中,注册完探测器几何形状后注册了物理列表,最后又注册了用户初始化。所以接下来看用户初始化,B2ActionInitialization

在B2ActionInitialization中,和B1一样,还是实例化B2PrimaryGeneratorAction,调用粒子枪来产生粒子。

这两个类都比较简单,没什么可讲的。

值得注意的是,B2a的初始粒子是质子,能量为3.0GeV:

G4ParticleDefinition* particleDefinition 
    = G4ParticleTable::GetParticleTable()->FindParticle("proton");

  fParticleGun->SetParticleDefinition(particleDefinition);
  fParticleGun->SetParticleMomentumDirection(G4ThreeVector(0.,0.,1.));
  fParticleGun->SetParticleEnergy(3.0*GeV);

这里讲完了运行的所有设置,后面呢就是输出信息的几个类了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

于谦烫头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值