File indexing completed on 2026-09-14 08:28:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "Run.hh"
0030
0031 #include "DetectorConstruction.hh"
0032 #include "HistoManager.hh"
0033 #include "PrimaryGeneratorAction.hh"
0034
0035 #include "G4SystemOfUnits.hh"
0036 #include "G4UnitsTable.hh"
0037
0038
0039
0040 Run::Run(DetectorConstruction* det) : fDetector(det) {}
0041
0042
0043
0044 void Run::SetPrimary(G4ParticleDefinition* particle, G4double energy)
0045 {
0046 fParticle = particle;
0047 fEkin = energy;
0048 }
0049
0050
0051
0052 void Run::CountProcesses(const G4VProcess* process)
0053 {
0054 if (process == nullptr) return;
0055 G4String procName = process->GetProcessName();
0056 std::map<G4String, G4int>::iterator it = fProcCounter.find(procName);
0057 if (it == fProcCounter.end()) {
0058 fProcCounter[procName] = 1;
0059 }
0060 else {
0061 fProcCounter[procName]++;
0062 }
0063 }
0064
0065
0066
0067 void Run::ParticleCount(G4String name, G4double Ekin, G4double meanLife)
0068 {
0069 std::map<G4String, ParticleData>::iterator it = fParticleDataMap1.find(name);
0070 if (it == fParticleDataMap1.end()) {
0071 fParticleDataMap1[name] = ParticleData(1, Ekin, Ekin, Ekin, meanLife);
0072 }
0073 else {
0074 ParticleData& data = it->second;
0075 data.fCount++;
0076 data.fEmean += Ekin;
0077
0078 G4double emin = data.fEmin;
0079 if (Ekin < emin) data.fEmin = Ekin;
0080 G4double emax = data.fEmax;
0081 if (Ekin > emax) data.fEmax = Ekin;
0082 data.fTmean = meanLife;
0083 }
0084 }
0085
0086
0087
0088 void Run::AddEdep(G4double edep)
0089 {
0090 fEnergyDeposit += edep;
0091 fEnergyDeposit2 += edep * edep;
0092 }
0093
0094
0095
0096 void Run::AddEflow(G4double eflow)
0097 {
0098 fEnergyFlow += eflow;
0099 fEnergyFlow2 += eflow * eflow;
0100 }
0101
0102
0103 void Run::ParticleFlux(G4String name, G4double Ekin)
0104 {
0105 std::map<G4String, ParticleData>::iterator it = fParticleDataMap2.find(name);
0106 if (it == fParticleDataMap2.end()) {
0107 fParticleDataMap2[name] = ParticleData(1, Ekin, Ekin, Ekin, -1 * ns);
0108 }
0109 else {
0110 ParticleData& data = it->second;
0111 data.fCount++;
0112 data.fEmean += Ekin;
0113
0114 G4double emin = data.fEmin;
0115 if (Ekin < emin) data.fEmin = Ekin;
0116 G4double emax = data.fEmax;
0117 if (Ekin > emax) data.fEmax = Ekin;
0118 data.fTmean = -1 * ns;
0119 }
0120 }
0121
0122
0123
0124 void Run::Merge(const G4Run* run)
0125 {
0126 const Run* localRun = static_cast<const Run*>(run);
0127
0128
0129
0130 fParticle = localRun->fParticle;
0131 fEkin = localRun->fEkin;
0132
0133
0134
0135 fEnergyDeposit += localRun->fEnergyDeposit;
0136 fEnergyDeposit2 += localRun->fEnergyDeposit2;
0137 fEnergyFlow += localRun->fEnergyFlow;
0138 fEnergyFlow2 += localRun->fEnergyFlow2;
0139
0140
0141 std::map<G4String, G4int>::const_iterator itp;
0142 for (itp = localRun->fProcCounter.begin(); itp != localRun->fProcCounter.end(); ++itp) {
0143 G4String procName = itp->first;
0144 G4int localCount = itp->second;
0145 if (fProcCounter.find(procName) == fProcCounter.end()) {
0146 fProcCounter[procName] = localCount;
0147 }
0148 else {
0149 fProcCounter[procName] += localCount;
0150 }
0151 }
0152
0153
0154 std::map<G4String, ParticleData>::const_iterator itc;
0155 for (itc = localRun->fParticleDataMap1.begin(); itc != localRun->fParticleDataMap1.end(); ++itc) {
0156 G4String name = itc->first;
0157 const ParticleData& localData = itc->second;
0158 if (fParticleDataMap1.find(name) == fParticleDataMap1.end()) {
0159 fParticleDataMap1[name] = ParticleData(localData.fCount, localData.fEmean, localData.fEmin,
0160 localData.fEmax, localData.fTmean);
0161 }
0162 else {
0163 ParticleData& data = fParticleDataMap1[name];
0164 data.fCount += localData.fCount;
0165 data.fEmean += localData.fEmean;
0166 G4double emin = localData.fEmin;
0167 if (emin < data.fEmin) data.fEmin = emin;
0168 G4double emax = localData.fEmax;
0169 if (emax > data.fEmax) data.fEmax = emax;
0170 data.fTmean = localData.fTmean;
0171 }
0172 }
0173
0174
0175 std::map<G4String, ParticleData>::const_iterator itn;
0176 for (itn = localRun->fParticleDataMap2.begin(); itn != localRun->fParticleDataMap2.end(); ++itn) {
0177 G4String name = itn->first;
0178 const ParticleData& localData = itn->second;
0179 if (fParticleDataMap2.find(name) == fParticleDataMap2.end()) {
0180 fParticleDataMap2[name] = ParticleData(localData.fCount, localData.fEmean, localData.fEmin,
0181 localData.fEmax, localData.fTmean);
0182 }
0183 else {
0184 ParticleData& data = fParticleDataMap2[name];
0185 data.fCount += localData.fCount;
0186 data.fEmean += localData.fEmean;
0187 G4double emin = localData.fEmin;
0188 if (emin < data.fEmin) data.fEmin = emin;
0189 G4double emax = localData.fEmax;
0190 if (emax > data.fEmax) data.fEmax = emax;
0191 data.fTmean = localData.fTmean;
0192 }
0193 }
0194
0195 G4Run::Merge(run);
0196 }
0197
0198
0199
0200 void Run::EndOfRun()
0201 {
0202 G4int prec = 5, wid = prec + 2;
0203 G4int dfprec = G4cout.precision(prec);
0204
0205
0206
0207 G4Material* material = fDetector->GetAbsorMaterial();
0208 G4String Particle = fParticle->GetParticleName();
0209 G4cout << "\n The run is " << numberOfEvent << " " << Particle << " of "
0210 << G4BestUnit(fEkin, "Energy") << " within " << material->GetName()
0211 << " (D = " << G4BestUnit(2 * (fDetector->GetAbsorRadius()), "Length")
0212 << " L = " << G4BestUnit(fDetector->GetAbsorLength(), "Length") << ")" << G4endl;
0213
0214 if (numberOfEvent == 0) {
0215 G4cout.precision(dfprec);
0216 return;
0217 }
0218
0219
0220
0221 G4cout << "\n Process calls frequency :" << G4endl;
0222 G4int index = 0;
0223 std::map<G4String, G4int>::iterator it;
0224 for (it = fProcCounter.begin(); it != fProcCounter.end(); it++) {
0225 G4String procName = it->first;
0226 G4int count = it->second;
0227 G4String space = " ";
0228 if (++index % 3 == 0) space = "\n";
0229 G4cout << " " << std::setw(20) << procName << "=" << std::setw(7) << count << space;
0230 }
0231 G4cout << G4endl;
0232
0233
0234
0235 G4cout << "\n List of generated particles (with meanLife != 0) :" << G4endl;
0236
0237 std::map<G4String, ParticleData>::iterator itc;
0238 for (itc = fParticleDataMap1.begin(); itc != fParticleDataMap1.end(); itc++) {
0239 G4String name = itc->first;
0240 ParticleData data = itc->second;
0241 G4int count = data.fCount;
0242 G4double eMean = data.fEmean / count;
0243 G4double eMin = data.fEmin;
0244 G4double eMax = data.fEmax;
0245 G4double meanLife = data.fTmean;
0246
0247 G4cout << " " << std::setw(13) << name << ": " << std::setw(7) << count
0248 << " Emean = " << std::setw(wid) << G4BestUnit(eMean, "Energy") << "\t( "
0249 << G4BestUnit(eMin, "Energy") << " --> " << G4BestUnit(eMax, "Energy") << ")";
0250 if (meanLife >= 0.)
0251 G4cout << "\tmean life = " << G4BestUnit(meanLife, "Time") << G4endl;
0252 else
0253 G4cout << "\tstable" << G4endl;
0254 }
0255
0256
0257
0258 G4int TotNbofEvents = numberOfEvent;
0259 fEnergyDeposit /= TotNbofEvents;
0260 fEnergyDeposit2 /= TotNbofEvents;
0261 G4double rmsEdep = fEnergyDeposit2 - fEnergyDeposit * fEnergyDeposit;
0262 if (rmsEdep > 0.)
0263 rmsEdep = std::sqrt(rmsEdep);
0264 else
0265 rmsEdep = 0.;
0266
0267 G4cout << "\n Mean energy deposit per event = " << G4BestUnit(fEnergyDeposit, "Energy")
0268 << "; rms = " << G4BestUnit(rmsEdep, "Energy") << G4endl;
0269
0270
0271
0272 fEnergyFlow /= TotNbofEvents;
0273 fEnergyFlow2 /= TotNbofEvents;
0274 G4double rmsEflow = fEnergyFlow2 - fEnergyFlow * fEnergyFlow;
0275 if (rmsEflow > 0.)
0276 rmsEflow = std::sqrt(rmsEflow);
0277 else
0278 rmsEflow = 0.;
0279
0280 G4cout << " Mean energy flow per event = " << G4BestUnit(fEnergyFlow, "Energy")
0281 << "; rms = " << G4BestUnit(rmsEflow, "Energy") << G4endl;
0282
0283
0284
0285 G4cout << "\n List of particles emerging from the container :" << G4endl;
0286
0287 std::map<G4String, ParticleData>::iterator itn;
0288 for (itn = fParticleDataMap2.begin(); itn != fParticleDataMap2.end(); itn++) {
0289 G4String name = itn->first;
0290 ParticleData data = itn->second;
0291 G4int count = data.fCount;
0292 G4double eMean = data.fEmean / count;
0293 G4double eMin = data.fEmin;
0294 G4double eMax = data.fEmax;
0295 G4double Eflow = data.fEmean / TotNbofEvents;
0296
0297 G4cout << " " << std::setw(13) << name << ": " << std::setw(7) << count
0298 << " Emean = " << std::setw(wid) << G4BestUnit(eMean, "Energy") << "\t( "
0299 << G4BestUnit(eMin, "Energy") << " --> " << G4BestUnit(eMax, "Energy")
0300 << ") \tEflow/event = " << G4BestUnit(Eflow, "Energy") << G4endl;
0301 }
0302
0303
0304 fProcCounter.clear();
0305 fParticleDataMap2.clear();
0306
0307
0308 G4cout.precision(dfprec);
0309 }
0310
0311