File indexing completed on 2025-02-23 09:22:14
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 "G4PhysicalConstants.hh"
0040 #include "G4Run.hh"
0041 #include "G4RunManager.hh"
0042 #include "G4SystemOfUnits.hh"
0043 #include "G4UnitsTable.hh"
0044 #include "Randomize.hh"
0045
0046 #include <iomanip>
0047 #include <stdexcept> // std::out_of_range
0048
0049
0050
0051 Run::Run(DetectorConstruction* det) : G4Run(), fDetector(det), fParticle(0), fEnergy(0)
0052 {
0053 InitFluence();
0054 }
0055
0056
0057
0058 Run::~Run() {}
0059
0060
0061
0062 void Run::SetPrimary(G4ParticleDefinition* particle, G4double energy)
0063 {
0064 fParticle = particle;
0065 fEnergy = energy;
0066 }
0067
0068
0069
0070 void Run::Merge(const G4Run* run)
0071 {
0072 const Run* localRun = static_cast<const Run*>(run);
0073
0074
0075 fParticle = localRun->fParticle;
0076 fEnergy = localRun->fEnergy;
0077
0078
0079 fNbBins = localRun->fNbBins;
0080 fDr = localRun->fDr;
0081
0082
0083
0084 for (unsigned int i = 0; i < localRun->fluence.size(); ++i) {
0085 try {
0086 fluence[i] += localRun->fluence[i];
0087 }
0088 catch (const std::out_of_range&) {
0089 fluence.push_back(localRun->fluence[i]);
0090 }
0091 }
0092
0093 for (unsigned int i = 0; i < localRun->fluence1.size(); ++i) {
0094 try {
0095 fluence1[i] += localRun->fluence1[i];
0096 }
0097 catch (const std::out_of_range&) {
0098 fluence1.push_back(localRun->fluence1[i]);
0099 }
0100 }
0101
0102 for (unsigned int i = 0; i < localRun->fluence2.size(); ++i) {
0103 try {
0104 fluence2[i] += localRun->fluence2[i];
0105 }
0106 catch (const std::out_of_range&) {
0107 fluence2.push_back(localRun->fluence2[i]);
0108 }
0109 }
0110
0111 for (unsigned int i = 0; i < localRun->fNbEntries.size(); ++i) {
0112 try {
0113 fNbEntries[i] += localRun->fNbEntries[i];
0114 }
0115 catch (const std::out_of_range&) {
0116 fNbEntries.push_back(localRun->fNbEntries[i]);
0117 }
0118 }
0119
0120 G4Run::Merge(run);
0121 }
0122
0123
0124
0125 void Run::EndOfRun()
0126 {
0127 if (numberOfEvent == 0) return;
0128
0129
0130
0131 G4Material* material = fDetector->GetMaterialScatter();
0132 G4double length = fDetector->GetThicknessScatter();
0133 G4double density = material->GetDensity();
0134 G4String partName = fParticle->GetParticleName();
0135
0136 G4cout << "\n ======================== run summary ======================\n";
0137
0138 G4int prec = G4cout.precision(3);
0139
0140 G4cout << "\n The run was " << numberOfEvent << " " << partName << " of "
0141 << G4BestUnit(fEnergy, "Energy") << " through " << G4BestUnit(length, "Length") << " of "
0142 << material->GetName() << " (density: " << G4BestUnit(density, "Volumic Mass") << ")"
0143 << G4endl;
0144
0145 G4cout.precision(prec);
0146
0147
0148
0149 G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0150 G4double fac = 1. / (double(numberOfEvent));
0151 analysisManager->ScaleH1(1, fac);
0152 analysisManager->ScaleH1(2, fac);
0153 analysisManager->ScaleH1(3, fac);
0154 analysisManager->ScaleH1(5, fac);
0155 analysisManager->ScaleH1(6, fac);
0156
0157 ComputeFluenceError();
0158 PrintFluence(numberOfEvent);
0159 }
0160
0161
0162
0163 void Run::InitFluence()
0164 {
0165
0166
0167 G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0168 G4int ih = 4;
0169 analysisManager->SetH1(ih, 120, 0 * mm, 240 * mm, "mm");
0170
0171
0172
0173 fNbBins = analysisManager->GetH1Nbins(ih);
0174 fDr = analysisManager->GetH1Width(ih);
0175 fluence.resize(fNbBins, 0.);
0176 fluence1.resize(fNbBins, 0.);
0177 fluence2.resize(fNbBins, 0.);
0178 fNbEntries.resize(fNbBins, 0);
0179 }
0180
0181
0182
0183 void Run::SumFluence(G4double r, G4double fl)
0184 {
0185 G4int ibin = (int)(r / fDr);
0186 if (ibin >= fNbBins) return;
0187 fNbEntries[ibin]++;
0188 fluence[ibin] += fl;
0189 fluence2[ibin] += fl * fl;
0190 }
0191
0192
0193
0194 void Run::ComputeFluenceError()
0195 {
0196
0197
0198 G4double ds, variance, rms;
0199 G4double rmean = -0.5 * fDr;
0200
0201 for (G4int bin = 0; bin < fNbBins; bin++) {
0202 rmean += fDr;
0203 ds = twopi * rmean * fDr;
0204 fluence[bin] /= ds;
0205 fluence2[bin] /= (ds * ds);
0206 variance = 0.;
0207 if (fNbEntries[bin] > 0)
0208 variance = fluence2[bin] - (fluence[bin] * fluence[bin]) / fNbEntries[bin];
0209 rms = 0.;
0210 if (variance > 0.) rms = std::sqrt(variance);
0211 fluence2[bin] = rms;
0212 }
0213
0214
0215
0216 G4double rnorm(4 * mm), radius(0.), fnorm(0.), fnorm2(0.);
0217 G4int inorm = -1;
0218 do {
0219 inorm++;
0220 radius += fDr;
0221 fnorm += fluence[inorm];
0222 fnorm2 += fluence2[inorm];
0223 } while (radius < rnorm);
0224 fnorm /= (inorm + 1);
0225 fnorm2 /= (inorm + 1);
0226
0227 G4double ratio, error;
0228 G4double scale = 1. / fnorm;
0229 G4double err0 = fnorm2 / fnorm, err1 = 0.;
0230
0231 rmean = -0.5 * fDr;
0232
0233 for (G4int bin = 0; bin < fNbBins; bin++) {
0234 ratio = fluence[bin] * scale;
0235 error = 0.;
0236 if (ratio > 0.) {
0237 err1 = fluence2[bin] / fluence[bin];
0238 error = ratio * std::sqrt(err1 * err1 + err0 * err0);
0239 }
0240 fluence1[bin] = ratio;
0241 fluence2[bin] = error;
0242 rmean += fDr;
0243 G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0244 analysisManager->FillH1(4, rmean, ratio);
0245 }
0246 }
0247
0248
0249
0250 #include <fstream>
0251
0252 void Run::PrintFluence(G4int TotEvents)
0253 {
0254 G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0255 G4String name = analysisManager->GetFileName();
0256 G4String fileName = name + ".ascii";
0257 std::ofstream File(fileName, std::ios::out);
0258
0259 std::ios::fmtflags mode = File.flags();
0260 File.setf(std::ios::scientific, std::ios::floatfield);
0261 G4int prec = File.precision(3);
0262
0263 File << " Fluence density distribution \n "
0264 << "\n ibin \t radius (mm) \t Nb \t fluence\t norma fl\t rms/nfl (%) \n"
0265 << G4endl;
0266
0267 G4double rmean = -0.5 * fDr;
0268 for (G4int bin = 0; bin < fNbBins; bin++) {
0269 rmean += fDr;
0270 G4double error = 0.;
0271 if (fluence1[bin] > 0.) error = 100 * fluence2[bin] / fluence1[bin];
0272 File << " " << bin << "\t " << rmean / mm << "\t " << fNbEntries[bin] << "\t "
0273 << fluence[bin] / double(TotEvents) << "\t " << fluence1[bin] << "\t " << error << G4endl;
0274 }
0275
0276
0277 File.setf(mode, std::ios::floatfield);
0278 File.precision(prec);
0279 }
0280
0281