Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/extended/electromagnetic/TestEm5/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 electromagnetic/TestEm5/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 "G4UnitsTable.hh"
 42 
 43 #include <iomanip>
 44 
 45 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 46 
 47 Run::Run(DetectorConstruction* det) : fDetector(det) {}
 48 
 49 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 50 
 51 void Run::SetPrimary(G4ParticleDefinition* particle, G4double energy)
 52 {
 53   fParticle = particle;
 54   fEkin = energy;
 55 
 56   // compute theta0
 57   fMscThetaCentral = 3 * ComputeMscHighland();
 58 }
 59 
 60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 61 
 62 void Run::Merge(const G4Run* run)
 63 {
 64   const Run* localRun = static_cast<const Run*>(run);
 65 
 66   // pass information about primary particle
 67   fParticle = localRun->fParticle;
 68   fEkin = localRun->fEkin;
 69 
 70   fMscThetaCentral = localRun->fMscThetaCentral;
 71 
 72   // accumulate sums
 73   //
 74   fEnergyDeposit += localRun->fEnergyDeposit;
 75   fEnergyDeposit2 += localRun->fEnergyDeposit2;
 76   fTrakLenCharged += localRun->fTrakLenCharged;
 77   fTrakLenCharged2 += localRun->fTrakLenCharged2;
 78   fTrakLenNeutral += localRun->fTrakLenNeutral;
 79   fTrakLenNeutral2 += localRun->fTrakLenNeutral2;
 80   fNbStepsCharged += localRun->fNbStepsCharged;
 81   fNbStepsCharged2 += localRun->fNbStepsCharged2;
 82   fNbStepsNeutral += localRun->fNbStepsNeutral;
 83   fNbStepsNeutral2 += localRun->fNbStepsNeutral2;
 84   fMscProjecTheta += localRun->fMscProjecTheta;
 85   fMscProjecTheta2 += localRun->fMscProjecTheta2;
 86 
 87   fTypes[0] += localRun->fTypes[0];
 88   fTypes[1] += localRun->fTypes[1];
 89   fTypes[2] += localRun->fTypes[2];
 90   fTypes[3] += localRun->fTypes[3];
 91 
 92   fNbGamma += localRun->fNbGamma;
 93   fNbElect += localRun->fNbElect;
 94   fNbPosit += localRun->fNbPosit;
 95 
 96   fTransmit[0] += localRun->fTransmit[0];
 97   fTransmit[1] += localRun->fTransmit[1];
 98   fReflect[0] += localRun->fReflect[0];
 99   fReflect[1] += localRun->fReflect[1];
100 
101   fMscEntryCentral += localRun->fMscEntryCentral;
102 
103   fEnergyLeak[0] += localRun->fEnergyLeak[0];
104   fEnergyLeak[1] += localRun->fEnergyLeak[1];
105   fEnergyLeak2[0] += localRun->fEnergyLeak2[0];
106   fEnergyLeak2[1] += localRun->fEnergyLeak2[1];
107 
108   G4Run::Merge(run);
109 }
110 
111 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
112 
113 void Run::EndOfRun()
114 {
115   // compute mean and rms
116   //
117   G4int TotNbofEvents = numberOfEvent;
118   if (TotNbofEvents == 0) return;
119 
120   G4double EnergyBalance = fEnergyDeposit + fEnergyLeak[0] + fEnergyLeak[1];
121   EnergyBalance /= TotNbofEvents;
122 
123   fEnergyDeposit /= TotNbofEvents;
124   fEnergyDeposit2 /= TotNbofEvents;
125   G4double rmsEdep = fEnergyDeposit2 - fEnergyDeposit * fEnergyDeposit;
126   if (rmsEdep > 0.)
127     rmsEdep = std::sqrt(rmsEdep / TotNbofEvents);
128   else
129     rmsEdep = 0.;
130 
131   fTrakLenCharged /= TotNbofEvents;
132   fTrakLenCharged2 /= TotNbofEvents;
133   G4double rmsTLCh = fTrakLenCharged2 - fTrakLenCharged * fTrakLenCharged;
134   if (rmsTLCh > 0.)
135     rmsTLCh = std::sqrt(rmsTLCh / TotNbofEvents);
136   else
137     rmsTLCh = 0.;
138 
139   fTrakLenNeutral /= TotNbofEvents;
140   fTrakLenNeutral2 /= TotNbofEvents;
141   G4double rmsTLNe = fTrakLenNeutral2 - fTrakLenNeutral * fTrakLenNeutral;
142   if (rmsTLNe > 0.)
143     rmsTLNe = std::sqrt(rmsTLNe / TotNbofEvents);
144   else
145     rmsTLNe = 0.;
146 
147   fNbStepsCharged /= TotNbofEvents;
148   fNbStepsCharged2 /= TotNbofEvents;
149   G4double rmsStCh = fNbStepsCharged2 - fNbStepsCharged * fNbStepsCharged;
150   if (rmsStCh > 0.)
151     rmsStCh = std::sqrt(rmsStCh / TotNbofEvents);
152   else
153     rmsStCh = 0.;
154 
155   fNbStepsNeutral /= TotNbofEvents;
156   fNbStepsNeutral2 /= TotNbofEvents;
157   G4double rmsStNe = fNbStepsNeutral2 - fNbStepsNeutral * fNbStepsNeutral;
158   if (rmsStNe > 0.)
159     rmsStNe = std::sqrt(rmsStNe / TotNbofEvents);
160   else
161     rmsStNe = 0.;
162 
163   G4double Gamma = (G4double)fNbGamma / TotNbofEvents;
164   G4double Elect = (G4double)fNbElect / TotNbofEvents;
165   G4double Posit = (G4double)fNbPosit / TotNbofEvents;
166 
167   G4double transmit[2];
168   transmit[0] = 100. * fTransmit[0] / TotNbofEvents;
169   transmit[1] = 100. * fTransmit[1] / TotNbofEvents;
170 
171   G4double reflect[2];
172   reflect[0] = 100. * fReflect[0] / TotNbofEvents;
173   reflect[1] = 100. * fReflect[1] / TotNbofEvents;
174 
175   G4double rmsMsc = 0., tailMsc = 0.;
176   if (fMscEntryCentral > 0) {
177     fMscProjecTheta /= fMscEntryCentral;
178     fMscProjecTheta2 /= fMscEntryCentral;
179     rmsMsc = fMscProjecTheta2 - fMscProjecTheta * fMscProjecTheta;
180     if (rmsMsc > 0.) {
181       rmsMsc = std::sqrt(rmsMsc);
182     }
183     if (fTransmit[1] > 0.0) {
184       tailMsc = 100. - (100. * fMscEntryCentral) / (2 * fTransmit[1]);
185     }
186   }
187 
188   fEnergyLeak[0] /= TotNbofEvents;
189   fEnergyLeak2[0] /= TotNbofEvents;
190   G4double rmsEl0 = fEnergyLeak2[0] - fEnergyLeak[0] * fEnergyLeak[0];
191   if (rmsEl0 > 0.)
192     rmsEl0 = std::sqrt(rmsEl0 / TotNbofEvents);
193   else
194     rmsEl0 = 0.;
195 
196   fEnergyLeak[1] /= TotNbofEvents;
197   fEnergyLeak2[1] /= TotNbofEvents;
198   G4double rmsEl1 = fEnergyLeak2[1] - fEnergyLeak[1] * fEnergyLeak[1];
199   if (rmsEl1 > 0.)
200     rmsEl1 = std::sqrt(rmsEl1 / TotNbofEvents);
201   else
202     rmsEl1 = 0.;
203 
204   // Stopping Power from input Table.
205   //
206   const G4Material* material = fDetector->GetAbsorberMaterial();
207   G4double length = fDetector->GetAbsorberThickness();
208   G4double density = material->GetDensity();
209   G4String partName = fParticle->GetParticleName();
210 
211   G4EmCalculator emCalculator;
212   G4double dEdxTable = 0., dEdxFull = 0.;
213   if (fParticle->GetPDGCharge() != 0.) {
214     dEdxTable = emCalculator.GetDEDX(fEkin, fParticle, material);
215     dEdxFull = emCalculator.ComputeTotalDEDX(fEkin, fParticle, material);
216   }
217   G4double stopTable = dEdxTable / density;
218   G4double stopFull = dEdxFull / density;
219 
220   // Stopping Power from simulation.
221   //
222   G4double meandEdx = fEnergyDeposit / length;
223   G4double stopPower = meandEdx / density;
224 
225   G4cout << "\n ======================== run summary ======================\n";
226 
227   G4int prec = G4cout.precision(3);
228 
229   G4cout << "\n The run was " << TotNbofEvents << " " << partName << " of "
230          << G4BestUnit(fEkin, "Energy") << " through " << G4BestUnit(length, "Length") << " of "
231          << material->GetName() << " (density: " << G4BestUnit(density, "Volumic Mass") << ")"
232          << G4endl;
233 
234   G4cout.precision(4);
235 
236   G4cout << "\n Total energy deposit in absorber per event = "
237          << G4BestUnit(fEnergyDeposit, "Energy") << " +- " << G4BestUnit(rmsEdep, "Energy")
238          << G4endl;
239 
240   G4cout << "\n -----> Mean dE/dx = " << meandEdx / (MeV / cm) << " MeV/cm"
241          << "\t(" << stopPower / (MeV * cm2 / g) << " MeV*cm2/g)" << G4endl;
242 
243   G4cout << "\n From formulas :" << G4endl;
244   G4cout << "   restricted dEdx = " << dEdxTable / (MeV / cm) << " MeV/cm"
245          << "\t(" << stopTable / (MeV * cm2 / g) << " MeV*cm2/g)" << G4endl;
246 
247   G4cout << "   full dEdx       = " << dEdxFull / (MeV / cm) << " MeV/cm"
248          << "\t(" << stopFull / (MeV * cm2 / g) << " MeV*cm2/g)" << G4endl;
249 
250   G4cout << "\n Leakage :  primary = " << G4BestUnit(fEnergyLeak[0], "Energy") << " +- "
251          << G4BestUnit(rmsEl0, "Energy")
252          << "   secondaries = " << G4BestUnit(fEnergyLeak[1], "Energy") << " +- "
253          << G4BestUnit(rmsEl1, "Energy") << G4endl;
254 
255   G4cout << " Energy balance :  edep + eleak = " << G4BestUnit(EnergyBalance, "Energy") << G4endl;
256 
257   G4cout << "\n Total track length (charged) in absorber per event = "
258          << G4BestUnit(fTrakLenCharged, "Length") << " +- " << G4BestUnit(rmsTLCh, "Length")
259          << G4endl;
260 
261   G4cout << " Total track length (neutral) in absorber per event = "
262          << G4BestUnit(fTrakLenNeutral, "Length") << " +- " << G4BestUnit(rmsTLNe, "Length")
263          << G4endl;
264 
265   G4cout << "\n Number of steps (charged) in absorber per event = " << fNbStepsCharged << " +- "
266          << rmsStCh << G4endl;
267 
268   G4cout << " Number of steps (neutral) in absorber per event = " << fNbStepsNeutral << " +- "
269          << rmsStNe << G4endl;
270 
271   G4cout << "\n Number of secondaries per event : Gammas = " << Gamma << ";   electrons = " << Elect
272          << ";   positrons = " << Posit << G4endl;
273 
274   G4cout << "\n Number of events with the primary particle transmitted = " << transmit[1] << " %"
275          << G4endl;
276 
277   G4cout << " Number of events with at least  1 particle transmitted "
278          << "(same charge as primary) = " << transmit[0] << " %" << G4endl;
279 
280   G4cout << "\n Number of events with the primary particle reflected = " << reflect[1] << " %"
281          << G4endl;
282 
283   G4cout << " Number of events with at least  1 particle reflected "
284          << "(same charge as primary) = " << reflect[0] << " %" << G4endl;
285 
286   // compute width of the Gaussian central part of the MultipleScattering
287   //
288   G4cout << "\n MultipleScattering:"
289          << "\n  rms proj angle of transmit primary particle = " << rmsMsc / mrad
290          << " mrad (central part only)" << G4endl;
291 
292   G4cout << "  computed theta0 (Highland formula)          = " << ComputeMscHighland() / mrad
293          << " mrad" << G4endl;
294 
295   G4cout << "  central part defined as +- " << fMscThetaCentral / mrad << " mrad; "
296          << "  Tail ratio = " << tailMsc << " %" << G4endl;
297 
298   // gamma process counts
299   //
300   G4cout << "\n Gamma process counts:" << G4endl;
301   G4cout << "   Photoeffect " << fTypes[0] << G4endl;
302   G4cout << "   Compton     " << fTypes[1] << G4endl;
303   G4cout << "   Conversion  " << fTypes[2] << G4endl;
304   G4cout << "   Rayleigh    " << fTypes[3] << G4endl;
305 
306   // normalize histograms
307   //
308   G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
309 
310   G4int ih = 1;
311   G4double binWidth = analysisManager->GetH1Width(ih);
312   G4double fac = 1. / (TotNbofEvents * binWidth);
313   analysisManager->ScaleH1(ih, fac);
314 
315   ih = 10;
316   binWidth = analysisManager->GetH1Width(ih);
317   fac = 1. / (TotNbofEvents * binWidth);
318   analysisManager->ScaleH1(ih, fac);
319 
320   ih = 12;
321   analysisManager->ScaleH1(ih, 1. / TotNbofEvents);
322 
323   // reset default precision
324   G4cout.precision(prec);
325 }
326 
327 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
328 
329 G4double Run::ComputeMscHighland()
330 {
331   // compute the width of the Gaussian central part of the MultipleScattering
332   // projected angular distribution.
333   // Eur. Phys. Jour. C15 (2000) page 166, formule 23.9
334 
335   G4double t =
336     (fDetector->GetAbsorberThickness()) / (fDetector->GetAbsorberMaterial()->GetRadlen());
337   if (t < DBL_MIN) return 0.;
338 
339   G4double T = fEkin;
340   G4double M = fParticle->GetPDGMass();
341   G4double z = std::abs(fParticle->GetPDGCharge() / eplus);
342 
343   G4double bpc = T * (T + 2 * M) / (T + M);
344   G4double teta0 = 13.6 * MeV * z * std::sqrt(t) * (1. + 0.038 * std::log(t)) / bpc;
345   return teta0;
346 }
347 
348 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
349