Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-03 07:56:51

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 "HistoManager.hh"
0032 #include "PrimaryGeneratorAction.hh"
0033 
0034 #include "G4PhysicalConstants.hh"
0035 #include "G4SystemOfUnits.hh"
0036 #include "G4UnitsTable.hh"
0037 
0038 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0039 
0040 void Run::SetPrimary(G4ParticleDefinition* particle, G4double energy)
0041 {
0042   fParticle = particle;
0043   fEkin = energy;
0044 }
0045 
0046 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0047 
0048 void Run::ParticleCount(G4String name, G4double Ekin, G4double meanLife)
0049 {
0050   std::map<G4String, ParticleData>::iterator it = fParticleDataMap.find(name);
0051   if (it == fParticleDataMap.end()) {
0052     fParticleDataMap[name] = ParticleData(1, Ekin, Ekin, Ekin, meanLife);
0053   }
0054   else {
0055     ParticleData& data = it->second;
0056     data.fCount++;
0057     data.fEmean += Ekin;
0058     // update min max
0059     G4double emin = data.fEmin;
0060     if (Ekin < emin) data.fEmin = Ekin;
0061     G4double emax = data.fEmax;
0062     if (Ekin > emax) data.fEmax = Ekin;
0063     data.fTmean = meanLife;
0064   }
0065 }
0066 
0067 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0068 
0069 void Run::SetTimeWindow(G4double t1, G4double t2)
0070 {
0071   fTimeWindow1 = t1;
0072   fTimeWindow2 = t2;
0073 }
0074 
0075 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0076 
0077 void Run::CountInTimeWindow(G4String name, G4bool life1, G4bool life2, G4bool decay)
0078 {
0079   std::map<G4String, ActivityData>::iterator it = fActivityMap.find(name);
0080   if (it == fActivityMap.end()) {
0081     G4int n1(0), n2(0), nd(0);
0082     if (life1) n1 = 1;
0083     if (life2) n2 = 1;
0084     if (decay) nd = 1;
0085     fActivityMap[name] = ActivityData(n1, n2, nd);
0086   }
0087   else {
0088     ActivityData& data = it->second;
0089     if (life1) data.fNlife_t1++;
0090     if (life2) data.fNlife_t2++;
0091     if (decay) data.fNdecay_t1t2++;
0092   }
0093 }
0094 
0095 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0096 
0097 void Run::Balance(G4double Ekin, G4double Pbal)
0098 {
0099   fDecayCount++;
0100   fEkinTot[0] += Ekin;
0101   // update min max
0102   if (fDecayCount == 1) fEkinTot[1] = fEkinTot[2] = Ekin;
0103   if (Ekin < fEkinTot[1]) fEkinTot[1] = Ekin;
0104   if (Ekin > fEkinTot[2]) fEkinTot[2] = Ekin;
0105 
0106   fPbalance[0] += Pbal;
0107   // update min max
0108   if (fDecayCount == 1) fPbalance[1] = fPbalance[2] = Pbal;
0109   if (Pbal < fPbalance[1]) fPbalance[1] = Pbal;
0110   if (Pbal > fPbalance[2]) fPbalance[2] = Pbal;
0111 }
0112 
0113 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0114 
0115 void Run::EventTiming(G4double time)
0116 {
0117   fTimeCount++;
0118   fEventTime[0] += time;
0119   if (fTimeCount == 1) fEventTime[1] = fEventTime[2] = time;
0120   if (time < fEventTime[1]) fEventTime[1] = time;
0121   if (time > fEventTime[2]) fEventTime[2] = time;
0122 }
0123 
0124 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0125 
0126 void Run::PrimaryTiming(G4double ptime)
0127 {
0128   fPrimaryTime += ptime;
0129 }
0130 
0131 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0132 
0133 void Run::EvisEvent(G4double Evis)
0134 {
0135   fEvisEvent[0] += Evis;
0136   if (fTimeCount == 1) fEvisEvent[1] = fEvisEvent[2] = Evis;
0137   if (Evis < fEvisEvent[1]) fEvisEvent[1] = Evis;
0138   if (Evis > fEvisEvent[2]) fEvisEvent[2] = Evis;
0139 }
0140 
0141 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0142 
0143 void Run::Merge(const G4Run* run)
0144 {
0145   const Run* localRun = static_cast<const Run*>(run);
0146 
0147   // primary particle info
0148   //
0149   fParticle = localRun->fParticle;
0150   fEkin = localRun->fEkin;
0151 
0152   // accumulate sums
0153   //
0154   fDecayCount += localRun->fDecayCount;
0155   fTimeCount += localRun->fTimeCount;
0156   fPrimaryTime += localRun->fPrimaryTime;
0157 
0158   fEkinTot[0] += localRun->fEkinTot[0];
0159   fPbalance[0] += localRun->fPbalance[0];
0160   fEventTime[0] += localRun->fEventTime[0];
0161   fEvisEvent[0] += localRun->fEvisEvent[0];
0162 
0163   G4double min, max;
0164   min = localRun->fEkinTot[1];
0165   max = localRun->fEkinTot[2];
0166   if (fEkinTot[1] > min) fEkinTot[1] = min;
0167   if (fEkinTot[2] < max) fEkinTot[2] = max;
0168   //
0169   min = localRun->fPbalance[1];
0170   max = localRun->fPbalance[2];
0171   if (fPbalance[1] > min) fPbalance[1] = min;
0172   if (fPbalance[2] < max) fPbalance[2] = max;
0173   //
0174   min = localRun->fEventTime[1];
0175   max = localRun->fEventTime[2];
0176   if (fEventTime[1] > min) fEventTime[1] = min;
0177   if (fEventTime[2] < max) fEventTime[2] = max;
0178   //
0179   min = localRun->fEvisEvent[1];
0180   max = localRun->fEvisEvent[2];
0181   if (fEvisEvent[1] > min) fEvisEvent[1] = min;
0182   if (fEvisEvent[2] < max) fEvisEvent[2] = max;
0183 
0184   // maps
0185   std::map<G4String, ParticleData>::const_iterator itn;
0186   for (itn = localRun->fParticleDataMap.begin(); itn != localRun->fParticleDataMap.end(); ++itn) {
0187     G4String name = itn->first;
0188     const ParticleData& localData = itn->second;
0189     if (fParticleDataMap.find(name) == fParticleDataMap.end()) {
0190       fParticleDataMap[name] = ParticleData(localData.fCount, localData.fEmean, localData.fEmin,
0191                                             localData.fEmax, localData.fTmean);
0192     }
0193     else {
0194       ParticleData& data = fParticleDataMap[name];
0195       data.fCount += localData.fCount;
0196       data.fEmean += localData.fEmean;
0197       G4double emin = localData.fEmin;
0198       if (emin < data.fEmin) data.fEmin = emin;
0199       G4double emax = localData.fEmax;
0200       if (emax > data.fEmax) data.fEmax = emax;
0201       data.fTmean = localData.fTmean;
0202     }
0203   }
0204 
0205   // activity
0206   fTimeWindow1 = localRun->fTimeWindow1;
0207   fTimeWindow2 = localRun->fTimeWindow2;
0208 
0209   std::map<G4String, ActivityData>::const_iterator ita;
0210   for (ita = localRun->fActivityMap.begin(); ita != localRun->fActivityMap.end(); ++ita) {
0211     G4String name = ita->first;
0212     const ActivityData& localData = ita->second;
0213     if (fActivityMap.find(name) == fActivityMap.end()) {
0214       fActivityMap[name] =
0215         ActivityData(localData.fNlife_t1, localData.fNlife_t2, localData.fNdecay_t1t2);
0216     }
0217     else {
0218       ActivityData& data = fActivityMap[name];
0219       data.fNlife_t1 += localData.fNlife_t1;
0220       data.fNlife_t2 += localData.fNlife_t2;
0221       data.fNdecay_t1t2 += localData.fNdecay_t1t2;
0222     }
0223   }
0224 
0225   G4Run::Merge(run);
0226 }
0227 
0228 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0229 
0230 void Run::EndOfRun()
0231 {
0232   G4int nbEvents = numberOfEvent;
0233   G4String partName = fParticle->GetParticleName();
0234 
0235   G4cout << "\n ======================== run summary ======================";
0236   G4cout << "\n The run was " << nbEvents << " " << partName << " of "
0237          << G4BestUnit(fEkin, "Energy");
0238   G4cout << "\n ===========================================================\n";
0239   G4cout << G4endl;
0240   if (nbEvents == 0) {
0241     return;
0242   }
0243 
0244   G4int prec = 4, wid = prec + 2;
0245   G4int dfprec = G4cout.precision(prec);
0246 
0247   // particle count
0248   //
0249   G4cout << " Nb of generated particles: \n" << G4endl;
0250 
0251   std::map<G4String, ParticleData>::iterator it;
0252   for (it = fParticleDataMap.begin(); it != fParticleDataMap.end(); it++) {
0253     G4String name = it->first;
0254     ParticleData data = it->second;
0255     G4int count = data.fCount;
0256     G4double eMean = data.fEmean / count;
0257     G4double eMin = data.fEmin;
0258     G4double eMax = data.fEmax;
0259     G4double meanLife = data.fTmean;
0260 
0261     G4cout << "  " << std::setw(15) << name << ": " << std::setw(7) << count
0262            << "  Emean = " << std::setw(wid) << G4BestUnit(eMean, "Energy") << "\t( "
0263            << G4BestUnit(eMin, "Energy") << " --> " << G4BestUnit(eMax, "Energy") << ")";
0264     if (meanLife > 0.)
0265       G4cout << "\tmean life = " << G4BestUnit(meanLife, "Time") << G4endl;
0266     else if (meanLife < 0.)
0267       G4cout << "\tstable" << G4endl;
0268     else
0269       G4cout << G4endl;
0270   }
0271 
0272   // energy momentum balance
0273   //
0274 
0275   if (fDecayCount > 0) {
0276     G4double Ebmean = fEkinTot[0] / fDecayCount;
0277     G4double Pbmean = fPbalance[0] / fDecayCount;
0278 
0279     G4cout << "\n   Ekin Total (Q single decay): mean = " << std::setw(wid)
0280            << G4BestUnit(Ebmean, "Energy") << "\t( " << G4BestUnit(fEkinTot[1], "Energy") << " --> "
0281            << G4BestUnit(fEkinTot[2], "Energy") << ")" << G4endl;
0282 
0283     G4cout << "\n   Momentum balance (excluding gamma desexcitation): mean = " << std::setw(wid)
0284            << G4BestUnit(Pbmean, "Energy") << "\t( " << G4BestUnit(fPbalance[1], "Energy")
0285            << " --> " << G4BestUnit(fPbalance[2], "Energy") << ")" << G4endl;
0286   }
0287 
0288   // total time of life
0289   //
0290   if (fTimeCount > 0) {
0291     G4double Tmean = fEventTime[0] / fTimeCount;
0292     G4double halfLife = Tmean * std::log(2.);
0293 
0294     G4cout << "\n   Total time of life (full chain): mean = " << std::setw(wid)
0295            << G4BestUnit(Tmean, "Time") << "  half-life = " << std::setw(wid)
0296            << G4BestUnit(halfLife, "Time") << "   ( " << G4BestUnit(fEventTime[1], "Time")
0297            << " --> " << G4BestUnit(fEventTime[2], "Time") << ")" << G4endl;
0298   }
0299 
0300   // total visible Energy
0301   //
0302   if (fTimeCount > 0) {
0303     G4double Evmean = fEvisEvent[0] / fTimeCount;
0304 
0305     G4cout << "\n   Total visible energy (full chain) : mean = " << std::setw(wid)
0306            << G4BestUnit(Evmean, "Energy") << "   ( " << G4BestUnit(fEvisEvent[1], "Energy")
0307            << " --> " << G4BestUnit(fEvisEvent[2], "Energy") << ")" << G4endl;
0308   }
0309 
0310   // activity of primary ion
0311   //
0312   G4double pTimeMean = fPrimaryTime / nbEvents;
0313   G4double molMass = fParticle->GetAtomicMass() * g / mole;
0314   G4double nAtoms_perUnitOfMass = Avogadro / molMass;
0315   G4double Activity_perUnitOfMass = 0.0;
0316   if (pTimeMean > 0.0) {
0317     Activity_perUnitOfMass = nAtoms_perUnitOfMass / pTimeMean;
0318   }
0319 
0320   G4cout << "\n   Activity of " << partName << " = " << std::setw(wid)
0321          << Activity_perUnitOfMass * g / becquerel << " Bq/g   ("
0322          << Activity_perUnitOfMass * g / curie << " Ci/g) \n"
0323          << G4endl;
0324 
0325   // activities in time window
0326   //
0327   if (fTimeWindow2 > 0.) {
0328     G4double dt = fTimeWindow2 - fTimeWindow1;
0329     G4cout << "   Activities in time window [t1, t2] = [" << G4BestUnit(fTimeWindow1, "Time")
0330            << ", " << G4BestUnit(fTimeWindow2, "Time")
0331            << "]  (delta time = " << G4BestUnit(dt, "Time") << ") : \n"
0332            << G4endl;
0333 
0334     std::map<G4String, ActivityData>::iterator ita;
0335     for (ita = fActivityMap.begin(); ita != fActivityMap.end(); ita++) {
0336       G4String name = ita->first;
0337       ActivityData data = ita->second;
0338       G4int n1 = data.fNlife_t1;
0339       G4int n2 = data.fNlife_t2;
0340       G4int ndecay = data.fNdecay_t1t2;
0341       G4double actv = ndecay / dt;
0342 
0343       G4cout << "  " << std::setw(15) << name << ": "
0344              << "  n(t1) = " << std::setw(7) << n1 << "\tn(t2) = " << std::setw(7) << n2
0345              << "\t   decays = " << std::setw(7) << ndecay
0346              << "   ---> <actv> = " << G4BestUnit(actv, "Activity") << "\n";
0347     }
0348   }
0349   G4cout << G4endl;
0350 
0351   // normalize histograms
0352   //
0353   G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0354   G4double factor = 100. / nbEvents;
0355   analysisManager->ScaleH1(1, factor);
0356   analysisManager->ScaleH1(2, factor);
0357   analysisManager->ScaleH1(3, factor);
0358   analysisManager->ScaleH1(4, factor);
0359   analysisManager->ScaleH1(5, factor);
0360 
0361   // remove all contents in fParticleDataMap
0362   //
0363   fParticleDataMap.clear();
0364   fActivityMap.clear();
0365 
0366   // restore default precision
0367   //
0368   G4cout.precision(dfprec);
0369 }
0370 
0371 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......