File indexing completed on 2026-09-13 08:29:19
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
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #include "HistoManager.hh"
0046
0047 #include "HistoManagerMessenger.hh"
0048
0049 #include "G4HadronicProcessStore.hh"
0050 #include "G4Neutron.hh"
0051 #include "G4NistManager.hh"
0052 #include "G4NucleiProperties.hh"
0053 #include "G4ParticleDefinition.hh"
0054 #include "G4ParticleTable.hh"
0055 #include "G4StableIsotopes.hh"
0056 #include "G4SystemOfUnits.hh"
0057 #include "G4UnitsTable.hh"
0058 #include "G4ios.hh"
0059 #include "globals.hh"
0060
0061
0062
0063 HistoManager::HistoManager()
0064 {
0065 fAnalysisManager = 0;
0066 fHistoName = "hadr00";
0067
0068 fNeutron = G4Neutron::Neutron();
0069 fMessenger = new HistoManagerMessenger(this);
0070 fVerbose = 1;
0071
0072 fParticleName = "proton";
0073 fElementName = "Al";
0074
0075 fTargetMaterial = 0;
0076
0077 fMinKinEnergy = 0.1 * MeV;
0078 fMaxKinEnergy = 10 * TeV;
0079 fMinMomentum = 1 * MeV;
0080 fMaxMomentum = 10 * TeV;
0081
0082 fBinsE = 800;
0083 fBinsP = 700;
0084 }
0085
0086
0087
0088 HistoManager::~HistoManager()
0089 {
0090 delete fMessenger;
0091 }
0092
0093
0094
0095 void HistoManager::BeginOfRun()
0096 {
0097 G4double p1 = std::log10(fMinMomentum / GeV);
0098 G4double p2 = std::log10(fMaxMomentum / GeV);
0099 G4double e1 = std::log10(fMinKinEnergy / MeV);
0100 G4double e2 = std::log10(fMaxKinEnergy / MeV);
0101
0102
0103
0104 fAnalysisManager = G4AnalysisManager::Instance();
0105 fAnalysisManager->OpenFile(fHistoName + ".root");
0106 fAnalysisManager->SetFirstHistoId(1);
0107
0108 fAnalysisManager->CreateH1("h1", "Elastic cross section (barn) as a functions of log10(p/GeV)",
0109 fBinsP, p1, p2);
0110 fAnalysisManager->CreateH1("h2", "Elastic cross section (barn) as a functions of log10(E/MeV)",
0111 fBinsE, e1, e2);
0112 fAnalysisManager->CreateH1("h3", "Inelastic cross section (barn) as a functions of log10(p/GeV)",
0113 fBinsP, p1, p2);
0114 fAnalysisManager->CreateH1("h4", "Inelastic cross section (barn) as a functions of log10(E/MeV)",
0115 fBinsE, e1, e2);
0116 fAnalysisManager->CreateH1("h5", "Capture cross section (barn) as a functions of log10(E/MeV)",
0117 fBinsE, e1, e2);
0118 fAnalysisManager->CreateH1("h6", "Fission cross section (barn) as a functions of log10(E/MeV)",
0119 fBinsE, e1, e2);
0120 fAnalysisManager->CreateH1(
0121 "h7", "Charge exchange cross section (barn) as a functions of log10(E/MeV)", fBinsE, e1, e2);
0122 fAnalysisManager->CreateH1("h8", "Total cross section (barn) as a functions of log10(E/MeV)",
0123 fBinsE, e1, e2);
0124 fAnalysisManager->CreateH1(
0125 "h9", "Inelastic cross section per volume as a functions of log10(E/MeV)", fBinsE, e1, e2);
0126 fAnalysisManager->CreateH1(
0127 "h10", "Elastic cross section per volume as a functions of log10(E/MeV)", fBinsE, e1, e2);
0128 }
0129
0130
0131
0132 void HistoManager::EndOfRun()
0133 {
0134 if (fVerbose > 0) {
0135 G4cout << "HistoManager: End of run actions are started" << G4endl;
0136 }
0137
0138 const G4Element* elm = G4NistManager::Instance()->FindOrBuildElement(fElementName);
0139 const G4Material* mat = G4NistManager::Instance()->FindOrBuildMaterial("G4_" + fElementName);
0140 const G4ParticleDefinition* particle =
0141 G4ParticleTable::GetParticleTable()->FindParticle(fParticleName);
0142
0143 G4cout << "### Fill Cross Sections for " << fParticleName << " off " << fElementName << G4endl;
0144 if (fVerbose > 0) {
0145 G4cout << "-------------------------------------------------------------" << G4endl;
0146 G4cout << " N E(MeV) Elastic(b) Inelastic(b)";
0147 if (particle == fNeutron) {
0148 G4cout << " Capture(b) Fission(b)";
0149 }
0150 G4cout << " Total(b)" << G4endl;
0151 G4cout << "-------------------------------------------------------------" << G4endl;
0152 }
0153 if (!particle || !elm) {
0154 G4cout << "HistoManager WARNING Particle or element undefined" << G4endl;
0155 return;
0156 }
0157
0158 G4int prec = G4cout.precision();
0159 G4cout.precision(4);
0160
0161 G4HadronicProcessStore* store = G4HadronicProcessStore::Instance();
0162 G4double mass = particle->GetPDGMass();
0163
0164
0165
0166 G4double p1 = std::log10(fMinMomentum / GeV);
0167 G4double p2 = std::log10(fMaxMomentum / GeV);
0168 G4double e1 = std::log10(fMinKinEnergy / MeV);
0169 G4double e2 = std::log10(fMaxKinEnergy / MeV);
0170 G4double de = (e2 - e1) / G4double(fBinsE);
0171 G4double dp = (p2 - p1) / G4double(fBinsP);
0172
0173 G4double x = e1 - de * 0.5;
0174 G4double e, p, xs, xtot;
0175 G4int i;
0176
0177 G4double coeff = 1.0;
0178 if (fTargetMaterial) {
0179 coeff = fTargetMaterial->GetDensity() * cm2 / g;
0180 }
0181
0182 for (i = 0; i < fBinsE; i++) {
0183 x += de;
0184 e = std::pow(10., x) * MeV;
0185 if (fVerbose > 0) G4cout << std::setw(5) << i << std::setw(12) << e;
0186 xs = store->GetElasticCrossSectionPerAtom(particle, e, elm, mat);
0187 xtot = xs;
0188 if (fVerbose > 0) G4cout << std::setw(12) << xs / barn;
0189 fAnalysisManager->FillH1(2, x, xs / barn);
0190 xs = store->GetInelasticCrossSectionPerAtom(particle, e, elm, mat);
0191 xtot += xs;
0192 if (fVerbose > 0) G4cout << " " << std::setw(12) << xs / barn;
0193 fAnalysisManager->FillH1(4, x, xs / barn);
0194 if (fTargetMaterial) {
0195 xs = store->GetInelasticCrossSectionPerVolume(particle, e, fTargetMaterial);
0196 fAnalysisManager->FillH1(9, x, xs / coeff);
0197 xs = store->GetElasticCrossSectionPerVolume(particle, e, fTargetMaterial);
0198 fAnalysisManager->FillH1(10, x, xs / coeff);
0199 }
0200 if (particle == fNeutron) {
0201 xs = store->GetCaptureCrossSectionPerAtom(particle, e, elm, mat);
0202 xtot += xs;
0203 if (fVerbose > 0) G4cout << " " << std::setw(12) << xs / barn;
0204 fAnalysisManager->FillH1(5, x, xs / barn);
0205 xs = store->GetFissionCrossSectionPerAtom(particle, e, elm, mat);
0206 xtot += xs;
0207 if (fVerbose > 0) G4cout << " " << std::setw(12) << xs / barn;
0208 fAnalysisManager->FillH1(6, x, xs / barn);
0209 }
0210 xs = store->GetChargeExchangeCrossSectionPerAtom(particle, e, elm, mat);
0211 if (fVerbose > 0) G4cout << " " << std::setw(12) << xtot / barn << G4endl;
0212 fAnalysisManager->FillH1(7, x, xs / barn);
0213 fAnalysisManager->FillH1(8, x, xtot / barn);
0214 }
0215
0216 x = p1 - dp * 0.5;
0217 for (i = 0; i < fBinsP; i++) {
0218 x += dp;
0219 p = std::pow(10., x) * GeV;
0220 e = std::sqrt(p * p + mass * mass) - mass;
0221 xs = store->GetElasticCrossSectionPerAtom(particle, e, elm, mat);
0222 fAnalysisManager->FillH1(1, x, xs / barn);
0223 xs = store->GetInelasticCrossSectionPerAtom(particle, e, elm, mat);
0224 fAnalysisManager->FillH1(3, x, xs / barn);
0225 }
0226 if (fVerbose > 0) {
0227 G4cout << "-------------------------------------------------------------" << G4endl;
0228 }
0229 G4cout.precision(prec);
0230 fAnalysisManager->Write();
0231 fAnalysisManager->CloseFile();
0232 fAnalysisManager->Clear();
0233
0234 G4bool extra = true;
0235 if (fTargetMaterial && extra) {
0236 G4double E = 5 * GeV;
0237 G4double cross = store->GetInelasticCrossSectionPerVolume(particle, E, fTargetMaterial);
0238 if (cross <= 0.0) {
0239 cross = 1.e-100;
0240 }
0241 G4cout << "### " << particle->GetParticleName() << " " << E / GeV << " GeV on "
0242 << fTargetMaterial->GetName()
0243 << " xs/X0= " << 1.0 / (cross * fTargetMaterial->GetRadlen()) << G4endl;
0244 }
0245 }
0246
0247
0248
0249 void HistoManager::SetVerbose(G4int val)
0250 {
0251 fVerbose = val;
0252 }
0253
0254