Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/medical/GammaTherapy/src/Run.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 /// \file medical/GammaTherapy/src/Run.cc
 27 /// \brief Implementation of the Run class
 28 //
 29 //
 30 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 31 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 32 
 33 #include "Run.hh"
 34 
 35 #include "DetectorConstruction.hh"
 36 #include "HistoManager.hh"
 37 #include "PrimaryGeneratorAction.hh"
 38 
 39 #include "G4EmCalculator.hh"
 40 #include "G4SystemOfUnits.hh"
 41 #include "G4Track.hh"
 42 #include "G4UnitsTable.hh"
 43 #include "G4VPhysicalVolume.hh"
 44 
 45 #include <iomanip>
 46 
 47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 48 
 49 Run::Run(DetectorConstruction* det, HistoManager* histoMgr)
 50   : G4Run(), fDetector(det), fHistoMgr(histoMgr)
 51 {
 52   fSumR = 0;
 53   fNevt = fNelec = fNposit = fNgam = fNstep = fNgamPh = fNgamTar = fNeTar = fNePh = fNstepTarget =
 54     0;
 55 
 56   fAnalysisManager = G4AnalysisManager::Instance();
 57 
 58   fHistoId = fHistoMgr->GetHistoIdentifiers();
 59   fNHisto = fHistoId.size();
 60 
 61   fCheckVolume = fDetector->GetCheckVolume();
 62   fGasVolume = fDetector->GetGasVolume();
 63   fPhantom = fDetector->GetPhantom();
 64   fTarget1 = fDetector->GetTarget1();
 65   fTarget2 = fDetector->GetTarget2();
 66 
 67   fNBinsR = fDetector->GetNumberDivR();
 68   fNBinsZ = fDetector->GetNumberDivZ();
 69 
 70   fScoreZ = fDetector->GetScoreZ();
 71   fAbsorberZ = fDetector->GetAbsorberZ();
 72   fAbsorberR = fDetector->GetAbsorberR();
 73   fMaxEnergy = fDetector->GetMaxEnergy();
 74 
 75   fNBinsE = fDetector->GetNumberDivE();
 76   fMaxEnergy = fDetector->GetMaxEnergy();
 77 
 78   fStepZ = fAbsorberZ / (G4double)fNBinsZ;
 79   fStepR = fAbsorberR / (G4double)fNBinsR;
 80   fStepE = fMaxEnergy / (G4double)fNBinsE;
 81   fScoreBin = (G4int)(fScoreZ / fStepZ + 0.5);
 82 
 83   fVerbose = fDetector->GetVerbose();
 84 
 85   fGamma = G4Gamma::Gamma();
 86   fElectron = G4Electron::Electron();
 87   fPositron = G4Positron::Positron();
 88 
 89   G4cout << "   " << fNBinsR << " bins R   stepR= " << fStepR / mm << " mm " << G4endl;
 90   G4cout << "   " << fNBinsZ << " bins Z   stepZ= " << fStepZ / mm << " mm " << G4endl;
 91   G4cout << "   " << fNBinsE << " bins E   stepE= " << fStepE / MeV << " MeV " << G4endl;
 92   G4cout << "   " << fScoreBin << "-th bin in Z is used for R distribution" << G4endl;
 93 
 94   fVolumeR.clear();
 95   fEdep.clear();
 96   fGammaE.clear();
 97 
 98   fVolumeR.resize(fNBinsR, 0.0);
 99   fEdep.resize(fNBinsR, 0.0);
100   fGammaE.resize(fNBinsE, 0.0);
101 
102   G4double r1 = 0.0;
103   G4double r2 = fStepR;
104   for (G4int i = 0; i < fNBinsR; ++i) {
105     fVolumeR[i] = cm * cm / (CLHEP::pi * (r2 * r2 - r1 * r1));
106     r1 = r2;
107     r2 += fStepR;
108   }
109 
110   if (fAnalysisManager->GetFileName() != "") fHistoMgr->Update(det, true);
111 }
112 
113 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
114 
115 Run::~Run() {}
116 
117 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
118 
119 void Run::Merge(const G4Run* run)
120 {
121   const Run* localRun = static_cast<const Run*>(run);
122 
123   fNevt += localRun->fNevt;
124 
125   fNelec += localRun->fNelec;
126   fNgam += localRun->fNgam;
127   fNposit += localRun->fNposit;
128 
129   fNgamTar += localRun->fNgamTar;
130   fNgamPh += localRun->fNgamPh;
131   fNeTar += localRun->fNeTar;
132   fNePh += localRun->fNePh;
133 
134   fNstep += localRun->fNstep;
135   fNstepTarget += localRun->fNstepTarget;
136 
137   fSumR += localRun->fSumR;
138 
139   for (int i = 0; i < (int)fEdep.size(); i++)
140     fEdep[i] += localRun->fEdep[i];
141   for (int i = 0; i < (int)fGammaE.size(); i++)
142     fGammaE[i] += localRun->fGammaE[i];
143 
144   G4Run::Merge(run);
145 }
146 
147 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
148 
149 void Run::EndOfRun()
150 {
151   G4cout << "Histo: End of run actions are started" << G4endl;
152 
153   // average
154   G4cout << "========================================================" << G4endl;
155   G4double x = (G4double)fNevt;
156   if (fNevt > 0) {
157     x = 1.0 / x;
158   }
159   G4double xe = x * (G4double)fNelec;
160   G4double xg = x * (G4double)fNgam;
161   G4double xp = x * (G4double)fNposit;
162   G4double xs = x * (G4double)fNstep;
163   G4double xph = x * (G4double)fNgamPh;
164   G4double xes = x * (G4double)fNstepTarget;
165   G4double xgt = x * (G4double)fNgamTar;
166   G4double xet = x * (G4double)fNeTar;
167   G4double xphe = x * (G4double)fNePh;
168 
169   G4cout << "Number of events                             " << std::setprecision(8) << fNevt
170          << G4endl;
171   G4cout << std::setprecision(4) << "Average number of e-                         " << xe << G4endl;
172   G4cout << std::setprecision(4) << "Average number of gamma                      " << xg << G4endl;
173   G4cout << std::setprecision(4) << "Average number of e+                         " << xp << G4endl;
174   G4cout << std::setprecision(4) << "Average number of steps in the phantom       " << xs << G4endl;
175   G4cout << std::setprecision(4) << "Average number of e- steps in the target     " << xes
176          << G4endl;
177   G4cout << std::setprecision(4) << "Average number of g  produced in the target  " << xgt
178          << G4endl;
179   G4cout << std::setprecision(4) << "Average number of e- produced in the target  " << xet
180          << G4endl;
181   G4cout << std::setprecision(4) << "Average number of g produced in the phantom  " << xph
182          << G4endl;
183   G4cout << std::setprecision(4) << "Average number of e- produced in the phantom " << xphe
184          << G4endl;
185   G4cout << std::setprecision(4) << "Total fGamma fluence in front of the phantom "
186          << x * fSumR / MeV << " MeV " << G4endl;
187   G4cout << "========================================================" << G4endl;
188   G4cout << G4endl;
189   G4cout << G4endl;
190 
191   G4double sum = 0.0;
192   for (G4int i = 0; i < fNBinsR; i++) {
193     fEdep[i] *= x;
194     sum += fEdep[i];
195   }
196 
197   if (fAnalysisManager) {
198     if (fAnalysisManager->IsActive()) {
199       // normalise histograms
200       for (G4int i = 0; i < fNHisto; i++) {
201         fAnalysisManager->GetH1(fHistoId[i])->scale(x);
202       }
203       G4double nr = fEdep[0];
204       if (nr > 0.0) {
205         nr = 1. / nr;
206       }
207       fAnalysisManager->GetH1(fHistoId[0])->scale(nr);
208 
209       nr = sum * fStepR;
210       if (nr > 0.0) {
211         nr = 1. / nr;
212       }
213       fAnalysisManager->GetH1(fHistoId[1])->scale(nr);
214 
215       fAnalysisManager->GetH1(fHistoId[3])
216         ->scale(1000.0 * cm3 / (CLHEP::pi * fAbsorberR * fAbsorberR * fStepZ));
217       fAnalysisManager->GetH1(fHistoId[4])->scale(1000.0 * cm3 * fVolumeR[0] / fStepZ);
218 
219       // Write histogram file
220       if (!fAnalysisManager->Write()) {
221         G4Exception("Histo::Save()", "hist01", FatalException, "Cannot write ROOT file.");
222       }
223       G4cout << "### Histo::Save: Histograms are saved" << G4endl;
224       if (fAnalysisManager->CloseFile() && fVerbose) {
225         G4cout << "                 File is closed" << G4endl;
226       }
227     }
228   }
229 }
230 
231 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
232 
233 void Run::AddTargetPhoton(const G4DynamicParticle* p)
234 {
235   ++fNgamTar;
236   if (fAnalysisManager) {
237     fAnalysisManager->FillH1(fHistoId[5], p->GetKineticEnergy() / MeV, 1.0);
238   }
239 }
240 
241 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
242 
243 void Run::AddPhantomPhoton(const G4DynamicParticle*)
244 {
245   ++fNgamPh;
246 }
247 
248 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
249 
250 void Run::AddTargetElectron(const G4DynamicParticle* p)
251 {
252   ++fNeTar;
253   if (fAnalysisManager) {
254     fAnalysisManager->FillH1(fHistoId[8], p->GetKineticEnergy() / MeV, 1.0);
255   }
256 }
257 
258 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
259 
260 void Run::AddPhantomElectron(const G4DynamicParticle* p)
261 {
262   ++fNePh;
263   if (fAnalysisManager) {
264     fAnalysisManager->FillH1(fHistoId[7], p->GetKineticEnergy() / MeV, 1.0);
265   }
266 }
267 
268 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
269 
270 void Run::ScoreNewTrack(const G4Track* aTrack)
271 {
272   // Save primary parameters
273   const G4ParticleDefinition* particle = aTrack->GetParticleDefinition();
274   G4int pid = aTrack->GetParentID();
275   G4VPhysicalVolume* pv = aTrack->GetVolume();
276   const G4DynamicParticle* dp = aTrack->GetDynamicParticle();
277 
278   // primary particle
279   if (0 == pid) {
280     ++fNevt;
281     if (fVerbose) {
282       G4ThreeVector pos = aTrack->GetVertexPosition();
283       G4ThreeVector dir = aTrack->GetMomentumDirection();
284       G4cout << "TrackingAction: Primary " << particle->GetParticleName()
285              << " Ekin(MeV)= " << aTrack->GetKineticEnergy() / MeV << "; pos= " << pos
286              << ";  dir= " << dir << G4endl;
287     }
288     // secondary electron
289   }
290   else if (0 < pid && particle == fElectron) {
291     if (fVerbose) {
292       G4cout << "TrackingAction: Secondary electron " << G4endl;
293     }
294     AddElectron();
295     if (pv == fPhantom) {
296       AddPhantomElectron(dp);
297     }
298     else if (pv == fTarget1 || pv == fTarget2) {
299       AddTargetElectron(dp);
300     }
301 
302     // secondary positron
303   }
304   else if (0 < pid && particle == fPositron) {
305     if (fVerbose) {
306       G4cout << "TrackingAction: Secondary positron " << G4endl;
307     }
308     AddPositron();
309 
310     // secondary gamma
311   }
312   else if (0 < pid && particle == fGamma) {
313     if (fVerbose) {
314       G4cout << "TrackingAction: Secondary gamma; parentID= " << pid
315              << " E= " << aTrack->GetKineticEnergy() << G4endl;
316     }
317     AddPhoton();
318     if (pv == fPhantom) {
319       AddPhantomPhoton(dp);
320     }
321     else if (pv == fTarget1 || pv == fTarget2) {
322       AddTargetPhoton(dp);
323     }
324   }
325 }
326 
327 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
328 
329 void Run::AddPhantomGamma(G4double e, G4double r)
330 {
331   e /= MeV;
332   fSumR += e;
333   G4int bin = (G4int)(e / fStepE);
334   if (bin >= fNBinsE) {
335     bin = fNBinsE - 1;
336   }
337   fGammaE[bin] += e;
338   G4int bin1 = (G4int)(r / fStepR);
339   if (bin1 >= fNBinsR) {
340     bin1 = fNBinsR - 1;
341   }
342   if (fAnalysisManager) {
343     G4AnalysisManager::Instance()->FillH1(fHistoId[6], e, 1.0);
344     G4AnalysisManager::Instance()->FillH1(fHistoId[9], r, e * fVolumeR[bin1]);
345   }
346 }
347 
348 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
349 
350 void Run::AddPhantomStep(G4double edep, G4double r1, G4double z1, G4double r2, G4double z2,
351                          G4double r0, G4double z0)
352 {
353   ++fNstep;
354   G4int nzbin = (G4int)(z0 / fStepZ);
355   if (fVerbose) {
356     G4cout << "Histo: edep(MeV)= " << edep / MeV << " at binz= " << nzbin << " r1= " << r1
357            << " z1= " << z1 << " r2= " << r2 << " z2= " << z2 << " r0= " << r0 << " z0= " << z0
358            << G4endl;
359   }
360   if (nzbin == fScoreBin) {
361     G4int bin = (G4int)(r0 / fStepR);
362     if (bin >= fNBinsR) {
363       bin = fNBinsR - 1;
364     }
365     double w = edep * fVolumeR[bin];
366     fEdep[bin] += w;
367 
368     if (fAnalysisManager) {
369       G4AnalysisManager::Instance()->FillH1(fHistoId[0], r0, w);
370       G4AnalysisManager::Instance()->FillH1(fHistoId[1], r0, w);
371       G4AnalysisManager::Instance()->FillH1(fHistoId[2], r0, w);
372     }
373   }
374   G4int bin1 = (G4int)(z1 / fStepZ);
375   if (bin1 >= fNBinsZ) {
376     bin1 = fNBinsZ - 1;
377   }
378   G4int bin2 = (G4int)(z2 / fStepZ);
379   if (bin2 >= fNBinsZ) {
380     bin2 = fNBinsZ - 1;
381   }
382   if (bin1 == bin2) {
383     if (fAnalysisManager) {
384       G4AnalysisManager::Instance()->FillH1(fHistoId[3], z0, edep);
385       if (r1 < fStepR) {
386         G4double w = edep;
387         if (r2 > fStepR) {
388           w *= (fStepR - r1) / (r2 - r1);
389         }
390         G4AnalysisManager::Instance()->FillH1(fHistoId[4], z0, w);
391       }
392     }
393   }
394   else {
395     G4int bin;
396 
397     if (bin2 < bin1) {
398       bin = bin2;
399       G4double z = z2;
400       bin2 = bin1;
401       z2 = z1;
402       bin1 = bin;
403       z1 = z;
404     }
405     G4double zz1 = z1;
406     G4double zz2 = (bin1 + 1) * fStepZ;
407     G4double rr1 = r1;
408     G4double dz = z2 - z1;
409     G4double dr = r2 - r1;
410     G4double rr2 = r1 + dr * (zz2 - zz1) / dz;
411     for (bin = bin1; bin <= bin2; bin++) {
412       if (fAnalysisManager) {
413         G4double de = edep * (zz2 - zz1) / dz;
414         G4double zf = (zz1 + zz2) * 0.5;
415         {
416           G4AnalysisManager::Instance()->FillH1(fHistoId[3], zf, de);
417         }
418         if (rr1 < fStepR) {
419           G4double w = de;
420           if (rr2 > fStepR) w *= (fStepR - rr1) / (rr2 - rr1);
421           {
422             G4AnalysisManager::Instance()->FillH1(fHistoId[4], zf, w);
423           }
424         }
425       }
426       zz1 = zz2;
427       zz2 = std::min(z2, zz1 + fStepZ);
428       rr1 = rr2;
429       rr2 = rr1 + dr * (zz2 - zz1) / dz;
430     }
431   }
432 }
433 
434 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
435