(旧)研究メモ

kennkyuumemo

Geant4でのデータ収集の仕方(2)

一番簡単なやり方、

ユーザフック


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;