一番簡単なやり方、
ユーザフック
exampleB1などで使われる。B1では線量計算をStep、Event、Run actionを自作して求める。
1. 構造物を作り、stepping actionをするvolumeを指定
2. Stepping actionクラス内で、今のStepがスコアすべき物体中にあるかどうかを調べて、その場合そのStepでのエネルギー付与を求めて積算
3. Event actionクラスで各Eventの後でエネルギー付与の積算
4. Run actionクラスで全Eventの積算を求めて、スコアした物体の質量と合わせて線量[J/kg]を計算し、出力
具体的に、
1. 構造物を作り、stepping actionをするvolumeを指定
new G4PVPlacement(0, //no rotation pos2, //at position logicShape2, //its logical volume "Shape2", //its name logicEnv, //its mother volume false, //no boolean operation 0, //copy number checkOverlaps); //overlaps checking // Set scoring volume to stepping action // (where we will account energy deposit) // B1SteppingAction* steppingAction = B1SteppingAction::Instance(); ////steppingAction->SetVolume(logicShape1); steppingAction->SetVolume(logicShape2);
2. Stepping actionクラス内で、今のStepがスコアすべき物体中にあるかどうかを調べて、その場合そのStepでのエネルギー付与を求めて積算
void B1SteppingAction::UserSteppingAction(const G4Step* step) { // get volume of the current step G4LogicalVolume* volume = step->GetPreStepPoint()->GetTouchableHandle() ->GetVolume()->GetLogicalVolume(); // check if we are in scoring volume if (volume != fVolume ) return; // collect energy and track length step by step G4double edep = step->GetTotalEnergyDeposit(); fEnergy += edep; }
3. Event actionクラスで各Eventの後でエネルギー付与の積算
void B1EventAction::BeginOfEventAction(const G4Event* event) { G4int eventNb = event->GetEventID(); if (eventNb%fPrintModulo == 0) { G4cout << "\n---> Begin of event: " << eventNb << G4endl; } // Reset accounted energy in stepping action B1SteppingAction::Instance()->Reset(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void B1EventAction::EndOfEventAction(const G4Event* /*event*/) { // accumulate statistics G4double energy = B1SteppingAction::Instance()->GetEnergy(); fEnergySum += energy; fEnergy2Sum += energy*energy; }
4. Run actionクラスで全Eventの積算を求めて、スコアした物体の質量と合わせて線量[J/kg]を計算し、出力
// Compute dose // G4double energySum = B1EventAction::Instance()->GetEnergySum(); G4double energy2Sum = B1EventAction::Instance()->GetEnergy2Sum(); G4double rms = energy2Sum - energySum*energySum/nofEvents; if (rms > 0.) rms = std::sqrt(rms); else rms = 0.; G4double mass = B1SteppingAction::Instance()->GetVolume()->GetMass(); G4double dose = energySum/mass; G4double rmsDose = rms/mass; … // Print // G4cout << "\n--------------------End of Run------------------------------\n" << " The run consists of " << nofEvents << " "<< particleName << " of " << G4BestUnit(particleEnergy,"Energy") << "\n Dose in scoring volume " << B1SteppingAction::Instance()->GetVolume()->GetName() << " : " << G4BestUnit(dose,"Dose") << " +- " << G4BestUnit(rmsDose,"Dose") << "\n------------------------------------------------------------\n" << G4endl;