Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:21:00

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file electromagnetic/TestEm5/src/Run.cc
0027 /// \brief Implementation of the Run class
0028 //
0029 //
0030 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0031 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0032 
0033 #include "Run.hh"
0034 
0035 #include "DetectorConstruction.hh"
0036 #include "HistoManager.hh"
0037 #include "PrimaryGeneratorAction.hh"
0038 
0039 #include "G4EmCalculator.hh"
0040 #include "G4SystemOfUnits.hh"
0041 #include "G4UnitsTable.hh"
0042 
0043 #include <iomanip>
0044 
0045 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0046 
0047 Run::Run(DetectorConstruction* det) : fDetector(det) {}
0048 
0049 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0050 
0051 void Run::SetPrimary(G4ParticleDefinition* particle, G4double energy)
0052 {
0053   fParticle = particle;
0054   fEkin = energy;
0055 
0056   // compute theta0
0057   fMscThetaCentral = 3 * ComputeMscHighland();
0058 }
0059 
0060 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0061 
0062 void Run::Merge(const G4Run* run)
0063 {
0064   const Run* localRun = static_cast<const Run*>(run);
0065 
0066   // pass information about primary particle
0067   fParticle = localRun->fParticle;
0068   fEkin = localRun->fEkin;
0069 
0070   fMscThetaCentral = localRun->fMscThetaCentral;
0071 
0072   // accumulate sums
0073   //
0074   fEnergyDeposit += localRun->fEnergyDeposit;
0075   fEnergyDeposit2 += localRun->fEnergyDeposit2;
0076   fTrakLenCharged += localRun->fTrakLenCharged;
0077   fTrakLenCharged2 += localRun->fTrakLenCharged2;
0078   fTrakLenNeutral += localRun->fTrakLenNeutral;
0079   fTrakLenNeutral2 += localRun->fTrakLenNeutral2;
0080   fNbStepsCharged += localRun->fNbStepsCharged;
0081   fNbStepsCharged2 += localRun->fNbStepsCharged2;
0082   fNbStepsNeutral += localRun->fNbStepsNeutral;
0083   fNbStepsNeutral2 += localRun->fNbStepsNeutral2;
0084   fMscProjecTheta += localRun->fMscProjecTheta;
0085   fMscProjecTheta2 += localRun->fMscProjecTheta2;
0086 
0087   fTypes[0] += localRun->fTypes[0];
0088   fTypes[1] += localRun->fTypes[1];
0089   fTypes[2] += localRun->fTypes[2];
0090   fTypes[3] += localRun->fTypes[3];
0091 
0092   fNbGamma += localRun->fNbGamma;
0093   fNbElect += localRun->fNbElect;
0094   fNbPosit += localRun->fNbPosit;
0095 
0096   fTransmit[0] += localRun->fTransmit[0];
0097   fTransmit[1] += localRun->fTransmit[1];
0098   fReflect[0] += localRun->fReflect[0];
0099   fReflect[1] += localRun->fReflect[1];
0100 
0101   fMscEntryCentral += localRun->fMscEntryCentral;
0102 
0103   fEnergyLeak[0] += localRun->fEnergyLeak[0];
0104   fEnergyLeak[1] += localRun->fEnergyLeak[1];
0105   fEnergyLeak2[0] += localRun->fEnergyLeak2[0];
0106   fEnergyLeak2[1] += localRun->fEnergyLeak2[1];
0107 
0108   G4Run::Merge(run);
0109 }
0110 
0111 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0112 
0113 void Run::EndOfRun()
0114 {
0115   // compute mean and rms
0116   //
0117   G4int TotNbofEvents = numberOfEvent;
0118   if (TotNbofEvents == 0) return;
0119 
0120   G4double EnergyBalance = fEnergyDeposit + fEnergyLeak[0] + fEnergyLeak[1];
0121   EnergyBalance /= TotNbofEvents;
0122 
0123   fEnergyDeposit /= TotNbofEvents;
0124   fEnergyDeposit2 /= TotNbofEvents;
0125   G4double rmsEdep = fEnergyDeposit2 - fEnergyDeposit * fEnergyDeposit;
0126   if (rmsEdep > 0.)
0127     rmsEdep = std::sqrt(rmsEdep / TotNbofEvents);
0128   else
0129     rmsEdep = 0.;
0130 
0131   fTrakLenCharged /= TotNbofEvents;
0132   fTrakLenCharged2 /= TotNbofEvents;
0133   G4double rmsTLCh = fTrakLenCharged2 - fTrakLenCharged * fTrakLenCharged;
0134   if (rmsTLCh > 0.)
0135     rmsTLCh = std::sqrt(rmsTLCh / TotNbofEvents);
0136   else
0137     rmsTLCh = 0.;
0138 
0139   fTrakLenNeutral /= TotNbofEvents;
0140   fTrakLenNeutral2 /= TotNbofEvents;
0141   G4double rmsTLNe = fTrakLenNeutral2 - fTrakLenNeutral * fTrakLenNeutral;
0142   if (rmsTLNe > 0.)
0143     rmsTLNe = std::sqrt(rmsTLNe / TotNbofEvents);
0144   else
0145     rmsTLNe = 0.;
0146 
0147   fNbStepsCharged /= TotNbofEvents;
0148   fNbStepsCharged2 /= TotNbofEvents;
0149   G4double rmsStCh = fNbStepsCharged2 - fNbStepsCharged * fNbStepsCharged;
0150   if (rmsStCh > 0.)
0151     rmsStCh = std::sqrt(rmsStCh / TotNbofEvents);
0152   else
0153     rmsStCh = 0.;
0154 
0155   fNbStepsNeutral /= TotNbofEvents;
0156   fNbStepsNeutral2 /= TotNbofEvents;
0157   G4double rmsStNe = fNbStepsNeutral2 - fNbStepsNeutral * fNbStepsNeutral;
0158   if (rmsStNe > 0.)
0159     rmsStNe = std::sqrt(rmsStNe / TotNbofEvents);
0160   else
0161     rmsStNe = 0.;
0162 
0163   G4double Gamma = (G4double)fNbGamma / TotNbofEvents;
0164   G4double Elect = (G4double)fNbElect / TotNbofEvents;
0165   G4double Posit = (G4double)fNbPosit / TotNbofEvents;
0166 
0167   G4double transmit[2];
0168   transmit[0] = 100. * fTransmit[0] / TotNbofEvents;
0169   transmit[1] = 100. * fTransmit[1] / TotNbofEvents;
0170 
0171   G4double reflect[2];
0172   reflect[0] = 100. * fReflect[0] / TotNbofEvents;
0173   reflect[1] = 100. * fReflect[1] / TotNbofEvents;
0174 
0175   G4double rmsMsc = 0., tailMsc = 0.;
0176   if (fMscEntryCentral > 0) {
0177     fMscProjecTheta /= fMscEntryCentral;
0178     fMscProjecTheta2 /= fMscEntryCentral;
0179     rmsMsc = fMscProjecTheta2 - fMscProjecTheta * fMscProjecTheta;
0180     if (rmsMsc > 0.) {
0181       rmsMsc = std::sqrt(rmsMsc);
0182     }
0183     if (fTransmit[1] > 0.0) {
0184       tailMsc = 100. - (100. * fMscEntryCentral) / (2 * fTransmit[1]);
0185     }
0186   }
0187 
0188   fEnergyLeak[0] /= TotNbofEvents;
0189   fEnergyLeak2[0] /= TotNbofEvents;
0190   G4double rmsEl0 = fEnergyLeak2[0] - fEnergyLeak[0] * fEnergyLeak[0];
0191   if (rmsEl0 > 0.)
0192     rmsEl0 = std::sqrt(rmsEl0 / TotNbofEvents);
0193   else
0194     rmsEl0 = 0.;
0195 
0196   fEnergyLeak[1] /= TotNbofEvents;
0197   fEnergyLeak2[1] /= TotNbofEvents;
0198   G4double rmsEl1 = fEnergyLeak2[1] - fEnergyLeak[1] * fEnergyLeak[1];
0199   if (rmsEl1 > 0.)
0200     rmsEl1 = std::sqrt(rmsEl1 / TotNbofEvents);
0201   else
0202     rmsEl1 = 0.;
0203 
0204   // Stopping Power from input Table.
0205   //
0206   const G4Material* material = fDetector->GetAbsorberMaterial();
0207   G4double length = fDetector->GetAbsorberThickness();
0208   G4double density = material->GetDensity();
0209   G4String partName = fParticle->GetParticleName();
0210 
0211   G4EmCalculator emCalculator;
0212   G4double dEdxTable = 0., dEdxFull = 0.;
0213   if (fParticle->GetPDGCharge() != 0.) {
0214     dEdxTable = emCalculator.GetDEDX(fEkin, fParticle, material);
0215     dEdxFull = emCalculator.ComputeTotalDEDX(fEkin, fParticle, material);
0216   }
0217   G4double stopTable = dEdxTable / density;
0218   G4double stopFull = dEdxFull / density;
0219 
0220   // Stopping Power from simulation.
0221   //
0222   G4double meandEdx = fEnergyDeposit / length;
0223   G4double stopPower = meandEdx / density;
0224 
0225   G4cout << "\n ======================== run summary ======================\n";
0226 
0227   G4int prec = G4cout.precision(3);
0228 
0229   G4cout << "\n The run was " << TotNbofEvents << " " << partName << " of "
0230          << G4BestUnit(fEkin, "Energy") << " through " << G4BestUnit(length, "Length") << " of "
0231          << material->GetName() << " (density: " << G4BestUnit(density, "Volumic Mass") << ")"
0232          << G4endl;
0233 
0234   G4cout.precision(4);
0235 
0236   G4cout << "\n Total energy deposit in absorber per event = "
0237          << G4BestUnit(fEnergyDeposit, "Energy") << " +- " << G4BestUnit(rmsEdep, "Energy")
0238          << G4endl;
0239 
0240   G4cout << "\n -----> Mean dE/dx = " << meandEdx / (MeV / cm) << " MeV/cm"
0241          << "\t(" << stopPower / (MeV * cm2 / g) << " MeV*cm2/g)" << G4endl;
0242 
0243   G4cout << "\n From formulas :" << G4endl;
0244   G4cout << "   restricted dEdx = " << dEdxTable / (MeV / cm) << " MeV/cm"
0245          << "\t(" << stopTable / (MeV * cm2 / g) << " MeV*cm2/g)" << G4endl;
0246 
0247   G4cout << "   full dEdx       = " << dEdxFull / (MeV / cm) << " MeV/cm"
0248          << "\t(" << stopFull / (MeV * cm2 / g) << " MeV*cm2/g)" << G4endl;
0249 
0250   G4cout << "\n Leakage :  primary = " << G4BestUnit(fEnergyLeak[0], "Energy") << " +- "
0251          << G4BestUnit(rmsEl0, "Energy")
0252          << "   secondaries = " << G4BestUnit(fEnergyLeak[1], "Energy") << " +- "
0253          << G4BestUnit(rmsEl1, "Energy") << G4endl;
0254 
0255   G4cout << " Energy balance :  edep + eleak = " << G4BestUnit(EnergyBalance, "Energy") << G4endl;
0256 
0257   G4cout << "\n Total track length (charged) in absorber per event = "
0258          << G4BestUnit(fTrakLenCharged, "Length") << " +- " << G4BestUnit(rmsTLCh, "Length")
0259          << G4endl;
0260 
0261   G4cout << " Total track length (neutral) in absorber per event = "
0262          << G4BestUnit(fTrakLenNeutral, "Length") << " +- " << G4BestUnit(rmsTLNe, "Length")
0263          << G4endl;
0264 
0265   G4cout << "\n Number of steps (charged) in absorber per event = " << fNbStepsCharged << " +- "
0266          << rmsStCh << G4endl;
0267 
0268   G4cout << " Number of steps (neutral) in absorber per event = " << fNbStepsNeutral << " +- "
0269          << rmsStNe << G4endl;
0270 
0271   G4cout << "\n Number of secondaries per event : Gammas = " << Gamma << ";   electrons = " << Elect
0272          << ";   positrons = " << Posit << G4endl;
0273 
0274   G4cout << "\n Number of events with the primary particle transmitted = " << transmit[1] << " %"
0275          << G4endl;
0276 
0277   G4cout << " Number of events with at least  1 particle transmitted "
0278          << "(same charge as primary) = " << transmit[0] << " %" << G4endl;
0279 
0280   G4cout << "\n Number of events with the primary particle reflected = " << reflect[1] << " %"
0281          << G4endl;
0282 
0283   G4cout << " Number of events with at least  1 particle reflected "
0284          << "(same charge as primary) = " << reflect[0] << " %" << G4endl;
0285 
0286   // compute width of the Gaussian central part of the MultipleScattering
0287   //
0288   G4cout << "\n MultipleScattering:"
0289          << "\n  rms proj angle of transmit primary particle = " << rmsMsc / mrad
0290          << " mrad (central part only)" << G4endl;
0291 
0292   G4cout << "  computed theta0 (Highland formula)          = " << ComputeMscHighland() / mrad
0293          << " mrad" << G4endl;
0294 
0295   G4cout << "  central part defined as +- " << fMscThetaCentral / mrad << " mrad; "
0296          << "  Tail ratio = " << tailMsc << " %" << G4endl;
0297 
0298   // gamma process counts
0299   //
0300   G4cout << "\n Gamma process counts:" << G4endl;
0301   G4cout << "   Photoeffect " << fTypes[0] << G4endl;
0302   G4cout << "   Compton     " << fTypes[1] << G4endl;
0303   G4cout << "   Conversion  " << fTypes[2] << G4endl;
0304   G4cout << "   Rayleigh    " << fTypes[3] << G4endl;
0305 
0306   // normalize histograms
0307   //
0308   G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0309 
0310   G4int ih = 1;
0311   G4double binWidth = analysisManager->GetH1Width(ih);
0312   G4double fac = 1. / (TotNbofEvents * binWidth);
0313   analysisManager->ScaleH1(ih, fac);
0314 
0315   ih = 10;
0316   binWidth = analysisManager->GetH1Width(ih);
0317   fac = 1. / (TotNbofEvents * binWidth);
0318   analysisManager->ScaleH1(ih, fac);
0319 
0320   ih = 12;
0321   analysisManager->ScaleH1(ih, 1. / TotNbofEvents);
0322 
0323   // reset default precision
0324   G4cout.precision(prec);
0325 }
0326 
0327 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0328 
0329 G4double Run::ComputeMscHighland()
0330 {
0331   // compute the width of the Gaussian central part of the MultipleScattering
0332   // projected angular distribution.
0333   // Eur. Phys. Jour. C15 (2000) page 166, formule 23.9
0334 
0335   G4double t =
0336     (fDetector->GetAbsorberThickness()) / (fDetector->GetAbsorberMaterial()->GetRadlen());
0337   if (t < DBL_MIN) return 0.;
0338 
0339   G4double T = fEkin;
0340   G4double M = fParticle->GetPDGMass();
0341   G4double z = std::abs(fParticle->GetPDGCharge() / eplus);
0342 
0343   G4double bpc = T * (T + 2 * M) / (T + M);
0344   G4double teta0 = 13.6 * MeV * z * std::sqrt(t) * (1. + 0.038 * std::log(t)) / bpc;
0345   return teta0;
0346 }
0347 
0348 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......