问题描述
我有一个简单的几何形状,它由一块薄的硅板(我的敏感探测器)组成,在其中向我发射511 keV光子的准直光束。 我只想用敏感探测器选择那些康普顿散射一次的光子。
我试图在我的SensitiveDetector.cc(称为SensitiveDetectorCPET03.cc)中放置一个条件,但这样做没有成功。我希望使用G4Step类来告诉我主光子是否被康普顿散射。
我的代码(在SensitiveDetectorCPET03.cc中)尝试应用此条件的部分如下
(HitCPET04.hh是myHit脚本)
G4bool SensitiveDetectorCPET04::ProcessHits(G4SteP* aStep,G4TouchableHistory*){
HitCPET04* newHit = new HitCPET04();
我想访问GetProcessDefinedStep(),因为我觉得这会 告诉我我的主光子和敏感探测器(如果有)之间发生了什么物理过程。因此,我首先介绍这一行代码。
G4StepPoint* postStepPoint = aStep->GetPostStepPoint();
现在,我尝试创建一个称为“进程”的const指针,希望它指向
信息存储在GetProcessDefinedStep()中,希望可以告诉我是什么过程导致了光子散射。所以我写这段代码
```const G4VProcess *process = postStepPoint->GetProcessDefinedStep();```
如果我能再写一个这样的条件。
if( *process == "compt" ){
fHitsCollection->insert( newHit );
// get analysis manager```
auto analysisManager = G4AnalysisManager::Instance();
G4double En = KineticEnergy/keV;
G4double theta = acos( 2- 511.0/En );
// fill ntuple
analysisManager->FillNtupleDColumn(0,KineticEnergy/keV);
analysisManager->FillNtupleDColumn(1,theta/deg);
analysisManager->AddNtupleRow(0);
std::cout << postStepPoint << std::endl;
}
return true;
}
那我想我会好起来的,但这行不通。我的编译器向我尖叫
没有运算符“ ==”匹配这些操作数-操作数类型为:const G4VProcess == const char [6]
我真的是Geant4的新人,所以我很抱歉我的知识很有限。我想如何设置条件,以仅记录康普顿被敏感探测器散射一次的那些光子。
感谢您抽出宝贵的时间阅读我的请求。
最诚挚的问候
彼得
解决方法
借助出色的解释,我已经解决了问题。 https://www.researchgate.net/post/How_to_stop_particles_tracking_in_GEANT4
下面的直方图显示了当我将角度分布与Klein-Nishina理论进行比较时得到的一致性。 (标题应为0.5毫米的Si立方。)
[Klein-Nishina理论与模拟] [1]
(下面是对我的ProccessHits代码的调整+一些解释。我希望这可以对其他人有所帮助。)
G4bool SensitiveDetectorCPET04::ProcessHits(G4Step* aStep,G4TouchableHistory*)
{
//实例化G4Analysismanager
auto analysisManager = G4AnalysisManager::Instance();
// c.f. https://www.researchgate.net/post/How_to_stop_particles_tracking_in_GEANT4 //在此方法内,您应该从step对象访问轨道:
G4Track *aTrack = aStep->GetTrack();
//然后,如果该过程是,则应该获取轨道的KineticEnergy //“康普顿散射”,如果在下一步中体积保持不变。 //参见下面的代码行:
G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
if (CurrentProcess != 0)
{
// To implement the next line,one needs to include " #include "G4VProcess.hh" "
// (See SteppingAction.cc in TestEm6)
const G4String & StepProcessName = CurrentProcess->GetProcessName();
// Get track ID for current processes
G4double TrackID = aStep->GetTrack()->GetTrackID();
if( (StepProcessName == "compt")&&(TrackID==1) )
{
// processing hit when entering the volume
G4double kineticEnergy = aStep->GetTrack()->GetKineticEnergy();
auto EkinUnits = G4BestUnit(kineticEnergy,"Energy");
// Get energy in units of keV
G4double En = kineticEnergy/keV;
// Determine angle in radians
G4double thetaRad = std::acos( 2- 511/En );
// Place condition to reject Compton scattering at 0 rad.
// (This is to avoid nan results when dividing through by 2pisin(theta))
if ( (thetaRad > 0) && (thetaRad < pi))
{
// fill histogram id = 0 (angular spread (in radians) as a function of scattering angle)
analysisManager->FillH1(0,thetaRad);
// (This produces the data in the above graph) ---> The theoretical curve comes from my root script.
// fill of histogram id = 1 (angular spread (in radians) as a function of solid angle)
// c.f. TestEm5 (TrackingAction.cc) and also (corrections at)
// https://geant4-forum.web.cern.ch/t/physics-validation/2893
G4double dthetaRad1 = ( analysisManager->GetH1Width(1) );
G4double unit1 = analysisManager->GetH1Unit(1);
G4double weight1 = (unit1)/( twopi*std::sin(thetaRad)*dthetaRad1 );
analysisManager->FillH1(1,thetaRad,weight1); **GRAPH NOT SHOWM**
// get particle name that's undergone the Compton scattering
G4String ParticleName = aStep->GetTrack()->GetParticleDefinition()->GetParticleName();
// Find position (c.f. /examples/extended/medical/GammaTherapy) in CheckVolumeSD.cc
G4ThreeVector pos = aStep->GetPreStepPoint()->GetPosition();
// G4double x = pos.x();
// G4double y = pos.y();
G4double z = pos.z();
// Fill NTuples
analysisManager->FillNtupleDColumn(0,En/keV);
analysisManager->FillNtupleDColumn(1,thetaRad/deg);
// analysisManager->FillNtupleDColumn(2,x/um);
// analysisManager->FillNtupleDColumn(3,y/um);
analysisManager->FillNtupleDColumn(2,z/um);
analysisManager->AddNtupleRow(0);
// FOR CHECKING
std::cout << "fromVolume: " << fromVolume
// << " unit: " << unit
<< " Particle: " << ParticleName
<< " Process: " << StepProcessName
<< " Energy: " << EkinUnits
<< " Angle: " << thetaRad/degree << " deg." << std::endl;
// << " Scattering site: " << pos << std::endl;
}
}
}
return true;
}
Best
Peter
[1]: https://i.stack.imgur.com/WsKu1.jpg