Warning, file /geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/CrossSection/src/XSHistoManager.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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
0046
0047
0048 #include "XSHistoManager.hh"
0049
0050 #include "G4Element.hh"
0051 #include "G4HadronicProcessStore.hh"
0052 #include "G4Material.hh"
0053 #include "G4NistManager.hh"
0054 #include "G4ParticleDefinition.hh"
0055 #include "G4ParticleTable.hh"
0056 #include "G4ios.hh"
0057
0058
0059 #include "tools_histo_flair.hh"
0060
0061 #include "G4RootAnalysisManager.hh"
0062
0063
0064
0065 XSHistoManager::XSHistoManager()
0066 : fMessenger(new XSHistoManagerMessenger(this)),
0067 fOutputFileName("all_XS"),
0068 fRootOutputFileName("all_XS.root"),
0069 fFlairOutputFileName("all_XS.hist"),
0070 fParticle(nullptr),
0071 fElement(nullptr),
0072 fMaterial(nullptr),
0073 fNumBins(10000),
0074 fMinKineticEnergy(1. * keV),
0075 fMaxKineticEnergy(10. * TeV),
0076 fFunctionName("none"),
0077 fBinSchemeName("log"),
0078 fRootEnergyUnit("MeV"),
0079 fAnalysisManager(G4RootAnalysisManager::Instance()),
0080 fElasticXSIndex(0),
0081 fInelasticXSIndex(1),
0082 fCaptureXSIndex(2),
0083 fFissionXSIndex(3),
0084 fChargeExchangeXSIndex(4),
0085 fTotalXSIndex(5),
0086 fElasticPerVolumeXSIndex(6),
0087 fInelasticPerVolumeXSIndex(7)
0088 {
0089
0090 }
0091
0092
0093
0094
0095 void XSHistoManager::SetOutputFileName(const G4String& outputFileName)
0096 {
0097 fOutputFileName = outputFileName;
0098 fRootOutputFileName = outputFileName + ".root";
0099 fFlairOutputFileName = outputFileName + ".hist";
0100 }
0101
0102
0103
0104
0105 void XSHistoManager::SetParticle(const G4String& particleName)
0106 {
0107 fParticle = G4ParticleTable::GetParticleTable()->FindParticle(particleName);
0108 }
0109
0110
0111
0112
0113 void XSHistoManager::SetElement(const G4String& elementName)
0114 {
0115 fElement = G4NistManager::Instance()->FindOrBuildElement(elementName);
0116
0117 SetMaterial(elementName);
0118 }
0119
0120
0121
0122
0123 void XSHistoManager::SetMaterial(const G4String& materialName)
0124 {
0125
0126 if (fMaterial) {
0127 G4ExceptionDescription msg;
0128 msg << "Please use UI command /allXS/elementName"
0129 << " OR UI command /allXS/nonElementaryMaterialName,"
0130 << " BUT NOT BOTH!" << G4endl;
0131 G4Exception("XSHistoManager::SetMaterial", "A target material is already defined.",
0132 FatalException, msg);
0133 }
0134
0135 fMaterial = G4NistManager::Instance()->FindOrBuildMaterial("G4_" + materialName);
0136 }
0137
0138
0139
0140
0141
0142 void XSHistoManager::Book()
0143 {
0144
0145 CheckInput();
0146
0147
0148 if (!fAnalysisManager->OpenFile(fRootOutputFileName)) {
0149 G4ExceptionDescription msg;
0150 msg << "Booking profiles: cannot open file " << fRootOutputFileName << G4endl;
0151 G4Exception("XSHistoManager::Book", "Cannot open file", FatalException, msg);
0152 }
0153 G4cout << "### XSHistoManager::Book: Successfully opened file " << fRootOutputFileName
0154 << " for dumping profiles." << G4endl;
0155
0156
0157 const G4int elasticXSProfileIndex =
0158 fAnalysisManager->CreateH1("ElasticXS", "Elastic XS", fNumBins, fMinKineticEnergy,
0159 fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
0160 fXSProfileIndex.insert(std::make_pair(fElasticXSIndex, elasticXSProfileIndex));
0161
0162 const G4int inelasticXSProfileIndex =
0163 fAnalysisManager->CreateH1("InelasticXS", "Inelastic XS", fNumBins, fMinKineticEnergy,
0164 fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
0165 fXSProfileIndex.insert(std::make_pair(fInelasticXSIndex, inelasticXSProfileIndex));
0166
0167 const G4int captureXSProfileIndex =
0168 fAnalysisManager->CreateH1("CaptureXS", "Capture XS", fNumBins, fMinKineticEnergy,
0169 fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
0170 fXSProfileIndex.insert(std::make_pair(fCaptureXSIndex, captureXSProfileIndex));
0171
0172 const G4int fissionXSProfileIndex =
0173 fAnalysisManager->CreateH1("FissionXS", "Fission XS", fNumBins, fMinKineticEnergy,
0174 fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
0175 fXSProfileIndex.insert(std::make_pair(fFissionXSIndex, fissionXSProfileIndex));
0176
0177 const G4int chargeExchangeXSProfileIndex = fAnalysisManager->CreateH1(
0178 "ChargeExchangeXS", "Charge exchange XS", fNumBins, fMinKineticEnergy, fMaxKineticEnergy,
0179 fRootEnergyUnit, fFunctionName, fBinSchemeName);
0180 fXSProfileIndex.insert(std::make_pair(fChargeExchangeXSIndex, chargeExchangeXSProfileIndex));
0181
0182 const G4int totalXSProfileIndex =
0183 fAnalysisManager->CreateH1("TotalXS", "Total XS", fNumBins, fMinKineticEnergy,
0184 fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
0185 fXSProfileIndex.insert(std::make_pair(fTotalXSIndex, totalXSProfileIndex));
0186
0187 const G4int elasticPerVolumeXSProfileIndex = fAnalysisManager->CreateH1(
0188 "ElasticPerVolumeXS", "Elastic XS per volume", fNumBins, fMinKineticEnergy, fMaxKineticEnergy,
0189 fRootEnergyUnit, fFunctionName, fBinSchemeName);
0190 fXSProfileIndex.insert(std::make_pair(fElasticPerVolumeXSIndex, elasticPerVolumeXSProfileIndex));
0191
0192 const G4int inelasticPerVolumeXSProfileIndex = fAnalysisManager->CreateH1(
0193 "InelasticPerVolumeXS", "Inelastic XS per volume", fNumBins, fMinKineticEnergy,
0194 fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
0195 fXSProfileIndex.insert(
0196 std::make_pair(fInelasticPerVolumeXSIndex, inelasticPerVolumeXSProfileIndex));
0197 }
0198
0199
0200
0201
0202 void XSHistoManager::EndOfRun()
0203 {
0204 G4cout << "### XSHistoManager::EndOfRun: Compute & fill XS for " << fParticle->GetParticleName()
0205 << " in " << (fElement ? fElement->GetName() : fMaterial->GetName()) << G4endl;
0206
0207 G4HadronicProcessStore* const store = G4HadronicProcessStore::Instance();
0208
0209
0210 const G4double logMinKineticEnergy = std::log10(fMinKineticEnergy);
0211 const G4double logMaxKineticEnergy = std::log10(fMaxKineticEnergy);
0212 const G4double deltaLogKineticEnergy = (logMaxKineticEnergy - logMinKineticEnergy) / fNumBins;
0213
0214 G4double logKineticEnergy = logMinKineticEnergy - deltaLogKineticEnergy / 2.;
0215
0216
0217 for (G4int binIndex = 0; binIndex < fNumBins; ++binIndex) {
0218 logKineticEnergy += deltaLogKineticEnergy;
0219 const G4double kineticEnergy = std::pow(10., logKineticEnergy) * MeV;
0220
0221 G4double totalXS = 0.;
0222 if (fElement) {
0223
0224 const G4double elasticXS =
0225 store->GetElasticCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
0226 fAnalysisManager->FillH1(fXSProfileIndex[fElasticXSIndex], kineticEnergy, elasticXS / barn);
0227 totalXS += elasticXS;
0228
0229
0230 const G4double inelasticXS =
0231 store->GetInelasticCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
0232 fAnalysisManager->FillH1(fXSProfileIndex[fInelasticXSIndex], kineticEnergy,
0233 inelasticXS / barn);
0234 totalXS += inelasticXS;
0235
0236 if (fParticle == G4Neutron::Definition()) {
0237
0238 const G4double captureXS =
0239 store->GetCaptureCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
0240 fAnalysisManager->FillH1(fXSProfileIndex[fCaptureXSIndex], kineticEnergy, captureXS / barn);
0241 totalXS += captureXS;
0242
0243
0244 const G4double fissionXS =
0245 store->GetFissionCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
0246 totalXS += fissionXS;
0247 fAnalysisManager->FillH1(fXSProfileIndex[fFissionXSIndex], kineticEnergy, fissionXS / barn);
0248 }
0249
0250
0251 const G4double chargeExchangeXS =
0252 store->GetChargeExchangeCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
0253 fAnalysisManager->FillH1(fXSProfileIndex[fChargeExchangeXSIndex], kineticEnergy,
0254 chargeExchangeXS / barn);
0255 totalXS += chargeExchangeXS;
0256
0257
0258 fAnalysisManager->FillH1(fXSProfileIndex[fTotalXSIndex], kineticEnergy, totalXS / barn);
0259 }
0260
0261 if (fMaterial) {
0262 const G4double materialSurfacicDensity =
0263 (fMaterial ? fMaterial->GetDensity() / (g / cm2) : 1.);
0264
0265
0266 const G4double elasticPerVolumeXS =
0267 store->GetElasticCrossSectionPerVolume(fParticle, kineticEnergy, fMaterial);
0268 fAnalysisManager->FillH1(fXSProfileIndex[fElasticPerVolumeXSIndex], kineticEnergy,
0269 elasticPerVolumeXS / materialSurfacicDensity);
0270
0271
0272 const G4double inelasticPerVolumeXS =
0273 store->GetInelasticCrossSectionPerVolume(fParticle, kineticEnergy, fMaterial);
0274 fAnalysisManager->FillH1(fXSProfileIndex[fInelasticPerVolumeXSIndex], kineticEnergy,
0275 inelasticPerVolumeXS / materialSurfacicDensity);
0276 }
0277 }
0278
0279
0280 DumpAllG4H1IntoRootFile();
0281
0282
0283 DumpAllG4H1IntoFlairFile();
0284
0285
0286 fAnalysisManager->CloseFile();
0287 fAnalysisManager->Clear();
0288 }
0289
0290
0291
0292
0293
0294 void XSHistoManager::CheckInput()
0295 {
0296 if (!fParticle) {
0297 G4ExceptionDescription msg;
0298 msg << "Please add a particle to study XS: UI command /allXS/particleName" << G4endl;
0299 G4Exception("XSHistoManager::CheckInput()", "Print XS: no input particle defined.",
0300 FatalException, msg);
0301 }
0302
0303 if (!fMaterial) {
0304 G4ExceptionDescription msg;
0305 msg << "Please add a material to study XS:"
0306 << " UI command /allXS/elementName for an elementary material,"
0307 << " or UI command /allXS/nonElementaryMaterialName for a compound/mixture material."
0308 << G4endl;
0309 G4Exception("XSHistoManager::CheckInput()", "Print XS: no target material defined.",
0310 FatalException, msg);
0311 }
0312 }
0313
0314
0315
0316
0317 void XSHistoManager::DumpAllG4H1IntoRootFile() const
0318 {
0319 if (!fAnalysisManager->Write()) {
0320 G4ExceptionDescription message;
0321 message << "Could not write ROOT file.";
0322 G4Exception("XSHistoManager::EndOfRun()", "I/O Error", FatalException, message);
0323 }
0324 G4cout << "### All profiles saved to " << fRootOutputFileName << G4endl;
0325 }
0326
0327
0328
0329
0330 void XSHistoManager::DumpAllG4H1IntoFlairFile() const
0331 {
0332 std::ofstream output;
0333 output.open(fFlairOutputFileName, std::ios_base::out);
0334 auto const rootAnalysisManager = dynamic_cast<G4RootAnalysisManager*>(fAnalysisManager);
0335
0336 G4int indexInOutputFile = 1;
0337 for (G4int xsIndex = fElasticXSIndex; xsIndex <= fInelasticPerVolumeXSIndex; ++xsIndex) {
0338 const G4int histoIndex = fXSProfileIndex.at(xsIndex);
0339 const G4String& histoName = fAnalysisManager->GetH1Name(histoIndex);
0340 const auto& histo = rootAnalysisManager->GetH1(histoIndex);
0341
0342 tools::histo::flair::dumpG4H1ProfileInFlairFormat(output, indexInOutputFile, histoName, histo,
0343 tools::histo::flair::Abscissa::KineticEnergy,
0344 fBinSchemeName);
0345 ++indexInOutputFile;
0346 }
0347 output.close();
0348 G4cout << "### All profiles saved to " << fFlairOutputFileName << G4endl;
0349 }
0350
0351