File indexing completed on 2025-02-23 09:22: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
0030
0031
0032
0033 #include "Run.hh"
0034
0035 #include "DetectorConstruction.hh"
0036 #include "HistoManager.hh"
0037 #include "PrimaryGeneratorAction.hh"
0038
0039 #include "G4Electron.hh"
0040 #include "G4EmCalculator.hh"
0041 #include "G4Run.hh"
0042 #include "G4RunManager.hh"
0043 #include "G4SystemOfUnits.hh"
0044 #include "G4UnitsTable.hh"
0045 #include "Randomize.hh"
0046
0047 #include <iomanip>
0048
0049
0050
0051 Run::Run(DetectorConstruction* det, PrimaryGeneratorAction* kin, bool isMaster)
0052 : G4Run(),
0053 fDetector(det),
0054 fKinematic(kin),
0055 fProcCounter(0),
0056 fEdepCavity(0.),
0057 fEdepCavity2(0.),
0058 fTrkSegmCavity(0.),
0059 fNbEventCavity(0),
0060 fStepWall(0.),
0061 fStepWall2(0.),
0062 fStepCavity(0.),
0063 fStepCavity2(0.),
0064 fNbStepWall(0),
0065 fNbStepCavity(0),
0066 fEnergyGun(0.),
0067 fMassWall(0.),
0068 fMassCavity(0.),
0069 fIsMaster(isMaster)
0070 {
0071
0072
0073 G4ParticleDefinition* particleGun = fKinematic->GetParticleGun()->GetParticleDefinition();
0074 G4String partName = particleGun->GetParticleName();
0075 fEnergyGun = fKinematic->GetParticleGun()->GetParticleEnergy();
0076
0077
0078
0079 G4double cavityThickness = fDetector->GetCavityThickness();
0080 G4Material* mateCavity = fDetector->GetCavityMaterial();
0081 G4double densityCavity = mateCavity->GetDensity();
0082 fMassCavity = cavityThickness * densityCavity;
0083
0084 G4double wallThickness = fDetector->GetWallThickness();
0085 G4Material* mateWall = fDetector->GetWallMaterial();
0086 G4double densityWall = mateWall->GetDensity();
0087
0088 G4EmCalculator emCal;
0089 G4double RangeWall = emCal.GetCSDARange(fEnergyGun, particleGun, mateWall);
0090 G4double factor = 1.2;
0091 G4double effWallThick = factor * RangeWall;
0092 if ((effWallThick > wallThickness) || (effWallThick <= 0.)) effWallThick = wallThickness;
0093 fMassWall = 2 * effWallThick * densityWall;
0094
0095 G4double massTotal = fMassWall + fMassCavity;
0096 G4double fMassWallRatio = fMassWall / massTotal;
0097 fKinematic->RunInitialisation(effWallThick, fMassWallRatio);
0098
0099 G4double massRatio = fMassCavity / fMassWall;
0100
0101
0102
0103 G4double worldRadius = fDetector->GetWallRadius();
0104 G4double RangeCavity = emCal.GetCSDARange(fEnergyGun, particleGun, mateCavity);
0105
0106
0107
0108 std::ios::fmtflags mode = G4cout.flags();
0109 G4cout.setf(std::ios::fixed, std::ios::floatfield);
0110 G4int prec = G4cout.precision(3);
0111
0112 G4cout << "\n ===================== run conditions =====================\n";
0113
0114 G4cout << "\n The run will be " << numberOfEvent << " " << partName << " of "
0115 << G4BestUnit(fEnergyGun, "Energy") << " through 2*" << G4BestUnit(effWallThick, "Length")
0116 << " of " << mateWall->GetName()
0117 << " (density: " << G4BestUnit(densityWall, "Volumic Mass")
0118 << "); Mass/cm2 = " << G4BestUnit(fMassWall * cm2, "Mass")
0119 << "\n csdaRange: " << G4BestUnit(RangeWall, "Length") << G4endl;
0120
0121 G4cout << "\n the cavity is " << G4BestUnit(cavityThickness, "Length") << " of "
0122 << mateCavity->GetName() << " (density: " << G4BestUnit(densityCavity, "Volumic Mass")
0123 << "); Mass/cm2 = " << G4BestUnit(fMassCavity * cm2, "Mass")
0124 << " --> massRatio = " << std::setprecision(6) << massRatio << G4endl;
0125
0126 G4cout.precision(3);
0127 G4cout << " Wall radius: " << G4BestUnit(worldRadius, "Length")
0128 << "; range in cavity: " << G4BestUnit(RangeCavity, "Length") << G4endl;
0129
0130 G4cout << "\n ==========================================================\n";
0131
0132
0133
0134 G4double dedxWall = emCal.GetDEDX(fEnergyGun, G4Electron::Electron(), mateWall);
0135 dedxWall /= densityWall;
0136 G4double dedxCavity = emCal.GetDEDX(fEnergyGun, G4Electron::Electron(), mateCavity);
0137 dedxCavity /= densityCavity;
0138
0139 G4cout << std::setprecision(4)
0140 << "\n StoppingPower in wall = " << G4BestUnit(dedxWall, "Energy*Surface/Mass")
0141 << "\n in cavity = " << G4BestUnit(dedxCavity, "Energy*Surface/Mass")
0142 << G4endl;
0143
0144
0145
0146 fProcCounter = new ProcessesCount;
0147
0148
0149
0150 fPartFlowCavity[0] = fPartFlowCavity[1] = 0;
0151 fEnerFlowCavity[0] = fEnerFlowCavity[1] = 0.;
0152
0153
0154
0155 fEdepCavity = fEdepCavity2 = fTrkSegmCavity = 0.;
0156 fNbEventCavity = 0;
0157
0158
0159
0160 fStepWall = fStepWall2 = fStepCavity = fStepCavity2 = 0.;
0161 fNbStepWall = fNbStepCavity = 0;
0162
0163
0164 G4cout.setf(mode, std::ios::floatfield);
0165 G4cout.precision(prec);
0166
0167
0168
0169 G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0170 if (analysisManager->IsActive()) {
0171 analysisManager->OpenFile();
0172 }
0173 }
0174
0175
0176
0177 Run::~Run() {}
0178
0179
0180
0181 void Run::CountProcesses(G4String procName)
0182 {
0183
0184 size_t nbProc = fProcCounter->size();
0185 size_t i = 0;
0186 while ((i < nbProc) && ((*fProcCounter)[i]->GetName() != procName))
0187 i++;
0188 if (i == nbProc) fProcCounter->push_back(new OneProcessCount(procName));
0189
0190 (*fProcCounter)[i]->Count();
0191 }
0192
0193
0194
0195 void Run::SurveyConvergence(G4int NbofEvents)
0196 {
0197 if (NbofEvents == 0) return;
0198
0199
0200
0201 G4int Nwall = fKinematic->GetWallCount();
0202 G4int Ncavity = fKinematic->GetCavityCount();
0203 G4double Iwall = Nwall / fMassWall;
0204 G4double Icavity = Ncavity / fMassCavity;
0205 G4double Iratio = Icavity / Iwall;
0206 G4double Itot = NbofEvents / (fMassWall + fMassCavity);
0207 G4double energyFluence = fEnergyGun * Itot;
0208
0209
0210
0211 G4double doseCavity = fEdepCavity / fMassCavity;
0212 G4double ratio = doseCavity / energyFluence;
0213 G4double err = 100 * (ratio - 1.);
0214
0215 std::ios::fmtflags mode = G4cout.flags();
0216 G4cout.setf(std::ios::fixed, std::ios::floatfield);
0217 G4int prec = G4cout.precision(5);
0218
0219 G4cout << "--->evntNb= " << NbofEvents << " Nwall= " << Nwall << " Ncav= " << Ncavity
0220 << " Ic/Iw= " << Iratio << " Ne-_cav= " << fPartFlowCavity[0]
0221 << " doseCavity/Ebeam= " << ratio << " (100*(ratio-1) = " << err << " %) \n"
0222 << G4endl;
0223
0224
0225 G4cout.setf(mode, std::ios::floatfield);
0226 G4cout.precision(prec);
0227 }
0228
0229
0230
0231 void Run::EndOfRun()
0232 {
0233
0234 std::ios::fmtflags mode = G4cout.flags();
0235 G4cout.setf(std::ios::fixed, std::ios::floatfield);
0236 G4int prec = G4cout.precision(3);
0237
0238 if (numberOfEvent == 0) return;
0239
0240
0241
0242 G4cout << "\n Process calls frequency --->";
0243 for (size_t i = 0; i < fProcCounter->size(); i++) {
0244 G4String procName = (*fProcCounter)[i]->GetName();
0245 G4int count = (*fProcCounter)[i]->GetCounter();
0246 G4cout << " " << procName << "= " << count;
0247 }
0248 G4cout << G4endl;
0249
0250
0251
0252 G4cout << "\n Charged particle flow in cavity :"
0253 << "\n Enter --> nbParticles = " << fPartFlowCavity[0]
0254 << "\t Energy = " << G4BestUnit(fEnerFlowCavity[0], "Energy")
0255 << "\n Exit --> nbParticles = " << fPartFlowCavity[1]
0256 << "\t Energy = " << G4BestUnit(fEnerFlowCavity[1], "Energy") << G4endl;
0257
0258 if (fPartFlowCavity[0] == 0) return;
0259
0260 G4int Nwall = fKinematic->GetWallCount();
0261 G4int Ncavity = fKinematic->GetCavityCount();
0262
0263 G4double Iwall = Nwall / fMassWall;
0264 G4double Icavity = Ncavity / fMassCavity;
0265 G4double Iratio = Icavity / Iwall;
0266 G4double Itot = numberOfEvent / (fMassWall + fMassCavity);
0267 G4double energyFluence = fEnergyGun * Itot;
0268
0269 G4cout.precision(5);
0270 G4cout << "\n beamFluence in wall = " << Nwall << "\t in cavity = " << Ncavity
0271 << "\t Icav/Iwall = " << Iratio
0272 << "\t energyFluence = " << energyFluence / (MeV * cm2 / mg) << " MeV*cm2/mg" << G4endl;
0273
0274
0275
0276 if (fNbEventCavity == 0) return;
0277 G4double meanEdep = fEdepCavity / fNbEventCavity;
0278 G4double meanEdep2 = fEdepCavity2 / fNbEventCavity;
0279 G4double varianceEdep = meanEdep2 - meanEdep * meanEdep;
0280 G4double dEoverE = 0.;
0281 if (varianceEdep > 0.) dEoverE = std::sqrt(varianceEdep / fNbEventCavity) / meanEdep;
0282
0283
0284
0285 G4double doseCavity = fEdepCavity / fMassCavity;
0286
0287 G4double ratio = doseCavity / energyFluence, error = ratio * dEoverE;
0288
0289 G4cout << "\n Total edep in cavity = " << G4BestUnit(fEdepCavity, "Energy") << " +- "
0290 << 100 * dEoverE << " %"
0291 << "\n Total dose in cavity = " << doseCavity / (MeV * cm2 / mg) << " MeV*cm2/mg"
0292 << " +- " << 100 * dEoverE << " %"
0293 << "\n\n DoseCavity/EnergyFluence = " << ratio << " +- " << error << G4endl;
0294
0295
0296 G4double meantrack = fTrkSegmCavity / fPartFlowCavity[0];
0297
0298 G4cout.precision(4);
0299 G4cout << "\n Total charged trackLength in cavity = " << G4BestUnit(fTrkSegmCavity, "Length")
0300 << " (mean value = " << G4BestUnit(meantrack, "Length") << ")" << G4endl;
0301
0302
0303
0304 fStepWall /= fNbStepWall;
0305 fStepWall2 /= fNbStepWall;
0306 G4double rms = fStepWall2 - fStepWall * fStepWall;
0307 if (rms > 0.)
0308 rms = std::sqrt(rms);
0309 else
0310 rms = 0.;
0311 G4double nbTrackWall = fKinematic->GetWallCount();
0312
0313 G4cout << "\n StepSize of ch. tracks in wall = " << G4BestUnit(fStepWall, "Length") << " +- "
0314 << G4BestUnit(rms, "Length") << "\t (nbSteps/track = " << double(fNbStepWall) / nbTrackWall
0315 << ")";
0316
0317 fStepCavity /= fNbStepCavity;
0318 fStepCavity2 /= fNbStepCavity;
0319 rms = fStepCavity2 - fStepCavity * fStepCavity;
0320 if (rms > 0.)
0321 rms = std::sqrt(rms);
0322 else
0323 rms = 0.;
0324
0325 G4cout << "\n StepSize of ch. tracks in cavity = " << G4BestUnit(fStepCavity, "Length") << " +- "
0326 << G4BestUnit(rms, "Length")
0327 << "\t (nbSteps/track = " << double(fNbStepCavity) / fPartFlowCavity[0] << ")";
0328
0329 G4cout << G4endl;
0330
0331
0332 G4cout.setf(mode, std::ios::floatfield);
0333 G4cout.precision(prec);
0334
0335
0336 while (fProcCounter->size() > 0) {
0337 OneProcessCount* aProcCount = fProcCounter->back();
0338 fProcCounter->pop_back();
0339 delete aProcCount;
0340 }
0341 delete fProcCounter;
0342
0343
0344 CLHEP::HepRandom::showEngineStatus();
0345 }
0346
0347
0348
0349 void Run::Merge(const G4Run* run)
0350 {
0351 const Run* localRun = static_cast<const Run*>(run);
0352
0353
0354 fPartFlowCavity[0] += localRun->fPartFlowCavity[0];
0355 fPartFlowCavity[1] += localRun->fPartFlowCavity[1];
0356 fEnerFlowCavity[0] += localRun->fEnerFlowCavity[0];
0357 fEnerFlowCavity[1] += localRun->fEnerFlowCavity[1];
0358 fEdepCavity += localRun->fEdepCavity;
0359 fEdepCavity2 += localRun->fEdepCavity2;
0360 fTrkSegmCavity += localRun->fTrkSegmCavity;
0361 fNbEventCavity += localRun->fNbEventCavity;
0362 fStepWall += localRun->fStepWall;
0363 fStepWall2 += localRun->fStepWall2;
0364 fStepCavity += localRun->fStepCavity;
0365 fStepCavity2 += localRun->fStepCavity2;
0366 fNbStepWall += localRun->fNbStepWall;
0367 fNbStepCavity += localRun->fNbStepCavity;
0368
0369
0370 fKinematic->AddWallCount(localRun->fKinematic->GetWallCount());
0371 fKinematic->AddCavityCount(localRun->fKinematic->GetCavityCount());
0372
0373
0374 std::vector<OneProcessCount*>::iterator it;
0375 for (it = localRun->fProcCounter->begin(); it != localRun->fProcCounter->end(); it++) {
0376 OneProcessCount* process = *it;
0377 for (G4int i = 0; i < process->GetCounter(); i++)
0378 this->CountProcesses(process->GetName());
0379 }
0380
0381 G4Run::Merge(run);
0382 }
0383
0384