Import Geant4 11.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2024-06-28 13:08:51 +02:00
parent f7b23877ed
commit e58e650b32
5232 changed files with 239416 additions and 244360 deletions
@@ -33,10 +33,10 @@
//
// GEANT4 HadronNucleusXS
//
/// This application allows the study of G4 cross-sections,
/// This application allows the study of G4 cross-sections,
/// and in addition, of the FLUKA hadron-nucleus inelastic cross sections.
///
/// The user can printout any particle-material XS.
/// The user can printout any particle-material XS.
/// The XS are exactly the ones defined in any default G4 PhysicsList chosen by the user,
/// or from FLUKA (hadron-nucleus inelastic case).
///
@@ -45,23 +45,23 @@
/// - target material (element, compound or even mixture).
/// - plotting options.
///
/// All plots (created via the G4 analysis manager) can be dumped
/// to any of the usually supported formats (e.g. ROOT format),
/// All plots (created via the G4 analysis manager) can be dumped
/// to any of the usually supported formats (e.g. ROOT format),
/// but also in a Flair-compatible format.
///
/// NB 1: Unlike the FlukaCern/ProcessLevel/FinalState example,
/// the choice here is to directly use physics lists
/// the choice here is to directly use physics lists
/// (hence under the hood, the processes they define),
/// instead of 'hardcoding' processes of interest.
/// This allows to directly study ALL XS, with no possible discrepancy
/// This allows to directly study ALL XS, with no possible discrepancy
/// with respect to what is defined inside the physics lists.
///
/// NB 2: Note that here, the application is completely independent
/// from the event loop, gun, detector etc:
/// NB 2: Note that here, the application is completely independent
/// from the event loop, gun, detector etc:
/// the XS printout happend outside of the event loop anyway.
/// Hence, the fakeRun mode is used (setting number of events to 0).
/// This implies that no ActionInitialization is needed
/// (nor would be used anyway, if ever constructed),
/// This implies that no ActionInitialization is needed
/// (nor would be used anyway, if ever constructed),
/// and that the detector is a dummy, empty one.
/// Use: build/HadronNucleusXS all_XS.in FTFP_BERT_HP
@@ -72,16 +72,17 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4RunManagerFactory.hh"
#include "G4RunManager.hh"
#include "DetectorConstruction.hh"
#include "G4PhysListFactory.hh"
#include "G4RunManager.hh"
#include "G4RunManagerFactory.hh"
#include "G4VModularPhysicsList.hh"
#ifdef G4_USE_FLUKA
#include "G4_HP_CernFLUKAHadronInelastic_PhysicsList.hh"
#include "FLUKAParticleTable.hh"
# include "FLUKAParticleTable.hh"
# include "G4_HP_CernFLUKAHadronInelastic_PhysicsList.hh"
#endif
#include "XSHistoManager.hh"
@@ -89,30 +90,25 @@
#include "G4Exception.hh"
#include "G4UImanager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int main(G4int argc, char** argv) {
G4int main(G4int argc, char** argv)
{
// Check number of arguments
if (argc != 3) {
G4Exception("HadronNucleusXS (main)",
"Wrong number of input arguments.",
FatalException,
G4Exception("HadronNucleusXS (main)", "Wrong number of input arguments.", FatalException,
"Example use: build/HadronNucleusXS all_XS.in FTFP_BERT_HP");
}
// Construct a serial RUN MANAGER.
std::unique_ptr<G4RunManager> runManager(
G4RunManagerFactory::CreateRunManager(G4RunManagerType::SerialOnly));
G4RunManagerFactory::CreateRunManager(G4RunManagerType::SerialOnly));
// Empty DETECTOR (compulsory).
const auto dummyDetector = new DetectorConstruction();
// The detector is owned by G4RunManager.
runManager->SetUserInitialization(dummyDetector);
// Get PHYSICS LIST from command line argument.
// Default: G4_HP_CFLUKAHI.
const G4String physicsListName = (argc >= 3 ? argv[2] : "G4_HP_CFLUKAHI");
@@ -125,26 +121,24 @@ G4int main(G4int argc, char** argv) {
#ifdef G4_USE_FLUKA
physicsList = new G4_HP_CernFLUKAHadronInelastic_PhysicsList();
#else
G4Exception("HadronNucleusXS.cc",
"Wrong compilation mode.",
FatalException,
"Requested G4_HP_CernFLUKAHadronInelastic physics list.\n" \
"This requires COMPILATION in FLUKA mode.\n" \
"Please fully recompile the example with G4_USE_FLUKA=yes.\n" \
"For example:\n" \
"source geant4/examples/extended/hadronic/FlukaCern/FlukaInterface/" \
"env_FLUKA_G4_interface.sh\n" \
"cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/CrossSection/\n" \
"mkdir build\n" \
"cd build\n" \
"cmake -DGeant4_DIR=your_path_to_geant4 -DG4_USE_FLUKA=1 .. \n" \
"make -j8 G4_USE_FLUKA=1\n" \
"NB: First time use of FLUKA interface:\n" \
"Do not forget to first compile the FLUKA interface itself.\n" \
"For example: cd geant4/examples/extended/hadronic/FlukaCern/FlukaInterface/ " \
"&& make interface && make env\n" \
"FlukaInterface/env_FLUKA_G4_interface.sh then needs to be sourced\n" \
"in whichever terminal you want to use the FLUKA interface.\n");
G4Exception("HadronNucleusXS.cc", "Wrong compilation mode.", FatalException,
"Requested G4_HP_CernFLUKAHadronInelastic physics list.\n"
"This requires COMPILATION in FLUKA mode.\n"
"Please fully recompile the example with G4_USE_FLUKA=yes.\n"
"For example:\n"
"source geant4/examples/extended/hadronic/FlukaCern/FlukaInterface/"
"env_FLUKA_G4_interface.sh\n"
"cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/CrossSection/\n"
"mkdir build\n"
"cd build\n"
"cmake -DGeant4_DIR=your_path_to_geant4 -DG4_USE_FLUKA=1 .. \n"
"make -j8 G4_USE_FLUKA=1\n"
"NB: First time use of FLUKA interface:\n"
"Do not forget to first compile the FLUKA interface itself.\n"
"For example: cd geant4/examples/extended/hadronic/FlukaCern/FlukaInterface/ "
"&& make interface && make env\n"
"FlukaInterface/env_FLUKA_G4_interface.sh then needs to be sourced\n"
"in whichever terminal you want to use the FLUKA interface.\n");
#endif
}
// Create G4 physics list from available catalog.
@@ -163,11 +157,9 @@ G4int main(G4int argc, char** argv) {
}
#endif
// Create HISTO MANAGER (and its messenger).
auto histoManager = XSHistoManager();
// User interface manager (owned by G4RunManagerKernel).
const auto uiManager = G4UImanager::GetUIpointer();
// BATCH MODE.
@@ -175,7 +167,6 @@ G4int main(G4int argc, char** argv) {
const G4String fileName = argv[1];
uiManager->ApplyCommand(command + fileName);
// CREATE HISTOGRAMS AND FILL THEM (independent from event loop!).
histoManager.Book();
histoManager.EndOfRun();
@@ -10,7 +10,7 @@
**************************************************************
Geant4 version Name: geant4-11-02-patch-02 (21-June-2024)
Geant4 version Name: geant4-11-02-ref-06 (28-June-2024)
Copyright : Geant4 Collaboration
References : NIM A 506 (2003), 250-303
: IEEE-TNS 53 (2006), 270-278
@@ -42,18 +42,15 @@
#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class DetectorConstruction : public G4VUserDetectorConstruction {
public:
DetectorConstruction() = default;
virtual G4VPhysicalVolume* Construct() override;
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction() = default;
virtual G4VPhysicalVolume* Construct() override;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
#endif
@@ -35,18 +35,18 @@
//
/// Create a set of profiles for XS study.
///
/// All profiles are G4H1.
/// All profiles are G4H1.
/// They are created and filled via G4VAnalysisManager.
///
/// The profiles can be dumped to all usual formats, including ROOT
/// The profiles can be dumped to all usual formats, including ROOT
/// (via G4VAnalysisManager).
/// An interesting added feature here, is that the plots, while being allocated
/// and filled via G4VAnalysisManager, are also dumped
/// An interesting added feature here, is that the plots, while being allocated
/// and filled via G4VAnalysisManager, are also dumped
/// in a Flair-compatible format (via tools::histo::flair).
///
/// NB: tools::histo::flair code, which allows the dump of any G4H1
/// into Flair-compatible format, is fully application-agnostic,
/// and is placed in FlukaCern/utils.
/// NB: tools::histo::flair code, which allows the dump of any G4H1
/// into Flair-compatible format, is fully application-agnostic,
/// and is placed in FlukaCern/utils.
/// It could also be added as an extension of core G4 Analysis Manager.
//
// ***************************************************************************
@@ -54,75 +54,70 @@
#ifndef XS_HISTO_MANAGER_HH
#define XS_HISTO_MANAGER_HH
#include <unordered_map>
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "XSHistoManagerMessenger.hh"
#include "G4SystemOfUnits.hh"
#include "globals.hh"
#include <unordered_map>
class G4ParticleDefinition;
class G4Element;
class G4Material;
class G4VAnalysisManager;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class XSHistoManager {
class XSHistoManager
{
public:
XSHistoManager();
public:
XSHistoManager();
void SetOutputFileName(const G4String& outputFileName);
void SetParticle(const G4String& particleName);
void SetElement(const G4String& elementName);
void SetMaterial(const G4String& materialName);
void SetNumberOfBins(const G4int numBins) { fNumBins = numBins; }
void SetMinKinEnergy(const G4double minKineticEnergy) { fMinKineticEnergy = minKineticEnergy; }
void SetMaxKinEnergy(const G4double maxKineticEnergy) { fMaxKineticEnergy = maxKineticEnergy; }
void SetOutputFileName(const G4String& outputFileName);
void SetParticle(const G4String& particleName);
void SetElement(const G4String& elementName);
void SetMaterial(const G4String& materialName);
void SetNumberOfBins(const G4int numBins) { fNumBins = numBins; }
void SetMinKinEnergy(const G4double minKineticEnergy) { fMinKineticEnergy = minKineticEnergy; }
void SetMaxKinEnergy(const G4double maxKineticEnergy) { fMaxKineticEnergy = maxKineticEnergy; }
void Book();
void EndOfRun();
void Book();
void EndOfRun();
private:
void CheckInput();
void DumpAllG4H1IntoRootFile() const;
void DumpAllG4H1IntoFlairFile() const;
XSHistoManagerMessenger* fMessenger = nullptr;
private:
void CheckInput();
void DumpAllG4H1IntoRootFile() const;
void DumpAllG4H1IntoFlairFile() const;
G4String fOutputFileName = "all_XS";
G4String fRootOutputFileName = "all_XS.root";
G4String fFlairOutputFileName = "all_XS.hist";
const G4ParticleDefinition* fParticle = nullptr;
const G4Element* fElement = nullptr;
const G4Material* fMaterial = nullptr;
G4int fNumBins = 10000;
G4double fMinKineticEnergy = 1. * keV;
G4double fMaxKineticEnergy = 10. * TeV;
G4String fFunctionName = "none";
G4String fBinSchemeName = "log";
G4String fRootEnergyUnit = "MeV";
XSHistoManagerMessenger* fMessenger = nullptr;
G4VAnalysisManager* fAnalysisManager = nullptr;
std::unordered_map<G4int, G4int> fXSProfileIndex; // key: XS index
// value: histo index from G4VAnalysisManager
G4String fOutputFileName = "all_XS";
G4String fRootOutputFileName = "all_XS.root";
G4String fFlairOutputFileName = "all_XS.hist";
const G4ParticleDefinition* fParticle = nullptr;
const G4Element* fElement = nullptr;
const G4Material* fMaterial = nullptr;
G4int fNumBins = 10000;
G4double fMinKineticEnergy = 1.*keV;
G4double fMaxKineticEnergy = 10.*TeV;
G4String fFunctionName = "none";
G4String fBinSchemeName = "log";
G4String fRootEnergyUnit = "MeV";
G4VAnalysisManager* fAnalysisManager = nullptr;
std::unordered_map<G4int, G4int> fXSProfileIndex; // key: XS index
// value: histo index from G4VAnalysisManager
G4int fElasticXSIndex = 0;
G4int fInelasticXSIndex = 1;
G4int fCaptureXSIndex = 2;
G4int fFissionXSIndex = 3;
G4int fChargeExchangeXSIndex = 4;
G4int fTotalXSIndex = 5;
G4int fElasticPerVolumeXSIndex = 6;
G4int fInelasticPerVolumeXSIndex = 7;
G4int fElasticXSIndex = 0;
G4int fInelasticXSIndex = 1;
G4int fCaptureXSIndex = 2;
G4int fFissionXSIndex = 3;
G4int fChargeExchangeXSIndex = 4;
G4int fTotalXSIndex = 5;
G4int fElasticPerVolumeXSIndex = 6;
G4int fInelasticPerVolumeXSIndex = 7;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -41,43 +41,36 @@
#ifndef HISTO_MANAGER_MESSENGER_HH
#define HISTO_MANAGER_MESSENGER_HH
#include "globals.hh"
#include "G4UImessenger.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIdirectory.hh"
#include "G4UImessenger.hh"
#include "globals.hh"
class XSHistoManager;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class XSHistoManagerMessenger: public G4UImessenger {
class XSHistoManagerMessenger : public G4UImessenger
{
public:
XSHistoManagerMessenger(XSHistoManager* const histoManager);
public:
virtual void SetNewValue(G4UIcommand*, G4String) override;
XSHistoManagerMessenger(XSHistoManager* const histoManager);
private:
XSHistoManager* fHisto = nullptr;
virtual void SetNewValue(G4UIcommand*, G4String) override;
private:
XSHistoManager* fHisto = nullptr;
G4UIcmdWithAString fOutputFileNameCmd;
G4UIcmdWithAString fParticleNameCmd;
G4UIcmdWithAString fElementNameCmd;
G4UIcmdWithAString fNonElementaryMaterialNameCmd;
G4UIcmdWithAnInteger fNumBinsCmd;
G4UIcmdWithADoubleAndUnit fMinKineticEnergyCmd;
G4UIcmdWithADoubleAndUnit fMaxKineticEnergyCmd;
G4UIcmdWithAString fOutputFileNameCmd;
G4UIcmdWithAString fParticleNameCmd;
G4UIcmdWithAString fElementNameCmd;
G4UIcmdWithAString fNonElementaryMaterialNameCmd;
G4UIcmdWithAnInteger fNumBinsCmd;
G4UIcmdWithADoubleAndUnit fMinKineticEnergyCmd;
G4UIcmdWithADoubleAndUnit fMaxKineticEnergyCmd;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -39,34 +39,26 @@
#include "DetectorConstruction.hh"
#include "G4Box.hh"
#include "G4NistManager.hh"
#include "G4Material.hh"
#include "G4LogicalVolume.hh"
#include "G4VPhysicalVolume.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4PVPlacement.hh"
#include "G4SystemOfUnits.hh"
#include "G4VPhysicalVolume.hh"
// ***************************************************************************
// Returns a 1-cm sided box filled with G4_Galactic.
// ***************************************************************************
G4VPhysicalVolume* DetectorConstruction::Construct() {
G4Box* const worldSolid = new G4Box("World", 1.*CLHEP::cm, 1.*CLHEP::cm, 1.*CLHEP::cm);
G4VPhysicalVolume* DetectorConstruction::Construct()
{
G4Box* const worldSolid = new G4Box("World", 1. * CLHEP::cm, 1. * CLHEP::cm, 1. * CLHEP::cm);
G4Material* const worldMaterial = G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic");
G4LogicalVolume* const worldLogicalVol = new G4LogicalVolume(worldSolid, worldMaterial, "World");
// NB: G4LogicalVolumeStore owns all logical volumes.
G4VPhysicalVolume* const worldPhysicalVol = new G4PVPlacement(nullptr,
G4ThreeVector(),
worldLogicalVol,
"World",
nullptr,
false,
0);
G4VPhysicalVolume* const worldPhysicalVol =
new G4PVPlacement(nullptr, G4ThreeVector(), worldLogicalVol, "World", nullptr, false, 0);
// NB: G4PhysicalVolumeStore owns all physical volumes.
return worldPhysicalVol;
@@ -35,10 +35,10 @@
//
/// Create a set of profiles for XS study.
///
/// All profiles are G4H1.
/// All profiles are G4H1.
/// They are created and filled via G4VAnalysisManager.
///
/// The profiles can be dumped to all usual formats, including ROOT
/// The profiles can be dumped to all usual formats, including ROOT
/// (via G4VAnalysisManager).
/// They are also dumped in a format compatible with Flair
/// (via tools::histo::flair).
@@ -47,360 +47,257 @@
#include "XSHistoManager.hh"
#include "G4ios.hh"
#include "G4Element.hh"
#include "G4HadronicProcessStore.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4ios.hh"
#include "G4NistManager.hh"
#include "G4Element.hh"
#include "G4Material.hh"
#include "G4HadronicProcessStore.hh"
//#include "G4AnalysisManager.hh"
#include "G4RootAnalysisManager.hh"
// #include "G4AnalysisManager.hh"
#include "tools_histo_flair.hh"
#include "G4RootAnalysisManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
XSHistoManager::XSHistoManager() :
fMessenger(new XSHistoManagerMessenger(this)),
fOutputFileName("all_XS"),
fRootOutputFileName("all_XS.root"),
fFlairOutputFileName("all_XS.hist"),
fParticle(nullptr),
fElement(nullptr),
fMaterial(nullptr),
fNumBins(10000),
fMinKineticEnergy(1.*keV),
fMaxKineticEnergy(10.*TeV),
fFunctionName("none"),
fBinSchemeName("log"),
fRootEnergyUnit("MeV"),
fAnalysisManager(G4RootAnalysisManager::Instance()),
fElasticXSIndex(0),
fInelasticXSIndex(1),
fCaptureXSIndex(2),
fFissionXSIndex(3),
fChargeExchangeXSIndex(4),
fTotalXSIndex(5),
fElasticPerVolumeXSIndex(6),
fInelasticPerVolumeXSIndex(7)
XSHistoManager::XSHistoManager()
: fMessenger(new XSHistoManagerMessenger(this)),
fOutputFileName("all_XS"),
fRootOutputFileName("all_XS.root"),
fFlairOutputFileName("all_XS.hist"),
fParticle(nullptr),
fElement(nullptr),
fMaterial(nullptr),
fNumBins(10000),
fMinKineticEnergy(1. * keV),
fMaxKineticEnergy(10. * TeV),
fFunctionName("none"),
fBinSchemeName("log"),
fRootEnergyUnit("MeV"),
fAnalysisManager(G4RootAnalysisManager::Instance()),
fElasticXSIndex(0),
fInelasticXSIndex(1),
fCaptureXSIndex(2),
fFissionXSIndex(3),
fChargeExchangeXSIndex(4),
fTotalXSIndex(5),
fElasticPerVolumeXSIndex(6),
fInelasticPerVolumeXSIndex(7)
{
//G4NistManager::Instance()->ListMaterials("all");
// G4NistManager::Instance()->ListMaterials("all");
}
// ***************************************************************************
// Set output files names: 2 formats supported, ROOT and Flair.
// ***************************************************************************
void XSHistoManager::SetOutputFileName(const G4String& outputFileName) {
void XSHistoManager::SetOutputFileName(const G4String& outputFileName)
{
fOutputFileName = outputFileName;
fRootOutputFileName = outputFileName + ".root";
fFlairOutputFileName = outputFileName + ".hist";
}
// ***************************************************************************
// Set the particle considered for XS study.
// ***************************************************************************
void XSHistoManager::SetParticle(const G4String& particleName) {
void XSHistoManager::SetParticle(const G4String& particleName)
{
fParticle = G4ParticleTable::GetParticleTable()->FindParticle(particleName);
}
// ***************************************************************************
// Set the target element considered for XS study.
// ***************************************************************************
void XSHistoManager::SetElement(const G4String& elementName) {
void XSHistoManager::SetElement(const G4String& elementName)
{
fElement = G4NistManager::Instance()->FindOrBuildElement(elementName);
// Also needs to set material!
SetMaterial(elementName);
}
// ***************************************************************************
// Set the target material considered for XS study.
// ***************************************************************************
void XSHistoManager::SetMaterial(const G4String& materialName) {
void XSHistoManager::SetMaterial(const G4String& materialName)
{
// Check that material is not set already.
if (fMaterial) {
G4ExceptionDescription msg;
msg << "Please use UI command /allXS/elementName"
<< " OR UI command /allXS/nonElementaryMaterialName,"
<< " BUT NOT BOTH!"
<< G4endl;
G4Exception("XSHistoManager::SetMaterial",
"A target material is already defined.",
FatalException,
msg);
<< " BUT NOT BOTH!" << G4endl;
G4Exception("XSHistoManager::SetMaterial", "A target material is already defined.",
FatalException, msg);
}
fMaterial = G4NistManager::Instance()->FindOrBuildMaterial("G4_" + materialName);
}
// ***************************************************************************
// Open output file + create all profiles considered for XS study.
// All profiles are G4H1, created via G4VAnalysisManager.
// ***************************************************************************
void XSHistoManager::Book() {
void XSHistoManager::Book()
{
// Check all XSHistoManager data is set properly.
CheckInput();
// Open file.
if (!fAnalysisManager->OpenFile(fRootOutputFileName)) {
G4ExceptionDescription msg;
msg << "Booking profiles: cannot open file " << fRootOutputFileName
<< G4endl;
G4Exception("XSHistoManager::Book",
"Cannot open file",
FatalException,
msg);
msg << "Booking profiles: cannot open file " << fRootOutputFileName << G4endl;
G4Exception("XSHistoManager::Book", "Cannot open file", FatalException, msg);
}
G4cout << "### XSHistoManager::Book: Successfully opened file "
<< fRootOutputFileName
<< " for dumping profiles."
<< G4endl;
G4cout << "### XSHistoManager::Book: Successfully opened file " << fRootOutputFileName
<< " for dumping profiles." << G4endl;
// Create all G4H1, and keep track of each histo index in fXSProfileIndex.
const G4int elasticXSProfileIndex = fAnalysisManager->CreateH1("ElasticXS",
"Elastic XS",
fNumBins,
fMinKineticEnergy,
fMaxKineticEnergy,
fRootEnergyUnit,
fFunctionName,
fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fElasticXSIndex,
elasticXSProfileIndex));
const G4int elasticXSProfileIndex =
fAnalysisManager->CreateH1("ElasticXS", "Elastic XS", fNumBins, fMinKineticEnergy,
fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fElasticXSIndex, elasticXSProfileIndex));
const G4int inelasticXSProfileIndex = fAnalysisManager->CreateH1("InelasticXS",
"Inelastic XS",
fNumBins,
fMinKineticEnergy,
fMaxKineticEnergy,
fRootEnergyUnit,
fFunctionName,
fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fInelasticXSIndex,
inelasticXSProfileIndex));
const G4int inelasticXSProfileIndex =
fAnalysisManager->CreateH1("InelasticXS", "Inelastic XS", fNumBins, fMinKineticEnergy,
fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fInelasticXSIndex, inelasticXSProfileIndex));
const G4int captureXSProfileIndex = fAnalysisManager->CreateH1("CaptureXS",
"Capture XS",
fNumBins,
fMinKineticEnergy,
fMaxKineticEnergy,
fRootEnergyUnit,
fFunctionName,
fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fCaptureXSIndex,
captureXSProfileIndex));
const G4int captureXSProfileIndex =
fAnalysisManager->CreateH1("CaptureXS", "Capture XS", fNumBins, fMinKineticEnergy,
fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fCaptureXSIndex, captureXSProfileIndex));
const G4int fissionXSProfileIndex = fAnalysisManager->CreateH1("FissionXS",
"Fission XS",
fNumBins,
fMinKineticEnergy,
fMaxKineticEnergy,
fRootEnergyUnit,
fFunctionName,
fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fFissionXSIndex,
fissionXSProfileIndex));
const G4int fissionXSProfileIndex =
fAnalysisManager->CreateH1("FissionXS", "Fission XS", fNumBins, fMinKineticEnergy,
fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fFissionXSIndex, fissionXSProfileIndex));
const G4int chargeExchangeXSProfileIndex = fAnalysisManager->CreateH1("ChargeExchangeXS",
"Charge exchange XS",
fNumBins,
fMinKineticEnergy,
fMaxKineticEnergy,
fRootEnergyUnit,
fFunctionName,
fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fChargeExchangeXSIndex,
chargeExchangeXSProfileIndex));
const G4int chargeExchangeXSProfileIndex = fAnalysisManager->CreateH1(
"ChargeExchangeXS", "Charge exchange XS", fNumBins, fMinKineticEnergy, fMaxKineticEnergy,
fRootEnergyUnit, fFunctionName, fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fChargeExchangeXSIndex, chargeExchangeXSProfileIndex));
const G4int totalXSProfileIndex = fAnalysisManager->CreateH1("TotalXS",
"Total XS",
fNumBins,
fMinKineticEnergy,
fMaxKineticEnergy,
fRootEnergyUnit,
fFunctionName,
fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fTotalXSIndex,
totalXSProfileIndex));
const G4int totalXSProfileIndex =
fAnalysisManager->CreateH1("TotalXS", "Total XS", fNumBins, fMinKineticEnergy,
fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fTotalXSIndex, totalXSProfileIndex));
const G4int elasticPerVolumeXSProfileIndex = fAnalysisManager->CreateH1("ElasticPerVolumeXS",
"Elastic XS per volume",
fNumBins,
fMinKineticEnergy,
fMaxKineticEnergy,
fRootEnergyUnit,
fFunctionName,
fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fElasticPerVolumeXSIndex,
elasticPerVolumeXSProfileIndex));
const G4int elasticPerVolumeXSProfileIndex = fAnalysisManager->CreateH1(
"ElasticPerVolumeXS", "Elastic XS per volume", fNumBins, fMinKineticEnergy, fMaxKineticEnergy,
fRootEnergyUnit, fFunctionName, fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fElasticPerVolumeXSIndex, elasticPerVolumeXSProfileIndex));
const G4int inelasticPerVolumeXSProfileIndex =
fAnalysisManager->CreateH1("InelasticPerVolumeXS",
"Inelastic XS per volume",
fNumBins,
fMinKineticEnergy,
fMaxKineticEnergy,
fRootEnergyUnit,
fFunctionName,
fBinSchemeName);
fXSProfileIndex.insert(std::make_pair(fInelasticPerVolumeXSIndex,
inelasticPerVolumeXSProfileIndex));
const G4int inelasticPerVolumeXSProfileIndex = fAnalysisManager->CreateH1(
"InelasticPerVolumeXS", "Inelastic XS per volume", fNumBins, fMinKineticEnergy,
fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
fXSProfileIndex.insert(
std::make_pair(fInelasticPerVolumeXSIndex, inelasticPerVolumeXSProfileIndex));
}
// ***************************************************************************
// Fill all plots, then dump them into relevant formats.
// ***************************************************************************
void XSHistoManager::EndOfRun() {
G4cout << "### XSHistoManager::EndOfRun: Compute & fill XS for "
<< fParticle->GetParticleName()
<< " in " << (fElement ? fElement->GetName() : fMaterial->GetName())
<< G4endl;
void XSHistoManager::EndOfRun()
{
G4cout << "### XSHistoManager::EndOfRun: Compute & fill XS for " << fParticle->GetParticleName()
<< " in " << (fElement ? fElement->GetName() : fMaterial->GetName()) << G4endl;
G4HadronicProcessStore* const store = G4HadronicProcessStore::Instance();
G4HadronicProcessStore* const store = G4HadronicProcessStore::Instance();
// Fill XS profiles.
const G4double logMinKineticEnergy = std::log10(fMinKineticEnergy);
const G4double logMaxKineticEnergy = std::log10(fMaxKineticEnergy);
const G4double deltaLogKineticEnergy =
(logMaxKineticEnergy - logMinKineticEnergy) / fNumBins;
// Fill XS profiles.
const G4double logMinKineticEnergy = std::log10(fMinKineticEnergy);
const G4double logMaxKineticEnergy = std::log10(fMaxKineticEnergy);
const G4double deltaLogKineticEnergy = (logMaxKineticEnergy - logMinKineticEnergy) / fNumBins;
G4double logKineticEnergy = logMinKineticEnergy - deltaLogKineticEnergy/2.;
// Loop on all kinetic energies of interest.
for (G4int binIndex = 0; binIndex < fNumBins; ++binIndex) {
G4double logKineticEnergy = logMinKineticEnergy - deltaLogKineticEnergy / 2.;
logKineticEnergy += deltaLogKineticEnergy;
const G4double kineticEnergy = std::pow(10., logKineticEnergy) * MeV;
// Loop on all kinetic energies of interest.
for (G4int binIndex = 0; binIndex < fNumBins; ++binIndex) {
logKineticEnergy += deltaLogKineticEnergy;
const G4double kineticEnergy = std::pow(10., logKineticEnergy) * MeV;
G4double totalXS = 0.;
if (fElement) {
// ELASTIC (ELEMENTARY MATERIAL)
const G4double elasticXS = store->GetElasticCrossSectionPerAtom(fParticle,
kineticEnergy,
fElement,
fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fElasticXSIndex],
kineticEnergy,
elasticXS/barn);
totalXS += elasticXS;
// INELASTIC (ELEMENTARY MATERIAL)
const G4double inelasticXS = store->GetInelasticCrossSectionPerAtom(fParticle,
kineticEnergy,
fElement,
fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fInelasticXSIndex],
kineticEnergy,
inelasticXS/barn);
totalXS += inelasticXS;
G4double totalXS = 0.;
if (fElement) {
// ELASTIC (ELEMENTARY MATERIAL)
const G4double elasticXS =
store->GetElasticCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fElasticXSIndex], kineticEnergy, elasticXS / barn);
totalXS += elasticXS;
if (fParticle == G4Neutron::Definition()) {
// NEUTRON CAPTURE (ELEMENTARY MATERIAL)
const G4double captureXS = store->GetCaptureCrossSectionPerAtom(fParticle,
kineticEnergy,
fElement,
fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fCaptureXSIndex],
kineticEnergy,
captureXS/barn);
totalXS += captureXS;
// FISSION (ELEMENTARY MATERIAL)
const G4double fissionXS = store->GetFissionCrossSectionPerAtom(fParticle,
kineticEnergy,
fElement,
fMaterial);
totalXS += fissionXS;
fAnalysisManager->FillH1(fXSProfileIndex[fFissionXSIndex],
kineticEnergy,
fissionXS/barn);
}
// INELASTIC (ELEMENTARY MATERIAL)
const G4double inelasticXS =
store->GetInelasticCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fInelasticXSIndex], kineticEnergy,
inelasticXS / barn);
totalXS += inelasticXS;
// CHARGE EXCHANGE (ELEMENTARY MATERIAL)
const G4double chargeExchangeXS =
store->GetChargeExchangeCrossSectionPerAtom(fParticle,
kineticEnergy,
fElement,
fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fChargeExchangeXSIndex],
kineticEnergy,
chargeExchangeXS/barn);
totalXS += chargeExchangeXS;
// TOTAL (ELEMENTARY MATERIAL)
fAnalysisManager->FillH1(fXSProfileIndex[fTotalXSIndex],
kineticEnergy,
totalXS/barn);
}
if (fParticle == G4Neutron::Definition()) {
// NEUTRON CAPTURE (ELEMENTARY MATERIAL)
const G4double captureXS =
store->GetCaptureCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fCaptureXSIndex], kineticEnergy, captureXS / barn);
totalXS += captureXS;
if (fMaterial) {
const G4double materialSurfacicDensity = (fMaterial ?
fMaterial->GetDensity() / (g/cm2)
: 1.);
// FISSION (ELEMENTARY MATERIAL)
const G4double fissionXS =
store->GetFissionCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
totalXS += fissionXS;
fAnalysisManager->FillH1(fXSProfileIndex[fFissionXSIndex], kineticEnergy, fissionXS / barn);
}
// ELASTIC
const G4double elasticPerVolumeXS =
store->GetElasticCrossSectionPerVolume(fParticle,
kineticEnergy,
fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fElasticPerVolumeXSIndex],
kineticEnergy,
elasticPerVolumeXS/materialSurfacicDensity);
// CHARGE EXCHANGE (ELEMENTARY MATERIAL)
const G4double chargeExchangeXS =
store->GetChargeExchangeCrossSectionPerAtom(fParticle, kineticEnergy, fElement, fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fChargeExchangeXSIndex], kineticEnergy,
chargeExchangeXS / barn);
totalXS += chargeExchangeXS;
// INELASTIC
const G4double inelasticPerVolumeXS =
store->GetInelasticCrossSectionPerVolume(fParticle,
kineticEnergy,
fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fInelasticPerVolumeXSIndex],
kineticEnergy,
inelasticPerVolumeXS/materialSurfacicDensity);
}
// TOTAL (ELEMENTARY MATERIAL)
fAnalysisManager->FillH1(fXSProfileIndex[fTotalXSIndex], kineticEnergy, totalXS / barn);
}
}
if (fMaterial) {
const G4double materialSurfacicDensity =
(fMaterial ? fMaterial->GetDensity() / (g / cm2) : 1.);
// ELASTIC
const G4double elasticPerVolumeXS =
store->GetElasticCrossSectionPerVolume(fParticle, kineticEnergy, fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fElasticPerVolumeXSIndex], kineticEnergy,
elasticPerVolumeXS / materialSurfacicDensity);
// DUMP G4H1 PLOTS INTO ROOT FILE
DumpAllG4H1IntoRootFile();
// INELASTIC
const G4double inelasticPerVolumeXS =
store->GetInelasticCrossSectionPerVolume(fParticle, kineticEnergy, fMaterial);
fAnalysisManager->FillH1(fXSProfileIndex[fInelasticPerVolumeXSIndex], kineticEnergy,
inelasticPerVolumeXS / materialSurfacicDensity);
}
}
// DUMP G4H1 PLOTS INTO FLAIR FILE
DumpAllG4H1IntoFlairFile();
// DUMP G4H1 PLOTS INTO ROOT FILE
DumpAllG4H1IntoRootFile();
// DUMP G4H1 PLOTS INTO FLAIR FILE
DumpAllG4H1IntoFlairFile();
// Close and clear fAnalysisManager.
fAnalysisManager->CloseFile();
fAnalysisManager->Clear();
// Close and clear fAnalysisManager.
fAnalysisManager->CloseFile();
fAnalysisManager->Clear();
}
// ***************************************************************************
// Checks that particle and material are set
// Checks that particle and material are set
// (all others have relevant default values).
// ***************************************************************************
void XSHistoManager::CheckInput() {
void XSHistoManager::CheckInput()
{
if (!fParticle) {
G4ExceptionDescription msg;
msg << "Please add a particle to study XS: UI command /allXS/particleName"
<< G4endl;
G4Exception("XSHistoManager::CheckInput()",
"Print XS: no input particle defined.",
FatalException,
msg);
msg << "Please add a particle to study XS: UI command /allXS/particleName" << G4endl;
G4Exception("XSHistoManager::CheckInput()", "Print XS: no input particle defined.",
FatalException, msg);
}
if (!fMaterial) {
@@ -409,51 +306,40 @@ void XSHistoManager::CheckInput() {
<< " UI command /allXS/elementName for an elementary material,"
<< " or UI command /allXS/nonElementaryMaterialName for a compound/mixture material."
<< G4endl;
G4Exception("XSHistoManager::CheckInput()",
"Print XS: no target material defined.",
FatalException,
msg);
G4Exception("XSHistoManager::CheckInput()", "Print XS: no target material defined.",
FatalException, msg);
}
}
// ***************************************************************************
// DUMP G4H1 PLOTS INTO ROOT FILE (via G4VAnalysisManager).
// ***************************************************************************
void XSHistoManager::DumpAllG4H1IntoRootFile() const {
if (!fAnalysisManager->Write()) {
G4ExceptionDescription message;
message << "Could not write ROOT file.";
G4Exception("XSHistoManager::EndOfRun()",
"I/O Error",
FatalException,
message);
}
G4cout << "### All profiles saved to " << fRootOutputFileName << G4endl;
void XSHistoManager::DumpAllG4H1IntoRootFile() const
{
if (!fAnalysisManager->Write()) {
G4ExceptionDescription message;
message << "Could not write ROOT file.";
G4Exception("XSHistoManager::EndOfRun()", "I/O Error", FatalException, message);
}
G4cout << "### All profiles saved to " << fRootOutputFileName << G4endl;
}
// ***************************************************************************
// DUMP G4H1 PLOTS INTO FLAIR FILE (via tools::histo::flair).
// ***************************************************************************
void XSHistoManager::DumpAllG4H1IntoFlairFile() const {
void XSHistoManager::DumpAllG4H1IntoFlairFile() const
{
std::ofstream output;
output.open(fFlairOutputFileName, std::ios_base::out);
auto const rootAnalysisManager = dynamic_cast<G4RootAnalysisManager*>(fAnalysisManager);
G4int indexInOutputFile = 1;
for (G4int xsIndex = fElasticXSIndex; xsIndex <= fInelasticPerVolumeXSIndex; ++xsIndex) {
const G4int histoIndex = fXSProfileIndex.at(xsIndex);
const G4String& histoName = fAnalysisManager->GetH1Name(histoIndex);
const auto& histo = rootAnalysisManager->GetH1(histoIndex);
tools::histo::flair::dumpG4H1ProfileInFlairFormat(output,
indexInOutputFile,
histoName,
histo,
tools::histo::flair::dumpG4H1ProfileInFlairFormat(output, indexInOutputFile, histoName, histo,
tools::histo::flair::Abscissa::KineticEnergy,
fBinSchemeName);
++indexInOutputFile;
@@ -40,7 +40,6 @@
#include "XSHistoManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
XSHistoManagerMessenger::XSHistoManagerMessenger(XSHistoManager* const histoManager)
@@ -54,15 +53,15 @@ XSHistoManagerMessenger::XSHistoManagerMessenger(XSHistoManager* const histoMana
fMaxKineticEnergyCmd(G4UIcmdWithADoubleAndUnit("/allXS/maxKineticEnergy", this))
{
fOutputFileNameCmd.SetGuidance("Set output file name (histograms).");
fParticleNameCmd.SetGuidance("Set particle name.");
fParticleNameCmd.SetParameterName("particleName", false);
fParticleNameCmd.AvailableForStates(G4State_PreInit, G4State_Idle);
fElementNameCmd.SetGuidance("Set target element name.");
fElementNameCmd.SetParameterName("elementName", false);
fElementNameCmd.AvailableForStates(G4State_PreInit, G4State_Idle);
fNonElementaryMaterialNameCmd.SetGuidance("Set target material name (in case not elementary).");
fNonElementaryMaterialNameCmd.SetParameterName("nonElementaryMaterialName", false);
fNonElementaryMaterialNameCmd.AvailableForStates(G4State_PreInit, G4State_Idle);
@@ -70,7 +69,7 @@ XSHistoManagerMessenger::XSHistoManagerMessenger(XSHistoManager* const histoMana
fNumBinsCmd.SetGuidance("Set number of bins in kinetic energy.");
fNumBinsCmd.SetParameterName("numBins", false);
fNumBinsCmd.AvailableForStates(G4State_PreInit, G4State_Idle);
fMinKineticEnergyCmd.SetGuidance("Set min kinetic energy");
fMinKineticEnergyCmd.SetParameterName("MinKineticEnergy", false);
fMinKineticEnergyCmd.SetUnitCategory("Energy");
@@ -84,8 +83,8 @@ XSHistoManagerMessenger::XSHistoManagerMessenger(XSHistoManager* const histoMana
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void XSHistoManagerMessenger::SetNewValue(G4UIcommand* command, G4String value) {
void XSHistoManagerMessenger::SetNewValue(G4UIcommand* command, G4String value)
{
if (command == &fOutputFileNameCmd) {
fHisto->SetOutputFileName(value);
}
@@ -101,10 +100,10 @@ void XSHistoManagerMessenger::SetNewValue(G4UIcommand* command, G4String value)
else if (command == &fNumBinsCmd) {
fHisto->SetNumberOfBins(fNumBinsCmd.GetNewIntValue(value));
}
else if (command == &fMinKineticEnergyCmd) {
else if (command == &fMinKineticEnergyCmd) {
fHisto->SetMinKinEnergy(fMinKineticEnergyCmd.GetNewDoubleValue(value));
}
else if (command == &fMaxKineticEnergyCmd) {
else if (command == &fMaxKineticEnergyCmd) {
fHisto->SetMaxKinEnergy(fMaxKineticEnergyCmd.GetNewDoubleValue(value));
}
}
@@ -36,15 +36,15 @@
// HadNucIneEvents
//
/// This program is an adaptation of Hadr09 example.
/// It offers all Hadr09 features, and adds the possibility of
/// It offers all Hadr09 features, and adds the possibility of
/// accessing hadron-nucleus inelastic interactions final states from FLUKA.
///
/// With respect to the Hadr09 example,
/// With respect to the Hadr09 example,
/// the program also adds the possibility of plotting the final state:
/// all encountered secondaries spectra are automatically plotted,
/// as well as the residual nuclei distributions.
/// All plots (created via the G4 analysis manager) can be dumped
/// to any of the usually supported formats (e.g. ROOT format),
/// All plots (created via the G4 analysis manager) can be dumped
/// to any of the usually supported formats (e.g. ROOT format),
/// but also in a Flair-compatible format.
///
/// The final states (i.e. secondary particles) produced by
@@ -79,10 +79,10 @@
/// of a G4VParticleChange object).
///
/// Here by default, an already well-defined type of hadron-nucleus
/// inelastic collision is selected
/// (specific hadron, at a given kinetic energy and direction,
/// on a specific material).
/// The initial random seed is not set randomly,
/// inelastic collision is selected
/// (specific hadron, at a given kinetic energy and direction,
/// on a specific material).
/// The initial random seed is not set randomly,
/// so that results are reproducible from one simulation to the next.
///
/// Use: build/HadNucIneEvents
@@ -92,31 +92,31 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include <chrono>
#include <iomanip>
#include "globals.hh"
#include "G4ios.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4VParticleChange.hh"
#include "G4UnitsTable.hh"
#include "G4SystemOfUnits.hh"
#include "HadronicGenerator.hh"
#include "G4GenericIon.hh"
#include "G4ProcessManager.hh"
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
#include "CLHEP/Random/Randomize.h"
#include "CLHEP/Random/Ranlux64Engine.h"
#include "FinalStateHistoManager.hh"
#include "HadronicGenerator.hh"
#include "G4GenericIon.hh"
#include "G4IonTable.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
#include "G4ParticleTable.hh"
#include "G4PhysicalConstants.hh"
#include "G4ProcessManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4UnitsTable.hh"
#include "G4VParticleChange.hh"
#include "G4ios.hh"
#include "globals.hh"
#include <chrono>
#include <iomanip>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4int main(G4int argc, char** argv) {
G4int main(G4int argc, char** argv)
{
G4cout << "=== Test of the HadronicGenerator ===" << G4endl;
// See the HadronicGenerator class for the possibilities and meaning of the "physics cases".
@@ -126,27 +126,27 @@ G4int main(G4int argc, char** argv) {
//***LOOKHERE*** PHYSICS CASE
G4String namePhysics = "CFLUKAHI";
//const G4String namePhysics = "FTFP_BERT";
//const G4String namePhysics = "FTFP_BERT_ATL";
//const G4String namePhysics = "QGSP_BERT";
//const G4String namePhysics = "QGSP_BIC";
//const G4String namePhysics = "FTFP_INCLXX";
//const G4String namePhysics = "FTFP";
//const G4String namePhysics = "QGSP";
//const G4String namePhysics = "BERT";
//const G4String namePhysics = "BIC";
//const G4String namePhysics = "IonBIC";
//const G4String namePhysics = "INCL";
// const G4String namePhysics = "FTFP_BERT";
// const G4String namePhysics = "FTFP_BERT_ATL";
// const G4String namePhysics = "QGSP_BERT";
// const G4String namePhysics = "QGSP_BIC";
// const G4String namePhysics = "FTFP_INCLXX";
// const G4String namePhysics = "FTFP";
// const G4String namePhysics = "QGSP";
// const G4String namePhysics = "BERT";
// const G4String namePhysics = "BIC";
// const G4String namePhysics = "IonBIC";
// const G4String namePhysics = "INCL";
// The kinetic energy of the projectile will be sampled randomly, with flat probability
// in the interval [minEnergy, maxEnergy].
G4double minEnergy = 7.*CLHEP::TeV; //***LOOKHERE*** HADRON PROJECTILE MIN Ekin
G4double maxEnergy = 7.*CLHEP::TeV; //***LOOKHERE*** HADRON PROJECTILE MAX Ekin
G4int numCollisions = 100000; //***LOOKHERE*** NUMBER OF COLLISIONS
//const G4int numCollisions = 100; // DEBUG
G4double minEnergy = 7. * CLHEP::TeV; //***LOOKHERE*** HADRON PROJECTILE MIN Ekin
G4double maxEnergy = 7. * CLHEP::TeV; //***LOOKHERE*** HADRON PROJECTILE MAX Ekin
// IMPORTANT - TESTING ONLY:
G4int numCollisions = 100000; //***LOOKHERE*** NUMBER OF COLLISIONS
// const G4int numCollisions = 100; // DEBUG
// IMPORTANT - TESTING ONLY:
// OVERWRITES DEFAULT PHYSICS CASE AND NUMBER OF EVENTS
std::vector<G4String> args(argv, argv + argc);
if (args.size() == 2 && args[1] == "--test") {
@@ -157,170 +157,167 @@ G4int main(G4int argc, char** argv) {
// Enable or disable the print out of this program: if enabled, the number of secondaries
// produced in each collisions is printed out; moreover, once every "printingGap"
// collisions, the list of secondaries is printed out.
const G4bool isPrintingEnabled = true; //***LOOKHERE*** PRINT OUT ON/OFF
const G4int printingGap = 100; //***LOOKHERE*** GAP IN PRINTING
const G4bool isPrintingEnabled = true; //***LOOKHERE*** PRINT OUT ON/OFF
const G4int printingGap = 100; //***LOOKHERE*** GAP IN PRINTING
// Vector of Geant4 names of hadron projectiles: one of this will be sampled randomly
// (with uniform probability) for each collision, when the projectile is not an ion.
// Note: comment out the corresponding line in order to exclude a particle.
std::vector< G4String > vecProjectiles; //***LOOKHERE*** POSSIBLE HADRON PROJECTILES
//vecProjectiles.push_back( "pi-" );
//Note: vecProjectiles.push_back( "pi0" ); // Excluded because too short-lived
//vecProjectiles.push_back( "pi+" );
//vecProjectiles.push_back( "kaon-" );
//vecProjectiles.push_back( "kaon+" );
//vecProjectiles.push_back( "kaon0L" );
//vecProjectiles.push_back( "kaon0S" );
//Note: vecProjectiles.push_back( "eta" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "eta_prime" ); // Excluded because too short-lived
vecProjectiles.push_back( "proton" );
//vecProjectiles.push_back( "neutron" );
//vecProjectiles.push_back( "deuteron" );
//vecProjectiles.push_back( "triton" );
//vecProjectiles.push_back( "He3" );
//vecProjectiles.push_back( "alpha" );
//vecProjectiles.push_back( "lambda" );
//vecProjectiles.push_back( "sigma-" );
//Note: vecProjectiles.push_back( "sigma0" ); // Excluded because too short-lived
//vecProjectiles.push_back( "sigma+" );
//vecProjectiles.push_back( "xi-" );
//vecProjectiles.push_back( "xi0" );
//vecProjectiles.push_back( "omega-" );
//vecProjectiles.push_back( "anti_proton" );
//vecProjectiles.push_back( "anti_neutron" );
//vecProjectiles.push_back( "anti_lambda" );
//vecProjectiles.push_back( "anti_sigma-" );
//Note: vecProjectiles.push_back( "anti_sigma0" ); // Excluded because too short-lived
//vecProjectiles.push_back( "anti_sigma+" );
//vecProjectiles.push_back( "anti_xi-" );
//vecProjectiles.push_back( "anti_xi0" );
//vecProjectiles.push_back( "anti_omega-" );
//vecProjectiles.push_back( "anti_deuteron" );
//vecProjectiles.push_back( "anti_triton" );
//vecProjectiles.push_back( "anti_He3" );
//vecProjectiles.push_back( "anti_alpha" );
// Charm and bottom hadrons
//vecProjectiles.push_back( "D+" );
//vecProjectiles.push_back( "D-" );
//vecProjectiles.push_back( "D0" );
//vecProjectiles.push_back( "anti_D0" );
//vecProjectiles.push_back( "Ds+" );
//vecProjectiles.push_back( "Ds-" );
//Note: vecProjectiles.push_back( "etac" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "J/psi" ); // Excluded because too short-lived
//vecProjectiles.push_back( "B+" );
//vecProjectiles.push_back( "B-" );
//vecProjectiles.push_back( "B0" );
//vecProjectiles.push_back( "anti_B0" );
//vecProjectiles.push_back( "Bs0" );
//vecProjectiles.push_back( "anti_Bs0" );
//vecProjectiles.push_back( "Bc+" );
//vecProjectiles.push_back( "Bc-" );
//Note: vecProjectiles.push_back( "Upsilon" ); // Excluded because too short-lived
//vecProjectiles.push_back( "lambda_c+" );
//vecProjectiles.push_back( "anti_lambda_c+" );
//Note: vecProjectiles.push_back( "sigma_c+" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "anti_sigma_c+" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "sigma_c0" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "anti_sigma_c0" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "sigma_c++" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "anti_sigma_c++" ); // Excluded because too short-lived
//vecProjectiles.push_back( "xi_c+" );
//vecProjectiles.push_back( "anti_xi_c+" );
//vecProjectiles.push_back( "xi_c0" );
//vecProjectiles.push_back( "anti_xi_c0" );
//vecProjectiles.push_back( "omega_c0" );
//vecProjectiles.push_back( "anti_omega_c0" );
//vecProjectiles.push_back( "lambda_b" );
//vecProjectiles.push_back( "anti_lambda_b" );
//Note: vecProjectiles.push_back( "sigma_b+" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "anti_sigma_b+" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "sigma_b0" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "sigma_b0" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "sigma_b-" ); // Excluded because too short-lived
//Note: vecProjectiles.push_back( "anti_sigma_b-" ); // Excluded because too short-lived
//vecProjectiles.push_back( "xi_b0" );
//vecProjectiles.push_back( "anti_xi_b0" );
//vecProjectiles.push_back( "xi_b-" );
//vecProjectiles.push_back( "anti_xi_b-" );
//vecProjectiles.push_back( "omega_b-" );
//vecProjectiles.push_back( "anti_omega_b-" );
std::vector<G4String> vecProjectiles; //***LOOKHERE*** POSSIBLE HADRON PROJECTILES
// vecProjectiles.push_back( "pi-" );
// Note: vecProjectiles.push_back( "pi0" ); // Excluded because too short-lived
// vecProjectiles.push_back( "pi+" );
// vecProjectiles.push_back( "kaon-" );
// vecProjectiles.push_back( "kaon+" );
// vecProjectiles.push_back( "kaon0L" );
// vecProjectiles.push_back( "kaon0S" );
// Note: vecProjectiles.push_back( "eta" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "eta_prime" ); // Excluded because too short-lived
vecProjectiles.push_back("proton");
// vecProjectiles.push_back( "neutron" );
// vecProjectiles.push_back( "deuteron" );
// vecProjectiles.push_back( "triton" );
// vecProjectiles.push_back( "He3" );
// vecProjectiles.push_back( "alpha" );
// vecProjectiles.push_back( "lambda" );
// vecProjectiles.push_back( "sigma-" );
// Note: vecProjectiles.push_back( "sigma0" ); // Excluded because too short-lived
// vecProjectiles.push_back( "sigma+" );
// vecProjectiles.push_back( "xi-" );
// vecProjectiles.push_back( "xi0" );
// vecProjectiles.push_back( "omega-" );
// vecProjectiles.push_back( "anti_proton" );
// vecProjectiles.push_back( "anti_neutron" );
// vecProjectiles.push_back( "anti_lambda" );
// vecProjectiles.push_back( "anti_sigma-" );
// Note: vecProjectiles.push_back( "anti_sigma0" ); // Excluded because too short-lived
// vecProjectiles.push_back( "anti_sigma+" );
// vecProjectiles.push_back( "anti_xi-" );
// vecProjectiles.push_back( "anti_xi0" );
// vecProjectiles.push_back( "anti_omega-" );
// vecProjectiles.push_back( "anti_deuteron" );
// vecProjectiles.push_back( "anti_triton" );
// vecProjectiles.push_back( "anti_He3" );
// vecProjectiles.push_back( "anti_alpha" );
// Charm and bottom hadrons
// vecProjectiles.push_back( "D+" );
// vecProjectiles.push_back( "D-" );
// vecProjectiles.push_back( "D0" );
// vecProjectiles.push_back( "anti_D0" );
// vecProjectiles.push_back( "Ds+" );
// vecProjectiles.push_back( "Ds-" );
// Note: vecProjectiles.push_back( "etac" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "J/psi" ); // Excluded because too short-lived
// vecProjectiles.push_back( "B+" );
// vecProjectiles.push_back( "B-" );
// vecProjectiles.push_back( "B0" );
// vecProjectiles.push_back( "anti_B0" );
// vecProjectiles.push_back( "Bs0" );
// vecProjectiles.push_back( "anti_Bs0" );
// vecProjectiles.push_back( "Bc+" );
// vecProjectiles.push_back( "Bc-" );
// Note: vecProjectiles.push_back( "Upsilon" ); // Excluded because too short-lived
// vecProjectiles.push_back( "lambda_c+" );
// vecProjectiles.push_back( "anti_lambda_c+" );
// Note: vecProjectiles.push_back( "sigma_c+" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "anti_sigma_c+" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "sigma_c0" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "anti_sigma_c0" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "sigma_c++" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "anti_sigma_c++" ); // Excluded because too short-lived
// vecProjectiles.push_back( "xi_c+" );
// vecProjectiles.push_back( "anti_xi_c+" );
// vecProjectiles.push_back( "xi_c0" );
// vecProjectiles.push_back( "anti_xi_c0" );
// vecProjectiles.push_back( "omega_c0" );
// vecProjectiles.push_back( "anti_omega_c0" );
// vecProjectiles.push_back( "lambda_b" );
// vecProjectiles.push_back( "anti_lambda_b" );
// Note: vecProjectiles.push_back( "sigma_b+" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "anti_sigma_b+" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "sigma_b0" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "sigma_b0" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "sigma_b-" ); // Excluded because too short-lived
// Note: vecProjectiles.push_back( "anti_sigma_b-" ); // Excluded because too short-lived
// vecProjectiles.push_back( "xi_b0" );
// vecProjectiles.push_back( "anti_xi_b0" );
// vecProjectiles.push_back( "xi_b-" );
// vecProjectiles.push_back( "anti_xi_b-" );
// vecProjectiles.push_back( "omega_b-" );
// vecProjectiles.push_back( "anti_omega_b-" );
G4ParticleDefinition* projectileNucleus = nullptr;
G4GenericIon* gion = G4GenericIon::GenericIon();
gion->SetProcessManager( new G4ProcessManager( gion ) );
gion->SetProcessManager(new G4ProcessManager(gion));
G4ParticleTable* partTable = G4ParticleTable::GetParticleTable();
G4IonTable* ions = partTable->GetIonTable();
partTable->SetReadiness();
ions->CreateAllIon();
ions->CreateAllIsomer();
//***LOOKHERE*** HADRON (false) OR ION (true) PROJECTILE ?
const G4bool isProjectileIon = false;
if ( isProjectileIon ) {
minEnergy = 40.0*13.0*CLHEP::GeV; //***LOOKHERE*** ION PROJECTILE MIN Ekin
maxEnergy = 40.0*13.0*CLHEP::GeV; //***LOOKHERE*** ION PROJECTILE MAX Ekin
G4int ionZ = 18, ionA = 40; //***LOOKHERE*** ION PROJECTILE (Z, A)
projectileNucleus = partTable->GetIonTable()->GetIon( ionZ, ionA, 0.0 );
if (isProjectileIon) {
minEnergy = 40.0 * 13.0 * CLHEP::GeV; //***LOOKHERE*** ION PROJECTILE MIN Ekin
maxEnergy = 40.0 * 13.0 * CLHEP::GeV; //***LOOKHERE*** ION PROJECTILE MAX Ekin
G4int ionZ = 18, ionA = 40; //***LOOKHERE*** ION PROJECTILE (Z, A)
projectileNucleus = partTable->GetIonTable()->GetIon(ionZ, ionA, 0.0);
}
// Vector of Geant4 NIST names of materials: one of this will be sampled randomly
// (with uniform probability) for each collision and used as target material.
// Note: comment out the corresponding line in order to exclude a material;
// or, vice versa, add a new line to extend the list with another material.
std::vector< G4String > vecMaterials; //***LOOKHERE*** : NIST TARGET MATERIALS
//vecMaterials.push_back( "G4_H" );
//vecMaterials.push_back( "G4_He" );
//vecMaterials.push_back( "G4_Be" );
vecMaterials.push_back( "G4_C" );
//vecMaterials.push_back( "G4_Al" );
//vecMaterials.push_back( "G4_Si" );
//vecMaterials.push_back( "G4_Sc" );
//vecMaterials.push_back( "G4_Ar" );
//vecMaterials.push_back( "G4_Fe" );
//vecMaterials.push_back( "G4_Cu" );
//vecMaterials.push_back( "G4_W" );
//vecMaterials.push_back( "G4_Pb" );
std::vector<G4String> vecMaterials; //***LOOKHERE*** : NIST TARGET MATERIALS
// vecMaterials.push_back( "G4_H" );
// vecMaterials.push_back( "G4_He" );
// vecMaterials.push_back( "G4_Be" );
vecMaterials.push_back("G4_C");
// vecMaterials.push_back( "G4_Al" );
// vecMaterials.push_back( "G4_Si" );
// vecMaterials.push_back( "G4_Sc" );
// vecMaterials.push_back( "G4_Ar" );
// vecMaterials.push_back( "G4_Fe" );
// vecMaterials.push_back( "G4_Cu" );
// vecMaterials.push_back( "G4_W" );
// vecMaterials.push_back( "G4_Pb" );
const G4int numProjectiles = vecProjectiles.size();
const G4int numMaterials = vecMaterials.size();
G4cout << G4endl
<< "================= Configuration ==================" << G4endl
<< "Model: " << namePhysics << G4endl
<< "Ekin: [ " << minEnergy/CLHEP::GeV << " , " << maxEnergy/CLHEP::GeV
<< " ] GeV" << G4endl
G4cout << G4endl << "================= Configuration ==================" << G4endl
<< "Model: " << namePhysics << G4endl << "Ekin: [ " << minEnergy / CLHEP::GeV << " , "
<< maxEnergy / CLHEP::GeV << " ] GeV" << G4endl
<< "Number of collisions: " << numCollisions << G4endl
<< "Number of hadron projectiles: " << numProjectiles << G4endl
<< "Number of materials: " << numMaterials << G4endl
<< "IsIonProjectile: " << ( projectileNucleus != nullptr ? "true \t" : "false" )
<< ( projectileNucleus != nullptr ? projectileNucleus->GetParticleName() : G4String("")) << G4endl
<< "===================================================" << G4endl
<< G4endl;
CLHEP::Ranlux64Engine defaultEngine( 1234567, 4 );
CLHEP::HepRandom::setTheEngine( &defaultEngine );
<< "Number of materials: " << numMaterials << G4endl
<< "IsIonProjectile: " << (projectileNucleus != nullptr ? "true \t" : "false")
<< (projectileNucleus != nullptr ? projectileNucleus->GetParticleName() : G4String(""))
<< G4endl << "===================================================" << G4endl << G4endl;
CLHEP::Ranlux64Engine defaultEngine(1234567, 4);
CLHEP::HepRandom::setTheEngine(&defaultEngine);
//***LOOKHERE*** RANDOM ENGINE START SEED
//G4int seed = time( NULL );
//CLHEP::HepRandom::setTheSeed( seed );
//G4cout << G4endl << " Initial seed = " << seed << G4endl << G4endl;
// G4int seed = time( NULL );
// CLHEP::HepRandom::setTheSeed( seed );
// G4cout << G4endl << " Initial seed = " << seed << G4endl << G4endl;
// Set up histo manager.
auto histoManager = FinalStateHistoManager();
histoManager.Book();
// Instanciate the HadronicGenerator providing the name of the "physics case"
HadronicGenerator* theHadronicGenerator = new HadronicGenerator( namePhysics );
HadronicGenerator* theHadronicGenerator = new HadronicGenerator(namePhysics);
//****************************************************************************
if ( theHadronicGenerator == nullptr ) {
if (theHadronicGenerator == nullptr) {
G4cerr << "ERROR: theHadronicGenerator is NULL !" << G4endl;
return 1;
} else if ( ! theHadronicGenerator->IsPhysicsCaseSupported() ) {
}
else if (!theHadronicGenerator->IsPhysicsCaseSupported()) {
G4cerr << "ERROR: this physics case is NOT supported !" << G4endl;
return 2;
}
// Start timing
auto start = std::chrono::high_resolution_clock::now();
@@ -328,83 +325,83 @@ G4int main(G4int argc, char** argv) {
// Loop over the collisions
G4double rnd1, rnd2, rnd3, rnd4, rnd5, rnd6, normalization, projectileEnergy;
G4VParticleChange* aChange = nullptr;
for ( G4int i = 0; i < numCollisions; ++i ) {
for (G4int i = 0; i < numCollisions; ++i) {
histoManager.BeginOfEvent();
// Draw some random numbers to select the hadron-nucleus interaction:
// projectile hadron, projectile kinetic energy, projectile direction, and target material.
rnd1 = CLHEP::HepRandom::getTheEngine()->flat();
rnd1 = CLHEP::HepRandom::getTheEngine()->flat();
rnd2 = CLHEP::HepRandom::getTheEngine()->flat();
rnd3 = CLHEP::HepRandom::getTheEngine()->flat();
rnd4 = CLHEP::HepRandom::getTheEngine()->flat();
rnd5 = CLHEP::HepRandom::getTheEngine()->flat();
rnd6 = CLHEP::HepRandom::getTheEngine()->flat();
// Sample the projectile kinetic energy
projectileEnergy = minEnergy + rnd1*( maxEnergy - minEnergy );
if ( projectileEnergy <= 0.0 ) projectileEnergy = minEnergy;
projectileEnergy = minEnergy + rnd1 * (maxEnergy - minEnergy);
if (projectileEnergy <= 0.0) projectileEnergy = minEnergy;
// Sample the projectile direction
normalization = 1.0 / std::sqrt( rnd2*rnd2 + rnd3*rnd3 + rnd4*rnd4 );
//***LOOKHERE*** IF true THEN SMEAR DIRECTION
const G4bool isOnSmearingDirection = false ;
normalization = 1.0 / std::sqrt(rnd2 * rnd2 + rnd3 * rnd3 + rnd4 * rnd4);
//***LOOKHERE*** IF true THEN SMEAR DIRECTION
const G4bool isOnSmearingDirection = false;
//***LOOKHERE*** ELSE USE THIS FIXED DIRECTION
G4ThreeVector aDirection = G4ThreeVector( 0.0, 0.0, 1.0 );
if ( isOnSmearingDirection ) {
aDirection = G4ThreeVector( normalization*rnd2, normalization*rnd3, normalization*rnd4 );
}
G4ThreeVector aDirection = G4ThreeVector(0.0, 0.0, 1.0);
if (isOnSmearingDirection) {
aDirection = G4ThreeVector(normalization * rnd2, normalization * rnd3, normalization * rnd4);
}
// Sample the projectile hadron from the vector vecProjectiles
G4int index_projectile = std::trunc( rnd5*numProjectiles );
G4String nameProjectile = vecProjectiles[ index_projectile ];
G4ParticleDefinition* projectile = partTable->FindParticle( nameProjectile );
if ( projectileNucleus ) {
G4int index_projectile = std::trunc(rnd5 * numProjectiles);
G4String nameProjectile = vecProjectiles[index_projectile];
G4ParticleDefinition* projectile = partTable->FindParticle(nameProjectile);
if (projectileNucleus) {
nameProjectile = projectileNucleus->GetParticleName();
projectile = projectileNucleus;
}
// Sample the target material from the vector vecMaterials
// (Note: the target nucleus will be sampled by Geant4)
G4int index_material = std::trunc( rnd6*numMaterials );
G4String nameMaterial = vecMaterials[ index_material ];
G4Material* material = G4NistManager::Instance()->FindOrBuildMaterial( nameMaterial );
if ( material == nullptr ) {
G4int index_material = std::trunc(rnd6 * numMaterials);
G4String nameMaterial = vecMaterials[index_material];
G4Material* material = G4NistManager::Instance()->FindOrBuildMaterial(nameMaterial);
if (material == nullptr) {
G4cerr << "ERROR: Material " << nameMaterial << " is not found !" << G4endl;
return 3;
}
if ( isPrintingEnabled ) {
if (isPrintingEnabled) {
G4cout << "\t Collision " << i << " ; projectile=" << nameProjectile;
if ( projectileNucleus ) {
G4cout << " ; Ekin[MeV]/nucleon=" << projectileEnergy /
static_cast< G4double >( std::abs( projectileNucleus->GetBaryonNumber() ) );
} else {
G4cout << " ; Ekin[MeV]=" << projectileEnergy;
if (projectileNucleus) {
G4cout << " ; Ekin[MeV]/nucleon="
<< projectileEnergy
/ static_cast<G4double>(std::abs(projectileNucleus->GetBaryonNumber()));
}
else {
G4cout << " ; Ekin[MeV]=" << projectileEnergy;
}
G4cout << " ; direction=" << aDirection << " ; material=" << nameMaterial;
}
// Call here the "hadronic generator" to get the secondaries produced by the hadronic collision
aChange = theHadronicGenerator->GenerateInteraction( projectile, projectileEnergy,
/* ********************************************** */ aDirection, material );
aChange = theHadronicGenerator->GenerateInteraction(
projectile, projectileEnergy,
/* ********************************************** */ aDirection, material);
G4int nsec = aChange ? aChange->GetNumberOfSecondaries() : 0;
G4bool isPrintingOfSecondariesEnabled = false;
if ( isPrintingEnabled ) {
G4cout << G4endl << "\t --> #secondaries=" << nsec
<< " ; impactParameter[fm]="
<< theHadronicGenerator->GetImpactParameter() / fermi
<< " ; #projectileSpectatorNucleons="
if (isPrintingEnabled) {
G4cout << G4endl << "\t --> #secondaries=" << nsec
<< " ; impactParameter[fm]=" << theHadronicGenerator->GetImpactParameter() / fermi
<< " ; #projectileSpectatorNucleons="
<< theHadronicGenerator->GetNumberOfProjectileSpectatorNucleons()
<< " ; #targetSpectatorNucleons="
<< " ; #targetSpectatorNucleons="
<< theHadronicGenerator->GetNumberOfTargetSpectatorNucleons()
<< " ; #NNcollisions="
<< theHadronicGenerator->GetNumberOfNNcollisions()
<< G4endl;
if ( i % printingGap == 0 ) {
<< " ; #NNcollisions=" << theHadronicGenerator->GetNumberOfNNcollisions() << G4endl;
if (i % printingGap == 0) {
isPrintingOfSecondariesEnabled = true;
G4cout << "\t \t List of produced secondaries: " << G4endl;
}
}
// Loop over produced secondaries and eventually print out some information.
for ( G4int j = 0; j < nsec; ++j ) {
for (G4int j = 0; j < nsec; ++j) {
const G4DynamicParticle* sec = aChange->GetSecondary(j)->GetDynamicParticle();
if ( isPrintingOfSecondariesEnabled ) {
if (isPrintingOfSecondariesEnabled) {
G4cout << "\t \t \t j=" << j << "\t" << sec->GetDefinition()->GetParticleName()
<< "\t p=" << sec->Get4Momentum() << " MeV" << G4endl;
}
@@ -414,24 +411,24 @@ G4int main(G4int argc, char** argv) {
delete aChange->GetSecondary(j);
}
if ( aChange ) aChange->Clear();
if (aChange) aChange->Clear();
histoManager.EndOfEvent();
}
histoManager.EndOfRun();
G4cout << G4endl << " Final random number = " << CLHEP::HepRandom::getTheEngine()->flat()
G4cout << G4endl << " Final random number = " << CLHEP::HepRandom::getTheEngine()->flat()
<< G4endl;
const auto stop = std::chrono::high_resolution_clock::now();
const auto diff = stop - start;
const auto time = static_cast<G4double>(
std::chrono::duration_cast<std::chrono::microseconds>(diff).count()) / 1e6;
const auto time =
static_cast<G4double>(std::chrono::duration_cast<std::chrono::microseconds>(diff).count())
/ 1e6;
G4cout << G4endl;
G4cout << "Processed " << numCollisions << " events (collisions) in "
<< std::scientific << time << " seconds."
<< " Average: " << std::defaultfloat << (time * 1E3 / numCollisions) << " ms / event."
G4cout << "Processed " << numCollisions << " events (collisions) in " << std::scientific << time
<< " seconds."
<< " Average: " << std::defaultfloat << (time * 1E3 / numCollisions) << " ms / event."
<< G4endl;
G4cout << G4endl;
@@ -6,7 +6,7 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-04-24 Gabriele Cosmo (exHadNucIneEvents-V11-01-02)
## 2024-04-24 Gabriele Cosmo (exHadNucIneEvents-V11-02-00)
- Fixed compilation error on Windows VC++ with C++20 Standard enabled.
Make proper use of G4String in HadNucIneEvents main() and
in FinalStateHistoManager.
@@ -40,7 +40,7 @@ Min energy per nucleon for multifragmentation 200 GeV
Limit excitation energy for Fermi BreakUp 20 MeV
Level density (1/MeV) 0.075
Use simple level density model 1
Use discrete excitation energy of the residual 1
Use discrete excitation energy of the residual 0
Time limit for long lived isomeres 1 ns
Isomer production flag 1
Internal e- conversion flag 1
@@ -49,7 +49,7 @@ Correlated gamma emission flag 0
Max 2J for sampling of angular correlations 10
=======================================================================
--> #secondaries=43 impactParameter[fm]=2.20708 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=10 #NNcollisions=2
--> #secondaries=44 impactParameter[fm]=2.20708 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=10 #NNcollisions=2
List of produced secondaries:
j=0 pi0 p=(-278.058,-54.2447,249604249604) MeV
j=1 pi+ p=(230.03,220.461,171304171305) MeV
@@ -90,56 +90,62 @@ Max 2J for sampling of angular correlations 10
j=36 anti_proton p=(-816.5,-1044.45,300607300612) MeV
j=37 pi0 p=(11.3286,-190.312,2085820859.3) MeV
j=38 proton p=(-249.193,60.3146,80839.980845.8) MeV
j=39 alpha p=(-363.424,209.746,-842.2813844.33) MeV
j=40 deuteron p=(-129.813,-6.02731,324.7681907.95) MeV
j=41 neutron p=(5.33356,-28.2918,306.082988.584) MeV
j=42 proton p=(244.952,-371.478,182.6581054.38) MeV
j=39 He3 p=(-240.431,173.976,-582.8082883.54) MeV
j=40 deuteron p=(-125.545,-8.41923,305.1661904.44) MeV
j=41 neutron p=(-6.72433,-28.3995,129.259948.864) MeV
j=42 neutron p=(278.182,-411.55,262.1171094.64) MeV
j=43 proton p=(-148.434,78.342,-142.506963.76) MeV
Collision 1 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=22 impactParameter[fm]=1.85456 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=10 #NNcollisions=1
--> #secondaries=63 impactParameter[fm]=0.616428 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=6 #NNcollisions=5
Collision 2 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=33 impactParameter[fm]=2.93443 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=1
--> #secondaries=48 impactParameter[fm]=2.11631 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=9 #NNcollisions=3
Collision 3 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=27 impactParameter[fm]=1.91246 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=1
--> #secondaries=7 impactParameter[fm]=2.88878 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=0
Collision 4 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=8 impactParameter[fm]=1.18725 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=0
--> #secondaries=52 impactParameter[fm]=1.5362 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=8 #NNcollisions=2
Collision 5 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=30 impactParameter[fm]=2.59294 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=10 #NNcollisions=2
--> #secondaries=31 impactParameter[fm]=3.03126 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=1
Collision 6 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=22 impactParameter[fm]=2.38324 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=1
--> #secondaries=54 impactParameter[fm]=1.2767 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=7 #NNcollisions=4
Collision 7 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=34 impactParameter[fm]=1.95621 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=9 #NNcollisions=2
--> #secondaries=51 impactParameter[fm]=3.14278 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=10 #NNcollisions=2
Collision 8 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=5 impactParameter[fm]=3.38892 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=0
--> #secondaries=39 impactParameter[fm]=2.61437 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=1
Collision 9 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=48 impactParameter[fm]=2.4417 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=9 #NNcollisions=3
--> #secondaries=60 impactParameter[fm]=2.28703 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=10 #NNcollisions=2
========================================================
Number of events 10
Average (per event) number of He3 0.4
Average (per event) number of Li6 0.1
Average (per event) number of alpha 0.8
Average (per event) number of He3 0.5
Average (per event) number of alpha 0.6
Average (per event) number of anti_lambda 0.5
Average (per event) number of anti_neutron 0.1
Average (per event) number of anti_proton 0.2
Average (per event) number of deuteron 0.9
Average (per event) number of eta 0.4
Average (per event) number of eta_prime 0.5
Average (per event) number of kaon+ 0.5
Average (per event) number of kaon- 0.4
Average (per event) number of anti_proton 0.4
Average (per event) number of anti_sigma+ 0.1
Average (per event) number of deuteron 0.5
Average (per event) number of eta 0.5
Average (per event) number of eta_prime 0.6
Average (per event) number of gamma 0.2
Average (per event) number of kaon+ 0.9
Average (per event) number of kaon- 0.7
Average (per event) number of kaon0L 0.7
Average (per event) number of kaon0S 0.5
Average (per event) number of lambda 0.1
Average (per event) number of neutron 3.2
Average (per event) number of pi+ 5.1
Average (per event) number of pi- 4.8
Average (per event) number of pi0 5.3
Average (per event) number of proton 3.2
Average (per event) number of kaon0S 0.9
Average (per event) number of lambda 0.4
Average (per event) number of neutron 3.6
Average (per event) number of pi+ 9.5
Average (per event) number of pi- 9.6
Average (per event) number of pi0 9.6
Average (per event) number of proton 4.7
Average (per event) number of sigma- 0.1
Average (per event) number of sigma0 0.1
Average (per event) number of triton 0.1
========================================================
### All histograms saved to all_secondaries.root
### All histograms saved to all_secondaries.hist
Final random number = 0.677923
Final random number = 0.280286
Processed 10 events (collisions) in 4.274400e-02 seconds. Average: 4.2744 ms / event.
Processed 10 events (collisions) in 5.218500e-02 seconds. Average: 5.2185 ms / event.
=== End of test ===
@@ -36,26 +36,26 @@
/// In practice, the interactions studied here are hadron nuclear inelastic interactions
/// (though the code is fully generic).
///
/// Energy spectra are plotted for all encountered secondaries
/// Energy spectra are plotted for all encountered secondaries
/// (one histo per secondary).
/// In addition, the residual nuclei Z and A distributions are plotted.
///
/// All histograms are G4H1.
/// All histograms are G4H1.
/// They are created and filled via the G4VAnalysisManager.
///
/// The histograms can be dumped to all usual formats, including ROOT
/// The histograms can be dumped to all usual formats, including ROOT
/// (via G4VAnalysisManager).
/// An interesting added feature here, is that the plots, while being allocated
/// and filled via G4VAnalysisManager, are also dumped
/// An interesting added feature here, is that the plots, while being allocated
/// and filled via G4VAnalysisManager, are also dumped
/// in a Flair-compatible format (via tools::histo::flair).
///
/// NB 1: Note that instead of a hardcoded number associated to a hardcoded set of particles,
/// particle PDG IDs are used to index the histos.
/// particle PDG IDs are used to index the histos.
/// This allows a dynamic storage of all particles encountered in the final states.
///
/// NB 2: tools::histo::flair code, which allows the dump of any G4H1
/// into Flair-compatible format, is fully application-agnostic,
/// and is placed in FlukaCern/utils.
/// NB 2: tools::histo::flair code, which allows the dump of any G4H1
/// into Flair-compatible format, is fully application-agnostic,
/// and is placed in FlukaCern/utils.
/// It could also be added as an extension of core G4 Analysis Manager.
//
// ***************************************************************************
@@ -63,67 +63,61 @@
#ifndef FINAL_STATE_HISTO_MANAGER_HH
#define FINAL_STATE_HISTO_MANAGER_HH
#include "G4H1Wrapper.hh"
#include "G4SystemOfUnits.hh"
#include "globals.hh"
#include <memory>
#include <unordered_map>
#include <vector>
#include "globals.hh"
#include "G4SystemOfUnits.hh"
#include "G4H1Wrapper.hh"
class G4DynamicParticle;
class G4VAnalysisManager;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class FinalStateHistoManager {
class FinalStateHistoManager
{
public:
FinalStateHistoManager();
public:
FinalStateHistoManager();
void Book();
void BeginOfEvent();
void ScoreSecondary(const G4DynamicParticle* const secondary);
void EndOfEvent();
void EndOfRun() const;
void Book();
void BeginOfEvent();
void ScoreSecondary(const G4DynamicParticle* const secondary);
void EndOfEvent();
void EndOfRun() const;
private:
void DumpAllG4H1IntoRootFile() const;
void
DumpAllG4H1IntoFlairFile(const std::map<G4String, const G4H1Wrapper*>& particlesHistos) const;
G4String fOutputFileName = "all_secondaries";
G4String fRootOutputFileName = fOutputFileName + ".root";
G4String fFlairOutputFileName = fOutputFileName + ".hist";
private:
void DumpAllG4H1IntoRootFile() const;
void DumpAllG4H1IntoFlairFile(const std::map<G4String,
const G4H1Wrapper*>& particlesHistos) const;
G4String fOutputFileName = "all_secondaries";
G4String fRootOutputFileName = fOutputFileName + ".root";
G4String fFlairOutputFileName = fOutputFileName + ".hist";
G4int fNumBins = 90;
G4double fMinKineticEnergy = 10. * keV;
G4double fMaxKineticEnergy = 10. * TeV;
G4String fFunctionName = "none";
G4String fBinSchemeName = "log";
G4String fRootEnergyUnit = "MeV";
G4int fNumBins = 90;
G4double fMinKineticEnergy = 10. * keV;
G4double fMaxKineticEnergy = 10. * TeV;
G4String fFunctionName = "none";
G4String fBinSchemeName = "log";
G4String fRootEnergyUnit = "MeV";
G4int fNucleiZMax = 25;
G4int fNucleiAMax = 50;
G4int fNucleiZMax = 25;
G4int fNucleiAMax = 50;
G4int fNumEvents = 0;
G4int fNumEvents = 0;
G4VAnalysisManager* fAnalysisManager = nullptr;
G4VAnalysisManager* fAnalysisManager = nullptr;
// key is particle PDG ID:
std::unordered_map<G4int, std::unique_ptr<G4H1Wrapper>> fParticleData;
// key is nuclei Z or A score index:
std::unordered_map<G4int, std::unique_ptr<G4H1Wrapper>> fNucleiData;
G4int fNucleiZScoreIndex = 0;
G4int fNucleiAScoreIndex = 1;
// key is particle PDG ID:
std::unordered_map<G4int, std::unique_ptr<G4H1Wrapper>> fParticleData;
// key is nuclei Z or A score index:
std::unordered_map<G4int, std::unique_ptr<G4H1Wrapper>> fNucleiData;
G4int fNucleiZScoreIndex = 0;
G4int fNucleiAScoreIndex = 1;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
#endif
@@ -25,7 +25,7 @@
//
/// \file HadronicGenerator.hh
/// \brief Definition of the HadronicGenerator class
//
//
//------------------------------------------------------------------------
// Class: HadronicGenerator
// Author: Alberto Ribon (CERN EP/SFT), May 2020
@@ -54,7 +54,7 @@
/// This class does NOT use the Geant4 run-manager, and therefore should
/// be usable in a multi-threaded application, with one instance of this
/// class in each thread.
///
///
/// This class has been inspired by test30 (whose author is Vladimir
/// Ivanchenko), with various simplifications and restricted to hadronic
/// inelastic interactions.
@@ -66,12 +66,13 @@
#ifndef HadronicGenerator_h
#define HadronicGenerator_h 1
#include <iomanip>
#include "globals.hh"
#include "G4ios.hh"
#include "G4ThreeVector.hh"
#include <map>
#include "G4HadronicProcess.hh"
#include "G4ThreeVector.hh"
#include "G4ios.hh"
#include "globals.hh"
#include <iomanip>
#include <map>
class G4ParticleDefinition;
class G4VParticleChange;
@@ -81,20 +82,20 @@ class G4HadronicInteraction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class HadronicGenerator {
// This class provides the functionality of a "hadronic generator"
// for Geant4 final-state inelastic hadronic collisions.
// Only a few of the available Geant4 final-state hadronic inelastic
// "physics cases" are currently available in this class - but it can
// be extended to other cases if needed.
// It is important to notice that this class does NOT use the Geant4
// run-manager, so it should work fine in a multi-threaded environment,
// with a separate instance of this class in each thread.
class HadronicGenerator
{
// This class provides the functionality of a "hadronic generator"
// for Geant4 final-state inelastic hadronic collisions.
// Only a few of the available Geant4 final-state hadronic inelastic
// "physics cases" are currently available in this class - but it can
// be extended to other cases if needed.
// It is important to notice that this class does NOT use the Geant4
// run-manager, so it should work fine in a multi-threaded environment,
// with a separate instance of this class in each thread.
public:
explicit HadronicGenerator( const G4String physicsCase = "FTFP_BERT_ATL" );
explicit HadronicGenerator(const G4String physicsCase = "FTFP_BERT_ATL");
// Currently supported final-state hadronic inelastic "physics cases":
// - Hadronic models : CernFLUKAHadronInelastic,
// - Hadronic models : CernFLUKAHadronInelastic,
// BERT, BIC, IonBIC, INCL, FTFP, QGSP
// - "Physics-list proxies" : FTFP_BERT_ATL (default), FTFP_BERT,
// QGSP_BERT, QGSP_BIC, FTFP_INCLXX
@@ -112,22 +113,22 @@ class HadronicGenerator {
~HadronicGenerator();
inline G4bool IsPhysicsCaseSupported() const;
// Returns "true" if the physicsCase is supported; "false" otherwise.
G4bool IsApplicable( const G4String &nameProjectile, const G4double projectileEnergy ) const;
G4bool IsApplicable( G4ParticleDefinition* projectileDefinition,
const G4double projectileEnergy ) const;
// Returns "true" if the physicsCase is supported; "false" otherwise.
G4bool IsApplicable(const G4String& nameProjectile, const G4double projectileEnergy) const;
G4bool IsApplicable(G4ParticleDefinition* projectileDefinition,
const G4double projectileEnergy) const;
// Returns "true" if the specified projectile (either by name or particle definition)
// of given energy is applicable, "false" otherwise.
G4VParticleChange* GenerateInteraction( const G4String &nameProjectile,
const G4double projectileEnergy,
const G4ThreeVector &projectileDirection ,
G4Material* targetMaterial );
G4VParticleChange* GenerateInteraction( G4ParticleDefinition* projectileDefinition,
const G4double projectileEnergy,
const G4ThreeVector &projectileDirection ,
G4Material* targetMaterial );
G4VParticleChange* GenerateInteraction(const G4String& nameProjectile,
const G4double projectileEnergy,
const G4ThreeVector& projectileDirection,
G4Material* targetMaterial);
G4VParticleChange* GenerateInteraction(G4ParticleDefinition* projectileDefinition,
const G4double projectileEnergy,
const G4ThreeVector& projectileDirection,
G4Material* targetMaterial);
// This is the main method provided by the class:
// in input it receives the projectile (either by name or particle definition),
// its energy, its direction and the target material, and it returns one sampled
@@ -151,28 +152,26 @@ class HadronicGenerator {
// else, returns a negative value (-999).
private:
G4String fPhysicsCase;
G4bool fPhysicsCaseIsSupported = false;
G4HadronicProcess* fLastHadronicProcess = nullptr;
G4ParticleTable* fPartTable = nullptr;
std::map< G4ParticleDefinition*, G4HadronicProcess* > fProcessMap;
std::map<G4ParticleDefinition*, G4HadronicProcess*> fProcessMap;
};
inline G4bool HadronicGenerator::IsPhysicsCaseSupported() const {
inline G4bool HadronicGenerator::IsPhysicsCaseSupported() const
{
return fPhysicsCaseIsSupported;
}
inline G4HadronicProcess* HadronicGenerator::GetHadronicProcess() const {
inline G4HadronicProcess* HadronicGenerator::GetHadronicProcess() const
{
return fLastHadronicProcess;
}
inline G4HadronicInteraction* HadronicGenerator::GetHadronicInteraction() const {
return fLastHadronicProcess == nullptr ? nullptr
: fLastHadronicProcess->GetHadronicInteraction();
inline G4HadronicInteraction* HadronicGenerator::GetHadronicInteraction() const
{
return fLastHadronicProcess == nullptr ? nullptr : fLastHadronicProcess->GetHadronicInteraction();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -36,26 +36,26 @@
/// In practice, the interactions studied here are hadron nuclear inelastic interactions
/// (though the code is fully generic).
///
/// Energy spectra are plotted for all encountered secondaries
/// Energy spectra are plotted for all encountered secondaries
/// (one histo per secondary).
/// In addition, the residual nuclei Z and A distributions are plotted.
///
/// All histograms are G4H1.
/// All histograms are G4H1.
/// They are created and filled solely via G4VAnalysisManager.
///
/// The histograms can be dumped to all usual formats, including ROOT
/// The histograms can be dumped to all usual formats, including ROOT
/// (via G4VAnalysisManager).
/// An interesting added feature here, is that the plots, while being allocated
/// and filled via G4VAnalysisManager, are also dumped
/// An interesting added feature here, is that the plots, while being allocated
/// and filled via G4VAnalysisManager, are also dumped
/// in a Flair-compatible format (via tools::histo::flair).
///
/// NB 1: Note that instead of a hardcoded number associated to a hardcoded set of particles,
/// particle PDG IDs are used to index the histos.
/// particle PDG IDs are used to index the histos.
/// This allows a dynamic storage of all particles encountered in the final states.
///
/// NB 2: tools::histo::flair code, which allows the dump of any G4H1
/// into Flair-compatible format, is fully application-agnostic,
/// and is placed in FlukaCern/utils.
/// NB 2: tools::histo::flair code, which allows the dump of any G4H1
/// into Flair-compatible format, is fully application-agnostic,
/// and is placed in FlukaCern/utils.
/// It could also be added as an extension of core G4 Analysis Manager.
//
// ***************************************************************************
@@ -63,106 +63,84 @@
#include "FinalStateHistoManager.hh"
#include "G4RootAnalysisManager.hh"
//#include "G4AnalysisManager.hh"
// #include "G4AnalysisManager.hh"
#include "G4ParticleTable.hh"
#include "G4DynamicParticle.hh"
#include "G4ios.hh"
#include "G4Exception.hh"
#include "g4hntools_defs.hh"
#include "tools_histo_flair.hh"
#include "G4DynamicParticle.hh"
#include "G4Exception.hh"
#include "G4ParticleTable.hh"
#include "G4ios.hh"
#include "g4hntools_defs.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
FinalStateHistoManager::FinalStateHistoManager() :
fOutputFileName("all_secondaries"),
fRootOutputFileName(fOutputFileName + ".root"),
fFlairOutputFileName(fOutputFileName + ".hist"),
fNumBins(90),
fMinKineticEnergy(10. * keV),
fMaxKineticEnergy(10. * TeV),
fFunctionName("none"),
fBinSchemeName("log"),
fRootEnergyUnit("MeV"),
fNucleiZMax(25),
fNucleiAMax(50),
fNumEvents(0),
fAnalysisManager(G4RootAnalysisManager::Instance()),
fNucleiZScoreIndex(0),
fNucleiAScoreIndex(1)
FinalStateHistoManager::FinalStateHistoManager()
: fOutputFileName("all_secondaries"),
fRootOutputFileName(fOutputFileName + ".root"),
fFlairOutputFileName(fOutputFileName + ".hist"),
fNumBins(90),
fMinKineticEnergy(10. * keV),
fMaxKineticEnergy(10. * TeV),
fFunctionName("none"),
fBinSchemeName("log"),
fRootEnergyUnit("MeV"),
fNucleiZMax(25),
fNucleiAMax(50),
fNumEvents(0),
fAnalysisManager(G4RootAnalysisManager::Instance()),
fNucleiZScoreIndex(0),
fNucleiAScoreIndex(1)
{
//fAnalysisManager = G4AnalysisManager::Instance();
//fAnalysisManager->SetDefaultFileType("root");
//fAnalysisManager->SetVerboseLevel(0);
//fOutputFileName += fAnalysisManager->GetFileType();
// fAnalysisManager = G4AnalysisManager::Instance();
// fAnalysisManager->SetDefaultFileType("root");
// fAnalysisManager->SetVerboseLevel(0);
// fOutputFileName += fAnalysisManager->GetFileType();
}
// ***************************************************************************
// Open output file + create residual nuclei histograms considered for final state study.
// The histograms are G4H1, created via G4VAnalysisManager.
// ***************************************************************************
void FinalStateHistoManager::Book() {
void FinalStateHistoManager::Book()
{
// Open file.
if(!fAnalysisManager->OpenFile(fRootOutputFileName)) {
if (!fAnalysisManager->OpenFile(fRootOutputFileName)) {
G4ExceptionDescription msg;
msg << "Booking histograms: cannot open file "
<< fRootOutputFileName
<< G4endl;
G4Exception("FinalStateHistoManager::Book",
"Cannot open file",
FatalException,
msg);
msg << "Booking histograms: cannot open file " << fRootOutputFileName << G4endl;
G4Exception("FinalStateHistoManager::Book", "Cannot open file", FatalException, msg);
}
G4cout << "### FinalStateHistoManager::Book: Successfully opended file "
<< fRootOutputFileName
<< " for dumping histograms."
<< G4endl;
G4cout << "### FinalStateHistoManager::Book: Successfully opended file " << fRootOutputFileName
<< " for dumping histograms." << G4endl;
// Create the residual nuclei distributions (in Z and A).
const G4int nucleiZHistoIndex = fAnalysisManager->CreateH1("nucleiZ",
"Residual nuclei distribution in Z",
fNucleiZMax,
0.5,
fNucleiZMax + 0.5);
auto nucleiZHistoWrapper = std::make_unique<G4H1Wrapper>(fAnalysisManager,
nucleiZHistoIndex);
const G4int nucleiZHistoIndex = fAnalysisManager->CreateH1(
"nucleiZ", "Residual nuclei distribution in Z", fNucleiZMax, 0.5, fNucleiZMax + 0.5);
auto nucleiZHistoWrapper = std::make_unique<G4H1Wrapper>(fAnalysisManager, nucleiZHistoIndex);
fNucleiData.insert(std::make_pair(fNucleiZScoreIndex, std::move(nucleiZHistoWrapper)));
const G4int nucleiAHistoIndex = fAnalysisManager->CreateH1("nucleiA",
"Residual nuclei distribution in A",
fNucleiAMax,
0.5,
fNucleiAMax + 0.5);
auto nucleiAHistoWrapper = std::make_unique<G4H1Wrapper>(fAnalysisManager,
nucleiAHistoIndex);
const G4int nucleiAHistoIndex = fAnalysisManager->CreateH1(
"nucleiA", "Residual nuclei distribution in A", fNucleiAMax, 0.5, fNucleiAMax + 0.5);
auto nucleiAHistoWrapper = std::make_unique<G4H1Wrapper>(fAnalysisManager, nucleiAHistoIndex);
fNucleiData.insert(std::make_pair(fNucleiAScoreIndex, std::move(nucleiAHistoWrapper)));
}
// ***************************************************************************
// Keep track of the total number of events (used later on for normalization).
// ***************************************************************************
void FinalStateHistoManager::BeginOfEvent() {
void FinalStateHistoManager::BeginOfEvent()
{
fNumEvents++;
}
// ***************************************************************************
// Fill all plots (WITHIN event, ie the interaction).
// ***************************************************************************
void FinalStateHistoManager::ScoreSecondary(const G4DynamicParticle* const secondary) {
void FinalStateHistoManager::ScoreSecondary(const G4DynamicParticle* const secondary)
{
// SELECT SPECIFIC SECONDARIES ONLY
// Select by angle with beam direction
/* if ( (std::pow(secondary->GetMomentumDirection().x(), 2.)
/* if ( (std::pow(secondary->GetMomentumDirection().x(), 2.)
+ std::pow(secondary->GetMomentumDirection().y(), 2.))
<= 0.0001 ) {*/
@@ -174,7 +152,6 @@ void FinalStateHistoManager::ScoreSecondary(const G4DynamicParticle* const secon
const auto& particle = secondary->GetDefinition();
// SECONDARIES ENERGY SPECTRA
// Dynamic creation of histos, so that all encountered particles have their own histos.
@@ -191,19 +168,12 @@ void FinalStateHistoManager::ScoreSecondary(const G4DynamicParticle* const secon
const G4String& particleName = particle->GetParticleName();
const G4int particlePDG = secondary->GetPDGcode();
const G4String histoTitle = (particlePDG == 0
? G4String("Particle pdg==0 spectrum")
: particleName + G4String(" spectrum"));
const G4int histoIndex = fAnalysisManager->CreateH1(particleName,
histoTitle,
fNumBins,
fMinKineticEnergy,
fMaxKineticEnergy,
fRootEnergyUnit,
fFunctionName,
fBinSchemeName);
auto histoWrapper = std::make_unique<G4H1Wrapper>(fAnalysisManager,
histoIndex);
const G4String histoTitle = (particlePDG == 0 ? G4String("Particle pdg==0 spectrum")
: particleName + G4String(" spectrum"));
const G4int histoIndex =
fAnalysisManager->CreateH1(particleName, histoTitle, fNumBins, fMinKineticEnergy,
fMaxKineticEnergy, fRootEnergyUnit, fFunctionName, fBinSchemeName);
auto histoWrapper = std::make_unique<G4H1Wrapper>(fAnalysisManager, histoIndex);
particleHistoWrapper = histoWrapper.get();
fParticleData.insert(std::make_pair(particlePDG, std::move(histoWrapper)));
}
@@ -212,7 +182,6 @@ void FinalStateHistoManager::ScoreSecondary(const G4DynamicParticle* const secon
const G4double kineticEnergy = secondary->GetKineticEnergy();
particleHistoWrapper->Fill(kineticEnergy, 1.);
// NUCLEI DISTRIBUTIONS IN Z AND A
if (particle->GetParticleType() == "nucleus") {
// Fill the G4H1Wrapper.
@@ -227,12 +196,11 @@ void FinalStateHistoManager::ScoreSecondary(const G4DynamicParticle* const secon
//} // select secondaries
}
// ***************************************************************************
// End of event: all event-level G4H1 are flushed into the Analysis Manager G4H1.
// ***************************************************************************
void FinalStateHistoManager::EndOfEvent() {
void FinalStateHistoManager::EndOfEvent()
{
for (const auto& particleIt : fParticleData) {
particleIt.second->EndOfEvent();
}
@@ -241,12 +209,11 @@ void FinalStateHistoManager::EndOfEvent() {
}
}
// ***************************************************************************
// Printout secondary counts + dump all plots into relevant formats.
// ***************************************************************************
void FinalStateHistoManager::EndOfRun() const {
void FinalStateHistoManager::EndOfRun() const
{
// PRINTOUT SECONDARYS COUNTS (FULL ENERGY RANGE).
// Order the histos by particles names.
@@ -254,115 +221,87 @@ void FinalStateHistoManager::EndOfRun() const {
for (const auto& particleIt : fParticleData) {
const G4int particlePdg = particleIt.first;
const G4String particleName = G4ParticleTable::GetParticleTable()
->FindParticle(particlePdg)->GetParticleName();
const G4String particleName =
G4ParticleTable::GetParticleTable()->FindParticle(particlePdg)->GetParticleName();
const G4H1Wrapper* const particleHisto = particleIt.second.get();
particlesHistos.insert(std::make_pair(particleName, particleHisto));
}
// Printout secondarys counts (full energy range)
// Values are averaged over the number of events.
G4cout << "========================================================" << G4endl;
G4cout << "Number of events " << fNumEvents << G4endl << G4endl;
for (const auto& particleIt : particlesHistos) {
// Note that the info is directly obtained from the histogram:
// it is the integral over the full energy range.
const G4int count = particleIt.second->GetG4H1()->sum_all_bin_heights();
const G4double averageCount = static_cast<G4double>(count) / fNumEvents;
G4cout << "Average (per event) number of " << particleIt.first
<< " " << averageCount
<< G4endl;
G4cout << "Average (per event) number of " << particleIt.first << " "
<< averageCount << G4endl;
}
G4cout << "========================================================" << G4endl;
G4cout << G4endl;
// DUMP G4H1 PLOTS INTO ROOT FILE
DumpAllG4H1IntoRootFile();
// DUMP G4H1 PLOTS INTO FLAIR FILE
DumpAllG4H1IntoFlairFile(particlesHistos);
// Close and clear fAnalysisManager.
fAnalysisManager->CloseFile();
fAnalysisManager->Clear();
}
// ***************************************************************************
// DUMP G4H1 PLOTS INTO ROOT FILE (via G4VAnalysisManager).
// ***************************************************************************
void FinalStateHistoManager::DumpAllG4H1IntoRootFile() const {
void FinalStateHistoManager::DumpAllG4H1IntoRootFile() const
{
if (!fAnalysisManager->Write()) {
G4ExceptionDescription message;
message << "Could not write ROOT file.";
G4Exception("FinalStateHistoManager::EndOfRun()",
"I/O Error",
FatalException,
message);
message << "Could not write ROOT file.";
G4Exception("FinalStateHistoManager::EndOfRun()", "I/O Error", FatalException, message);
}
G4cout << "### All histograms saved to " << fRootOutputFileName << G4endl;
}
// ***************************************************************************
// DUMP G4H1 PLOTS INTO FLAIR FILE (via tools::histo::flair).
// ***************************************************************************
void FinalStateHistoManager::DumpAllG4H1IntoFlairFile(
const std::map<G4String, const G4H1Wrapper*>& particlesHistos) const {
const std::map<G4String, const G4H1Wrapper*>& particlesHistos) const
{
std::ofstream output;
output.open(fFlairOutputFileName, std::ios_base::out);
G4int indexInOutputFile = 1;
// SECONDARIES ENERGY SPECTRA
for (const auto& particleIt : particlesHistos) {
const G4String& histoName = particleIt.first;
const auto& histo = particleIt.second->GetG4H1();
tools::histo::flair::dumpG4H1HistoInFlairFormat(output,
indexInOutputFile,
histoName,
histo,
tools::histo::flair::Abscissa::KineticEnergy,
fBinSchemeName,
fNumEvents,
particleIt.second
->GetSumSquaredEventTotals(),
particleIt.second
->GetSumSquaredEventInRangeTotals());
tools::histo::flair::dumpG4H1HistoInFlairFormat(
output, indexInOutputFile, histoName, histo, tools::histo::flair::Abscissa::KineticEnergy,
fBinSchemeName, fNumEvents, particleIt.second->GetSumSquaredEventTotals(),
particleIt.second->GetSumSquaredEventInRangeTotals());
++indexInOutputFile;
}
// RESIDUAL NUCLEI DISTRIBUTIONS
for (const auto& plotIt : fNucleiData) {
const auto& histo = plotIt.second->GetG4H1();
const G4String& histoName = (plotIt.first == fNucleiZScoreIndex ?
"nucleiZ"
: "nucleiA");
const auto& abscissaKind = (plotIt.first == fNucleiZScoreIndex ?
tools::histo::flair::Abscissa::Z
: tools::histo::flair::Abscissa::A);
tools::histo::flair::dumpG4H1HistoInFlairFormat(output,
indexInOutputFile,
histoName,
histo,
abscissaKind,
fBinSchemeName,
fNumEvents,
plotIt.second
->GetSumSquaredEventTotals(),
plotIt.second
->GetSumSquaredEventInRangeTotals());
const G4String& histoName = (plotIt.first == fNucleiZScoreIndex ? "nucleiZ" : "nucleiA");
const auto& abscissaKind =
(plotIt.first == fNucleiZScoreIndex ? tools::histo::flair::Abscissa::Z
: tools::histo::flair::Abscissa::A);
tools::histo::flair::dumpG4H1HistoInFlairFormat(
output, indexInOutputFile, histoName, histo, abscissaKind, fBinSchemeName, fNumEvents,
plotIt.second->GetSumSquaredEventTotals(), plotIt.second->GetSumSquaredEventInRangeTotals());
++indexInOutputFile;
}
File diff suppressed because it is too large Load Diff