Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-28 07:50:28

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 Run.cc
0027 /// \brief Implementation of the Run class
0028 
0029 #include "Run.hh"
0030 
0031 #include "DetectorConstruction.hh"
0032 #include "EventAction.hh"
0033 #include "HistoManager.hh"
0034 #include "PrimaryGeneratorAction.hh"
0035 
0036 #include "G4Event.hh"
0037 #include "G4Material.hh"
0038 #include "G4SystemOfUnits.hh"
0039 #include "G4UnitsTable.hh"
0040 
0041 #include <iomanip>
0042 
0043 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0044 
0045 Run::Run(DetectorConstruction* detector) : fDetector(detector)
0046 {
0047   fTotEdep[1] = fEleak[1] = fEtotal[1] = joule;
0048 
0049   for (G4int i = 0; i < kMaxAbsor; ++i) {
0050     fEdeposit[i] = 0.;
0051     fEmin[i] = joule;
0052     fEmax[i] = 0.;
0053   }
0054 }
0055 
0056 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0057 
0058 void Run::SetPrimary(G4ParticleDefinition* particle, G4double energy)
0059 {
0060   fParticle = particle;
0061   fEkin = energy;
0062 }
0063 
0064 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0065 
0066 void Run::CountProcesses(const G4VProcess* process)
0067 {
0068   if (process == nullptr) return;
0069   G4String procName = process->GetProcessName();
0070   std::map<G4String, G4int>::iterator it = fProcCounter.find(procName);
0071   if (it == fProcCounter.end()) {
0072     fProcCounter[procName] = 1;
0073   }
0074   else {
0075     fProcCounter[procName]++;
0076   }
0077 }
0078 
0079 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0080 
0081 void Run::ParticleCount(G4int k, G4String name, G4double Ekin, G4double meanLife)
0082 {
0083   std::map<G4String, ParticleData>::iterator it = fParticleDataMap[k].find(name);
0084   if (it == fParticleDataMap[k].end()) {
0085     (fParticleDataMap[k])[name] = ParticleData(1, Ekin, Ekin, Ekin, meanLife);
0086   }
0087   else {
0088     ParticleData& data = it->second;
0089     data.fCount++;
0090     data.fEmean += Ekin;
0091     // update min max
0092     G4double emin = data.fEmin;
0093     if (Ekin < emin) data.fEmin = Ekin;
0094     G4double emax = data.fEmax;
0095     if (Ekin > emax) data.fEmax = Ekin;
0096     data.fTmean = meanLife;
0097   }
0098 }
0099 
0100 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0101 
0102 void Run::AddEdep(G4int i, G4double e)
0103 {
0104   if (e > 0.) {
0105     fEdeposit[i] += e;
0106     if (e < fEmin[i]) fEmin[i] = e;
0107     if (e > fEmax[i]) fEmax[i] = e;
0108   }
0109 }
0110 
0111 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0112 
0113 void Run::AddTotEdep(G4double e)
0114 {
0115   if (e > 0.) {
0116     fTotEdep[0] += e;
0117     if (e < fTotEdep[1]) fTotEdep[1] = e;
0118     if (e > fTotEdep[2]) fTotEdep[2] = e;
0119   }
0120 }
0121 
0122 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0123 
0124 void Run::AddEleak(G4double e)
0125 {
0126   if (e > 0.) {
0127     fEleak[0] += e;
0128     if (e < fEleak[1]) fEleak[1] = e;
0129     if (e > fEleak[2]) fEleak[2] = e;
0130   }
0131 }
0132 
0133 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0134 
0135 void Run::AddEtotal(G4double e)
0136 {
0137   if (e > 0.) {
0138     fEtotal[0] += e;
0139     if (e < fEtotal[1]) fEtotal[1] = e;
0140     if (e > fEtotal[2]) fEtotal[2] = e;
0141   }
0142 }
0143 
0144 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0145 
0146 void Run::AddTrackStatus(G4int i)
0147 {
0148   fStatus[i]++;
0149 }
0150 
0151 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0152 
0153 void Run::Merge(const G4Run* run)
0154 {
0155   const Run* localRun = static_cast<const Run*>(run);
0156 
0157   // pass information about primary particle
0158   fParticle = localRun->fParticle;
0159   fEkin = localRun->fEkin;
0160 
0161   // Edep in absorbers
0162   //
0163   G4int nbOfAbsor = fDetector->GetNbOfAbsor();
0164   for (G4int i = 1; i <= nbOfAbsor; ++i) {
0165     fEdeposit[i] += localRun->fEdeposit[i];
0166     // min, max
0167     G4double min, max;
0168     min = localRun->fEmin[i];
0169     max = localRun->fEmax[i];
0170     if (fEmin[i] > min) fEmin[i] = min;
0171     if (fEmax[i] < max) fEmax[i] = max;
0172   }
0173 
0174   for (G4int i = 0; i < 3; ++i)
0175     fStatus[i] += localRun->fStatus[i];
0176 
0177   // total Edep
0178   fTotEdep[0] += localRun->fTotEdep[0];
0179   G4double min, max;
0180   min = localRun->fTotEdep[1];
0181   max = localRun->fTotEdep[2];
0182   if (fTotEdep[1] > min) fTotEdep[1] = min;
0183   if (fTotEdep[2] < max) fTotEdep[2] = max;
0184 
0185   // Eleak
0186   fEleak[0] += localRun->fEleak[0];
0187   min = localRun->fEleak[1];
0188   max = localRun->fEleak[2];
0189   if (fEleak[1] > min) fEleak[1] = min;
0190   if (fEleak[2] < max) fEleak[2] = max;
0191 
0192   // Etotal
0193   fEtotal[0] += localRun->fEtotal[0];
0194   min = localRun->fEtotal[1];
0195   max = localRun->fEtotal[2];
0196   if (fEtotal[1] > min) fEtotal[1] = min;
0197   if (fEtotal[2] < max) fEtotal[2] = max;
0198 
0199   // map: processes count
0200   std::map<G4String, G4int>::const_iterator itp;
0201   for (itp = localRun->fProcCounter.begin(); itp != localRun->fProcCounter.end(); ++itp) {
0202     G4String procName = itp->first;
0203     G4int localCount = itp->second;
0204     if (fProcCounter.find(procName) == fProcCounter.end()) {
0205       fProcCounter[procName] = localCount;
0206     }
0207     else {
0208       fProcCounter[procName] += localCount;
0209     }
0210   }
0211 
0212   // map: created particles in absorbers count
0213   for (G4int k = 0; k <= nbOfAbsor; ++k) {
0214     std::map<G4String, ParticleData>::const_iterator itc;
0215     for (itc = localRun->fParticleDataMap[k].begin(); itc != localRun->fParticleDataMap[k].end();
0216          ++itc)
0217     {
0218       G4String name = itc->first;
0219       const ParticleData& localData = itc->second;
0220       if (fParticleDataMap[k].find(name) == fParticleDataMap[k].end()) {
0221         (fParticleDataMap[k])[name] = ParticleData(
0222           localData.fCount, localData.fEmean, localData.fEmin, localData.fEmax, localData.fTmean);
0223       }
0224       else {
0225         ParticleData& data = (fParticleDataMap[k])[name];
0226         data.fCount += localData.fCount;
0227         data.fEmean += localData.fEmean;
0228         G4double emin = localData.fEmin;
0229         if (emin < data.fEmin) data.fEmin = emin;
0230         G4double emax = localData.fEmax;
0231         if (emax > data.fEmax) data.fEmax = emax;
0232         data.fTmean = localData.fTmean;
0233       }
0234     }
0235   }
0236 
0237   G4Run::Merge(run);
0238 }
0239 
0240 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0241 
0242 void Run::EndOfRun()
0243 {
0244   G4int prec = 5, wid = prec + 2;
0245   G4int dfprec = G4cout.precision(prec);
0246 
0247   // run conditions
0248   //
0249   G4String partName = fParticle->GetParticleName();
0250   G4int nbOfAbsor = fDetector->GetNbOfAbsor();
0251 
0252   G4cout << "\n ======================== run summary =====================\n";
0253   G4cout << "\n The run is " << numberOfEvent << " " << partName << " of "
0254          << G4BestUnit(fEkin, "Energy") << " through " << nbOfAbsor << " absorbers: \n";
0255   for (G4int i = 1; i <= nbOfAbsor; i++) {
0256     G4Material* material = fDetector->GetAbsorMaterial(i);
0257     G4double thickness = fDetector->GetAbsorThickness(i);
0258     G4double density = material->GetDensity();
0259     G4cout << std::setw(5) << i << std::setw(10) << G4BestUnit(thickness, "Length") << " of "
0260            << material->GetName() << " (density: " << G4BestUnit(density, "Volumic Mass") << ")"
0261            << G4endl;
0262   }
0263 
0264   if (numberOfEvent == 0) {
0265     G4cout.precision(dfprec);
0266     return;
0267   }
0268 
0269   G4cout.precision(3);
0270 
0271   // frequency of processes
0272   //
0273   G4cout << "\n Process calls frequency :" << G4endl;
0274   G4int index = 0;
0275   std::map<G4String, G4int>::iterator it;
0276   for (it = fProcCounter.begin(); it != fProcCounter.end(); it++) {
0277     G4String procName = it->first;
0278     G4int count = it->second;
0279     G4String space = " ";
0280     if (++index % 3 == 0) space = "\n";
0281     G4cout << " " << std::setw(20) << procName << "=" << std::setw(7) << count << space;
0282   }
0283   G4cout << G4endl;
0284 
0285   // Edep in absorbers
0286   //
0287   for (G4int i = 1; i <= nbOfAbsor; i++) {
0288     fEdeposit[i] /= numberOfEvent;
0289 
0290     G4cout << "\n Edep in absorber " << i << " = " << G4BestUnit(fEdeposit[i], "Energy") << "\t("
0291            << G4BestUnit(fEmin[i], "Energy") << "-->" << G4BestUnit(fEmax[i], "Energy") << ")";
0292   }
0293   G4cout << G4endl;
0294 
0295   if (nbOfAbsor > 1) {
0296     fTotEdep[0] /= numberOfEvent;
0297     G4cout << "\n Edep in all absorb = " << G4BestUnit(fTotEdep[0], "Energy") << "\t("
0298            << G4BestUnit(fTotEdep[1], "Energy") << "-->" << G4BestUnit(fTotEdep[2], "Energy") << ")"
0299            << G4endl;
0300   }
0301 
0302   // Eleak
0303   //
0304   fEleak[0] /= numberOfEvent;
0305   G4cout << " Energy leakage     = " << G4BestUnit(fEleak[0], "Energy") << "\t("
0306          << G4BestUnit(fEleak[1], "Energy") << "-->" << G4BestUnit(fEleak[2], "Energy") << ")"
0307          << G4endl;
0308 
0309   // Etotal
0310   //
0311   fEtotal[0] /= numberOfEvent;
0312   G4cout << " Energy total       = " << G4BestUnit(fEtotal[0], "Energy") << "\t("
0313          << G4BestUnit(fEtotal[1], "Energy") << "-->" << G4BestUnit(fEtotal[2], "Energy") << ")"
0314          << G4endl;
0315 
0316   // particles count in absorbers
0317   //
0318   for (G4int k = 1; k <= nbOfAbsor; k++) {
0319     G4cout << "\n List of created particles in absorber " << k << ":" << G4endl;
0320 
0321     std::map<G4String, ParticleData>::iterator itc;
0322     for (itc = fParticleDataMap[k].begin(); itc != fParticleDataMap[k].end(); itc++) {
0323       G4String name = itc->first;
0324       ParticleData data = itc->second;
0325       G4int count = data.fCount;
0326       G4double eMean = data.fEmean / count;
0327       G4double eMin = data.fEmin;
0328       G4double eMax = data.fEmax;
0329       G4double meanLife = data.fTmean;
0330 
0331       G4cout << "  " << std::setw(13) << name << ": " << std::setw(7) << count
0332              << "  Emean = " << std::setw(wid) << G4BestUnit(eMean, "Energy") << "\t( "
0333              << G4BestUnit(eMin, "Energy") << " --> " << G4BestUnit(eMax, "Energy") << ")";
0334       if (meanLife >= 0.)
0335         G4cout << "\tmean life = " << G4BestUnit(meanLife, "Time") << G4endl;
0336       else
0337         G4cout << "\tstable" << G4endl;
0338     }
0339   }
0340   // particles emerging from absorbers
0341   //
0342   G4cout << "\n List of particles emerging from absorbers :" << G4endl;
0343 
0344   std::map<G4String, ParticleData>::iterator itc;
0345   for (itc = fParticleDataMap[0].begin(); itc != fParticleDataMap[0].end(); itc++) {
0346     G4String name = itc->first;
0347     ParticleData data = itc->second;
0348     G4int count = data.fCount;
0349     G4double eMean = data.fEmean / count;
0350     G4double eMin = data.fEmin;
0351     G4double eMax = data.fEmax;
0352     /// G4double meanLife = data.fTmean;
0353 
0354     G4cout << "  " << std::setw(13) << name << ": " << std::setw(7) << count
0355            << "  Emean = " << std::setw(wid) << G4BestUnit(eMean, "Energy") << "\t( "
0356            << G4BestUnit(eMin, "Energy") << " --> " << G4BestUnit(eMax, "Energy") << ")" << G4endl;
0357   }
0358 
0359   // transmission coefficients
0360   //
0361   G4double dNofEvents = double(numberOfEvent);
0362   G4double absorbed = 100. * fStatus[0] / dNofEvents;
0363   G4double transmit = 100. * fStatus[1] / dNofEvents;
0364   G4double reflected = 100. * fStatus[2] / dNofEvents;
0365 
0366   G4cout.precision(2);
0367   G4cout << "\n Nb of events with primary absorbed = " << absorbed << " %,"
0368          << "   transmit = " << transmit << " %,"
0369          << "   reflected = " << reflected << " %" << G4endl;
0370 
0371   // normalize histograms of longitudinal energy profile
0372   //
0373   G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0374   G4int ih = 10;
0375   G4double binWidth = analysisManager->GetH1Width(ih) * analysisManager->GetH1Unit(ih);
0376   G4double fac = (1. / (numberOfEvent * binWidth)) * (mm / MeV);
0377   analysisManager->ScaleH1(ih, fac);
0378 
0379   // remove all contents in fProcCounter, fCount
0380   fProcCounter.clear();
0381   for (G4int k = 0; k <= nbOfAbsor; k++)
0382     fParticleDataMap[k].clear();
0383 
0384   // reset default formats
0385   G4cout.precision(dfprec);
0386 }
0387 
0388 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......