Import Geant4 11.2.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2023-06-30 09:09:57 +02:00
parent aef78ca386
commit dd1f179cda
3780 changed files with 212808 additions and 142780 deletions
@@ -0,0 +1,190 @@
/// @file "hadronic/FlukaCern/ProcessLevel/FinalState/.README.txt"
/// @brief Example exFlukaCernFinalState README
/*! \page exFlukaCernFinalState Example : exFlukaCernFinalState
# Description
This example allows the simulation of hadron-nucleus inelastic nuclear interactions,
and the study of the resulting final states.
It is an adaptation of `Hadr09` example. <br>
It offers all `Hadr09` features, and adds the possibility
of accessing hadron-nucleus inelastic nuclear interaction final states FROM `FLUKA`.
With respect to the `Hadr09` example, the program also adds
the possibility of PLOTTING the final state:
secondaries energy spectra, and residual nuclei distributions. <br>
All plots (created via the G4 analysis manager) can be dumped
to any of the usually supported formats (e.g. ROOT format),
as well as in a Flair-compatible format. <br>
Regarding the extension of `G4H1` to insure `Flair` compatibility,
see `geant4/examples/extended/hadronic/FlukaCern/utils`.
The class `HadronicGenerator` is the "generator". <br>
The main hadronic models (`CernFLUKAHadronInelastic`, `FTFP`, `QGSP`, `BERT`, `BIC`, `IonBIC`, `INCL`) are available. <br>
See `include/HadronicGenerator.hh` for more detailed information. <br>
In the `HadronicGenerator`, one can activate/desactivate coalescence and heavy fragments evaporation for `CernFLUKAHadronInelastic`.
The main, `HadNucIneEvents.cc`, shows an example of how to use the event generator. <br>
In `HadNucIneEvents.cc`, one can select the physics models,
as well as the projectile hadron, its energy, its direction, the target material, and the number of collisions.
Note that the Geant4 run manager is not used.
Before you can access the `FLUKA` hadron-nucleus inelastic models in this example,
you will need to install and setup `FLUKA` and its interface. <br>
See the compulsory "Dependencies" paragraph below.
A version of the interface to `FLUKA` is directly located at `geant4/examples/extended/hadronic/FlukaCern/FlukaInterface`. <br>
Note that for consistency, all calls to the random engine rely on the G4 random engine (including the calls from within the downloaded `FLUKA` release; see the `FlukaInterface` `Makefile` to see how this is handled).
# FLUKA inelastic hadron-nucleus interactions
Hadron-NUCLEON interaction models are based on resonance production and decay below a few GeV,
and on the Dual Parton model above. <br>
Hadron-NUCLEUS interactions: the PEANUT package includes
a detailed Generalised Intra-Nuclear Cascade (GINC) and a preequilibrium stage,
followed by equilibrium processes: evaporation, fission, Fermi break-up, gamma deexcitation.
\verbatim
A. Ferrari and P. Sala, “The Physics of High Energy Reactions,” in Proc. Workshop on Nuclear Reaction Data and Nuclear Reactors Physics, Design and Safety, p. 424, World Scientific, 1998.
A. Ferrari and P. Sala, “Nuclear reactions in Monte Carlo codes,” Radiat. Prot. Dosimetry, vol. 99, no. 1-4, pp. 2938, 2002.
\endverbatim
# Dependencies
### Environment
- **gcc** >= 7 (Linux) and **gcc** >= 9 (MacOS) <br>
In practice, a recent version is recommended, at least `gcc >=10`.
\verbatim
gcc --version
\endverbatim
<br>
- **CMake** >= 3.16...3.21 <br>
\verbatim
cmake3 --version
\endverbatim
<br>
- **G4** >= 11.0.3 (Not tested on older G4 releases: might still work, but with no guarantee). <br>
IMPORTANT: YOU NEED TO SOURCE YOUR G4 ENVIRONMENT. <br>
It needs to be sourced in whichever terminal you want to build / run a G4 application with the `FLUKA` interface.
\verbatim
source path_to_geant4/install/bin/geant4.sh
which geant4-config # NB: Your geant4-config should support the modern CMake way of building G4.
\endverbatim
<br>
- **Easy setup on lxplus** (lxplus7): <br>
All you need to do on lxplus, to setup an environment satisfying all the conditions above, is, for example:
\verbatim
source /cvmfs/sft.cern.ch/lcg/releases/gcc/10.1.0/x86_64-centos7/setup.sh
source /cvmfs/geant4.cern.ch/geant4/11.1/x86_64-centos7-gcc10-optdeb-MT/CMake-setup.sh
# NB: Your geant4.sh is at: /cvmfs/geant4.cern.ch/geant4/11.1/x86_64-centos7-gcc10-optdeb-MT/bin/geant4.sh
\endverbatim
<br>
### FLUKA4
Release: >= **4-3.2**
Please install the latest `FLUKA` release. <br>
(1) You first need to register (and accept the licence when relevant): https://fluka.cern/download/registration <br>
(2) You can then download the `binary libraries` (or potentially the `source code` package, depending on your case):
https://fluka.cern/download/latest-fluka-release. <br>
(3) Follow the `FLUKA` installation instructions: https://fluka.cern/documentation/installation <br>
In particular, for a Linux/MacOS install: https://fluka.cern/documentation/installation/fluka-linux-macos <br>
They will show you how to setup `FLUKA`. <br>
If (and only if) you went for the source code package option, you will need to build `fluka`, and, in addition, to do `make cpp_headers` at `path_to_fluka/src`. <br>
(4) Eventually, all you need are the headers `fluka_repo/include`, libraries `fluka_repo/lib`, and data `fluka_repo/data`. Check that they are not empty. <br>
Do not forget to add `/path_to_fluka/bin` to your `PATH`. Check with `which fluka`.
### FlukaInterface
A version of the G4-FLUKA interface (`FLUKA` hadron-nucleus inelastic physics)
is located at `geant4/examples/extended/hadronic/FlukaCern/FlukaInterface`. <br>
You will first need to build the interface to `FLUKA`, and create the environment scripts. <br>
\verbatim
cd geant4/examples/extended/hadronic/FlukaCern/FlukaInterface/
# Check with `which fluka` that fluka executable is added to your `PATH`.
source path_to_geant4/install/bin/geant4.sh
make interface
make env # Creates `env_FLUKA.sh` and `env_FLUKA_G4_interface.sh`
\endverbatim
IMPORTANT: `env_FLUKA_G4_interface.sh` needs to be sourced in whichever terminal
you want to build / run a G4 application with the `FLUKA` interface.
# Build this example
\verbatim
cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
# Check with `which fluka` that fluka executable is added to your `PATH`.
source path_to_geant4/install/bin/geant4.sh
source ../../FlukaInterface/env_FLUKA_G4_interface.sh
mkdir build
cd build
cmake3 -DG4_USE_FLUKA=1 ..
make -j8
\endverbatim
# Run this example
\verbatim
cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
# Check with `which fluka` that fluka executable is added to your `PATH`.
source path_to_geant4/install/bin/geant4.sh
source ../../FlukaInterface/env_FLUKA_G4_interface.sh
./build/HadNucIneEvents
\endverbatim
# Study the final states
All plots are dumped at the end of the run in `all_secondaries.ext`. <br>
2 formats are supported: `ROOT` and `Flair`.
- You can use `ROOT`:
\verbatim
cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
root all_secondaries.root
\endverbatim
<br>
- Alternatively, the use of `Flair` is also supported. <br>
Please see http://flair.web.cern.ch/flair/download.html for `Flair` download. <br>
`Flair` tutorials are also available from that website. <br>
You can download the package corresponding to your distribution at the top of the page
(no need for `geoviewer`, which is for geometry display). Then look at the requirements & installation instructions at the bottom of the page. <br>
If you face issues installing `Flair`, you can get support at: https://fluka-forum.web.cern.ch/c/installation/
<br><br>
An example file, showing how to directly visualize the final states with Flair, is provided in this G4 example. <br>
By default, it directly provides comparison plots:
`FTFP_BERT` versus `QGSP_BERT` versus `CernFLUKAHadronInelastic`, 7TeV proton on C. <br>
You can very easily adapt it to any study of interest (choice of physics models, choice of secondaries, etc).
\verbatim
cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
mkdir -p results/FLUKAHadronInelastic results/FTFP_BERT results/QGSP_BERT
# Choose physics case (modify HadNucIneEvents.cc), compile the G4 example, then run physics case:
cd results/FLUKAHadronInelastic
../../build/HadNucIneEvents
# Etc for EACH physics case: FLUKAHadronInelastic, FTFP_BERT, QGSP_BERT.
cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
./update_final_state_flair_file.sh # Update `Det` indices in Flair file, to the ones observed in your simulation.
flair study_final_state.flair &
\endverbatim
In the `Plot` tab, you can select the plot of interest in the left column,
and then click `Plot` (top banner, yellow button). <br>
You can select a physics case by clicking on its name in the `Detectors` box (center). You can then decide to change its color, line width (`Options` box). You can decide to plot it or not, by selecting / unselecting `graph` in the `Show` box (in the center). <br>
IMPORTANT: You can select any secondary data (or residual nuclei data) which was created,
by chosing in the `Det` selection (button on the right). <br>
IMPORTANT: If a secondary does not appear in the `Det` drop-down menu, it means it is not part of the final state. In that case, you will want to unselect `graph`, so that no other secondary (see `Det`) is plotted. <br>
You can change the path of the data file by clicking on the folder button (button on the right). <br>
You can set the plots extrema, as well as select or unselect the log format, in the top right corner.
*/
@@ -0,0 +1,72 @@
#----------------------------------------------------------------------------
# Setup the project
cmake_minimum_required(VERSION 3.16...3.21)
project(HadNucIneEvents)
#----------------------------------------------------------------------------
# Find Geant4 package, activating all available UI and Vis drivers by default
# You can set WITH_GEANT4_UIVIS to OFF via the command line or ccmake/cmake-gui
# to build a batch mode only executable
#
option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
if(WITH_GEANT4_UIVIS)
find_package(Geant4 REQUIRED ui_all vis_all)
else()
find_package(Geant4 REQUIRED)
endif()
#----------------------------------------------------------------------------
# Setup Geant4 include directories and compile definitions
#
include(${Geant4_USE_FILE})
#----------------------------------------------------------------------------
# Check whether FLUKA should be used or not
set(G4_USE_FLUKA OFF CACHE BOOL "Using FLUKA")
if(G4_USE_FLUKA)
message(STATUS "G4_USE_FLUKA=ON : Using FLUKA interface for building ${PROJECT_SOURCE_DIR}")
add_definitions(-DG4_USE_FLUKA)
find_package(FLUKAInterface REQUIRED)
if(FLUKAInterface_FOUND)
message(STATUS "FLUKA cmake module was found : ${CMAKE_MODULE_PATH}")
else()
message(FATAL_ERROR "FLUKA cmake module was NOT found! Please add one.")
endif()
else()
message(STATUS "G4_USE_FLUKA=OFF : NOT using FLUKA interface for building ${PROJECT_SOURCE_DIR}. \n \
If ever you want to use the FLUKA interface, please repeat cmake command with -DG4_USE_FLUKA=1")
endif()
#----------------------------------------------------------------------------
# Locate sources and headers for this project
#
include_directories(${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/../../utils/include
${FLUKAInterface_INCLUDE_DIR}
${Geant4_INCLUDE_DIR})
file(GLOB sources ${PROJECT_SOURCE_DIR}/../../utils/src/*.cc ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/../../utils/include/*.hh ${PROJECT_SOURCE_DIR}/include/*.hh)
#----------------------------------------------------------------------------
# Add the executable, and link it to the Geant4 libraries
#
add_executable(HadNucIneEvents HadNucIneEvents.cc ${sources} ${headers})
target_link_libraries(HadNucIneEvents ${FLUKAInterface_LIBRARIES} ${Geant4_LIBRARIES})
#----------------------------------------------------------------------------
# Copy all scripts to the build directory, i.e. the directory in which we
# build HadNucIneEvents. This is so that we can run the executable directly because it
# relies on these scripts being in the current working directory.
#
foreach(_script ${HadNucIneEvents_SCRIPTS})
configure_file(
${PROJECT_SOURCE_DIR}/${_script}
${PROJECT_BINARY_DIR}/${_script}
COPYONLY
)
endforeach()
#----------------------------------------------------------------------------
# Install the executable to 'bin' directory under CMAKE_INSTALL_PREFIX
#
install(TARGETS HadNucIneEvents DESTINATION bin)
@@ -0,0 +1,441 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
/// \file HadNucIneEvents.cc
/// \brief Main program,
/// hadronic/FlukaCern/ProcessLevel/FinalState example.
//
// Author: A. Ribbon, 8 November 2020
// Modified: G. Hugo, 8 December 2022
//
//------------------------------------------------------------------------
//
// HadNucIneEvents
//
/// This program is an adaptation of Hadr09 example.
/// 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,
/// 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),
/// but also in a Flair-compatible format.
///
/// The final states (i.e. secondary particles) produced by
/// hadron-nuclear inelastic collisions are handled by HadronicGenerator.
///
/// The use of the class Hadronic Generator is very simple:
/// the constructor needs to be invoked only once - specifying the name
/// of the "physics case" to consider ("CFLUKAHI" will be
/// considered as default if the name is not specified) - and then one
/// method needs to be called at each collision, specifying the type of
/// collision (hadron, energy, direction, material) to be simulated.
/// The class HadronicGenerator is expected to work also in a
/// multi-threaded environment with "external" threads (i.e. threads
/// that are not necessarily managed by Geant4 run-manager):
/// each thread should have its own instance of the class.
///
/// See the string "***LOOKHERE***" below for the setting of parameters
/// of this example: the "physics case", the set of possibilities from
/// which to sample the projectile
/// a list of hadrons is possible from which to sample at each collision),
/// the kinetic energy of the projectile (which can be sampled within
/// an interval), whether the direction of the projectile is fixed or
/// sampled at each collision, the target material (a list of materials
/// is possible, from which the target material can be sampled at each
/// collision, and then from this target material, the target nucleus
/// will be chosen randomly by Geant4 itself), and whether to print out
/// some information or not and how frequently.
/// Once a well-defined type of hadron-nucleus
/// inelastic collision has been chosen, the method
/// HadronicGenerator::GenerateInteraction
/// returns the secondaries produced by that interaction (in the form
/// 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,
/// so that results are reproducible from one simulation to the next.
///
/// Use: build/HadNucIneEvents
//
//------------------------------------------------------------------------
//....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"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
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".
// ( In short, it is the name of the Geant4 hadronic model used for the simulation of
// the collision, with the possibility of having a transition between two models in
// a given energy interval, as in physics lists. )
//***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";
// 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
// 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") {
namePhysics = G4String("FTFP_BERT");
numCollisions = 10;
}
// 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
// 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-" );
G4ParticleDefinition* projectileNucleus = nullptr;
G4GenericIon* gion = G4GenericIon::GenericIon();
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 );
}
// 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" );
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
<< "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() : "") << 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;
// Set up histo manager.
auto histoManager = FinalStateHistoManager();
histoManager.Book();
// Instanciate the HadronicGenerator providing the name of the "physics case"
HadronicGenerator* theHadronicGenerator = new HadronicGenerator( namePhysics );
//****************************************************************************
if ( theHadronicGenerator == nullptr ) {
G4cerr << "ERROR: theHadronicGenerator is NULL !" << G4endl;
return 1;
} 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();
// Loop over the collisions
G4double rnd1, rnd2, rnd3, rnd4, rnd5, rnd6, normalization, projectileEnergy;
G4VParticleChange* aChange = nullptr;
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();
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;
// 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 ;
//***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 );
}
// 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 ) {
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 ) {
G4cerr << "ERROR: Material " << nameMaterial << " is not found !" << G4endl;
return 3;
}
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;
}
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 );
G4int nsec = aChange ? aChange->GetNumberOfSecondaries() : 0;
G4bool isPrintingOfSecondariesEnabled = false;
if ( isPrintingEnabled ) {
G4cout << G4endl << "\t --> #secondaries=" << nsec
<< " ; impactParameter[fm]="
<< theHadronicGenerator->GetImpactParameter() / fermi
<< " ; #projectileSpectatorNucleons="
<< theHadronicGenerator->GetNumberOfProjectileSpectatorNucleons()
<< " ; #targetSpectatorNucleons="
<< theHadronicGenerator->GetNumberOfTargetSpectatorNucleons()
<< " ; #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 ) {
const G4DynamicParticle* sec = aChange->GetSecondary(j)->GetDynamicParticle();
if ( isPrintingOfSecondariesEnabled ) {
G4cout << "\t \t \t j=" << j << "\t" << sec->GetDefinition()->GetParticleName()
<< "\t p=" << sec->Get4Momentum() << " MeV" << G4endl;
}
// Store each secondary.
histoManager.ScoreSecondary(sec);
delete aChange->GetSecondary(j);
}
if ( aChange ) aChange->Clear();
histoManager.EndOfEvent();
}
histoManager.EndOfRun();
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;
G4cout << G4endl;
G4cout << "Processed " << numCollisions << " events (collisions) in "
<< std::scientific << time << " seconds."
<< " Average: " << std::defaultfloat << (time * 1E3 / numCollisions) << " ms / event."
<< G4endl;
G4cout << G4endl;
G4cout << "=== End of test ===" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,19 @@
-------------------------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
HadNucIneEvents History file
-------------------
This file should be used by the G4 example coordinator to briefly
summarize all major modifications introduced in the code and keep
track of all tags.
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
08-12-22 Gabrielle Hugo (exHadNucIneEvents-V11-01-00)
- Created this example (from `Hadr09`).
@@ -0,0 +1,151 @@
=== Test of the HadronicGenerator ===
================= Configuration ==================
Model: FTFP_BERT
Ekin: [ 7000 , 7000 ] GeV
Number of collisions: 10
Number of hadron projectiles: 1
Number of materials: 1
IsIonProjectile: false
===================================================
### FinalStateHistoManager::Book: Successfully opended file all_secondaries.root for dumping histograms.
================================================================================
INCL++ WARNING
INCL++/G4ExcitationHandler could not use its own level-density parameter for fission
================================================================================
Collision 0 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C=======================================================================
====== Geant4 Native Pre-compound Model Parameters ========
=======================================================================
Type of pre-compound inverse x-section 3
Pre-compound model active 1
Pre-compound excitation low energy 100 keV
Pre-compound excitation high energy 30 MeV
Angular generator for pre-compound model 1
Use NeverGoBack option for pre-compound model 0
Use SoftCutOff option for pre-compound model 0
Use CEM transitions for pre-compound model 1
Use GNASH transitions for pre-compound model 0
Use HETC submodel for pre-compound model 0
=======================================================================
====== Nuclear De-excitation Module Parameters ========
=======================================================================
Type of de-excitation inverse x-section 3
Type of de-excitation factory Evaporation+GEM
Number of de-excitation channels 68
Min excitation energy 10 eV
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
Time limit for long lived isomeres 1 ns
Isomer production flag 1
Internal e- conversion flag 1
Store e- internal conversion data 0
Correlated gamma emission flag 0
Max 2J for sampling of angular correlations 10
=======================================================================
--> #secondaries=44 impactParameter[fm]=2.20708 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=10 #NNcollisions=2
List of produced secondaries:
j=0 pi0 p=(-278.056,-54.2443,249603249603) MeV
j=1 pi+ p=(230.029,220.459,171303171304) MeV
j=2 pi0 p=(-469.822,62.0587,83597.283598.7) MeV
j=3 kaon0L p=(-807.182,-630.872,7481.167567.36) MeV
j=4 pi+ p=(-18.2834,94.391,4761.174764.19) MeV
j=5 pi- p=(-65.525,38.2802,21213.921214.5) MeV
j=6 kaon+ p=(902.744,526.473,225354225357) MeV
j=7 pi- p=(-25.0614,-160.697,62327.162327.5) MeV
j=8 proton p=(457.791,307.539,357.451145.55) MeV
j=9 pi+ p=(187.049,258.114,13773.813778.2) MeV
j=10 eta_prime p=(407.557,161.798,29438.329457.2) MeV
j=11 pi- p=(129.938,-141.881,4209.444216.15) MeV
j=12 pi0 p=(71.0042,453.782,6627.166644.43) MeV
j=13 neutron p=(-16.419,129.541,310.001997.965) MeV
j=14 proton p=(135.377,-168.25,28.0742963.212) MeV
j=15 pi0 p=(125.272,-388.858,1.53492e+061.53492e+06) MeV
j=16 neutron p=(-255.463,71.5904,3.54864e+063.54864e+06) MeV
j=17 pi0 p=(117.323,-60.3735,-34.8848191.951) MeV
j=18 neutron p=(446.611,-171.762,1383.281739.32) MeV
j=19 pi- p=(210.496,175.307,1032.121076.94) MeV
j=20 kaon+ p=(690.16,73.5808,9055.49095.37) MeV
j=21 pi- p=(177.308,-219.884,3488.423502.62) MeV
j=22 pi0 p=(-53.4748,65.7408,2602.062606.93) MeV
j=23 pi+ p=(-144.662,198.791,3725.553736.26) MeV
j=24 pi- p=(429.909,309.238,52688.552691.4) MeV
j=25 pi+ p=(-15.7564,-416.423,91345.391346.3) MeV
j=26 pi- p=(-35.5745,175.967,45452.845453.3) MeV
j=27 pi+ p=(-361.018,-259.16,2125021255.1) MeV
j=28 pi- p=(-1222.43,64.7139,89625.989634.4) MeV
j=29 pi0 p=(-295.877,103.056,27493.927496) MeV
j=30 pi+ p=(-308.863,130.216,5371453715.3) MeV
j=31 pi0 p=(-106.131,119.136,43773.943774.4) MeV
j=32 kaon0S p=(810.072,-3.24422,165782165785) MeV
j=33 pi0 p=(-115.05,-174.435,1450.991472.16) MeV
j=34 pi- p=(291.714,445.213,3613.763655.41) MeV
j=35 pi+ p=(72.3103,36.167,1728917289.7) MeV
j=36 anti_proton p=(-817.196,-1045.02,300634300639) MeV
j=37 pi0 p=(11.2051,-189.687,20817.620818.9) MeV
j=38 proton p=(-249.068,59.6892,80867.280873) MeV
j=39 He3 p=(117.034,-199.489,-159.672822.42) MeV
j=40 deuteron p=(-211.988,-209.404,-136.1621904.01) MeV
j=41 neutron p=(23.8186,-71.9476,-141.265953.144) MeV
j=42 neutron p=(-190.541,431.213,494.9871161.91) MeV
j=43 proton p=(18.7242,-146.424,-86.6639953.759) MeV
Collision 1 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=37 impactParameter[fm]=2.60398 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=1
Collision 2 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=31 impactParameter[fm]=3.28119 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=1
Collision 3 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=46 impactParameter[fm]=3.13666 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=10 #NNcollisions=2
Collision 4 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=7 impactParameter[fm]=3.17708 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=0
Collision 5 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=21 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=63 impactParameter[fm]=1.55971 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=9 #NNcollisions=3
Collision 7 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=6 impactParameter[fm]=2.7974 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=0
Collision 8 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=26 impactParameter[fm]=2.42631 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=11 #NNcollisions=1
Collision 9 projectile=proton Ekin[MeV]=7e+06 direction=(0,0,1) material=G4_C
--> #secondaries=42 impactParameter[fm]=2.60456 #projectileSpectatorNucleons=0 #targetSpectatorNucleons=10 #NNcollisions=1
========================================================
Number of events 10
Average (per event) number of B10[718.380] 0.1
Average (per event) number of He3 0.3
Average (per event) number of alpha 0.8
Average (per event) number of anti_lambda 0.1
Average (per event) number of anti_proton 0.4
Average (per event) number of deuteron 0.8
Average (per event) number of eta 0.8
Average (per event) number of eta_prime 0.9
Average (per event) number of gamma 0.3
Average (per event) number of kaon+ 0.9
Average (per event) number of kaon- 0.4
Average (per event) number of kaon0L 0.7
Average (per event) number of kaon0S 1
Average (per event) number of lambda 0.1
Average (per event) number of neutron 2.2
Average (per event) number of pi+ 6.4
Average (per event) number of pi- 6.2
Average (per event) number of pi0 6
Average (per event) number of proton 3
Average (per event) number of sigma+ 0.1
Average (per event) number of sigma- 0.2
Average (per event) number of sigma0 0.3
Average (per event) number of triton 0.3
========================================================
### All histograms saved to all_secondaries.root
### All histograms saved to all_secondaries.hist
Final random number = 0.957412
Processed 10 events (collisions) in 2.706730e-01 seconds. Average: 27.0673 ms / event.
=== End of test ===
@@ -0,0 +1,181 @@
# Description
This example allows the simulation of hadron-nucleus inelastic nuclear interactions,
and the study of the resulting final states.
It is an adaptation of `Hadr09` example.
It offers all `Hadr09` features, and adds the possibility
of accessing hadron-nucleus inelastic nuclear interaction final states FROM `FLUKA`.
With respect to the `Hadr09` example, the program also adds
the possibility of PLOTTING the final state:
secondaries energy spectra, and 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),
as well as in a Flair-compatible format.
Regarding the extension of `G4H1` to insure `Flair` compatibility,
see `geant4/examples/extended/hadronic/FlukaCern/utils`.
The class `HadronicGenerator` is the "generator".
The main hadronic models (`CernFLUKAHadronInelastic`, `FTFP`, `QGSP`, `BERT`, `BIC`, `IonBIC`, `INCL`) are available.
See `include/HadronicGenerator.hh` for more detailed information.
In the `HadronicGenerator`, one can activate/desactivate coalescence and heavy fragments evaporation for `CernFLUKAHadronInelastic`.
The main, `HadNucIneEvents.cc`, shows an example of how to use the event generator.
In `HadNucIneEvents.cc`, one can select the physics models,
as well as the projectile hadron, its energy, its direction, the target material, and the number of collisions.
Note that the Geant4 run manager is not used.
Before you can access the `FLUKA` hadron-nucleus inelastic models in this example,
you will need to install and setup `FLUKA` and its interface.
See the compulsory "Dependencies" paragraph below.
A version of the interface to `FLUKA` is directly located at `geant4/examples/extended/hadronic/FlukaCern/FlukaInterface`.
Note that for consistency, all calls to the random engine rely on the G4 random engine (including the calls from within the downloaded `FLUKA` release; see the `FlukaInterface` `Makefile` to see how this is handled).
# FLUKA inelastic hadron-nucleus interactions
Hadron-NUCLEON interaction models are based on resonance production and decay below a few GeV,
and on the Dual Parton model above.
Hadron-NUCLEUS interactions: the PEANUT package includes
a detailed Generalised Intra-Nuclear Cascade (GINC) and a preequilibrium stage,
followed by equilibrium processes: evaporation, fission, Fermi break-up, gamma deexcitation.
```
A. Ferrari and P. Sala, “The Physics of High Energy Reactions,” in Proc. Workshop on Nuclear Reaction Data and Nuclear Reactors Physics, Design and Safety, p. 424, World Scientific, 1998.
A. Ferrari and P. Sala, “Nuclear reactions in Monte Carlo codes,” Radiat. Prot. Dosimetry, vol. 99, no. 1-4, pp. 2938, 2002.
```
# Dependencies
### Environment
- **gcc** >= 7 (Linux) and **gcc** >= 9 (MacOS)
In practice, a recent version is recommended, at least `gcc >=10`.
```
gcc --version
```
- **CMake** >= 3.16...3.21
```
cmake3 --version
```
- **G4** >= 11.0.3 (Not tested on older G4 releases: might still work, but with no guarantee).
IMPORTANT: YOU NEED TO SOURCE YOUR G4 ENVIRONMENT.
It needs to be sourced in whichever terminal you want to build / run a G4 application with the `FLUKA` interface.
```
source path_to_geant4/install/bin/geant4.sh
which geant4-config # NB: Your geant4-config should support the modern CMake way of building G4.
```
- **Easy setup on lxplus** (lxplus7):
All you need to do on lxplus, to setup an environment satisfying all the conditions above, is, for example:
```
source /cvmfs/sft.cern.ch/lcg/releases/gcc/10.1.0/x86_64-centos7/setup.sh
source /cvmfs/geant4.cern.ch/geant4/11.1/x86_64-centos7-gcc10-optdeb-MT/CMake-setup.sh
# NB: Your geant4.sh is at: /cvmfs/geant4.cern.ch/geant4/11.1/x86_64-centos7-gcc10-optdeb-MT/bin/geant4.sh
```
### `FLUKA4`
Release: >= **4-3.2**
Please install the latest `FLUKA` release.
(1) You first need to register (and accept the licence when relevant): https://fluka.cern/download/registration
(2) You can then download the `binary libraries` (or potentially the `source code` package, depending on your case):
https://fluka.cern/download/latest-fluka-release.
(3) Follow the `FLUKA` installation instructions: https://fluka.cern/documentation/installation
In particular, for a Linux/MacOS install: https://fluka.cern/documentation/installation/fluka-linux-macos
They will show you how to setup `FLUKA`.
If (and only if) you went for the source code package option, you will need to build `fluka`, and, in addition, to do `make cpp_headers` at `path_to_fluka/src`.
(4) Eventually, all you need are the headers `fluka_repo/include`, libraries `fluka_repo/lib`, and data `fluka_repo/data`. Check that they are not empty.
Do not forget to add `/path_to_fluka/bin` to your `PATH`. Check with `which fluka`.
### `FlukaInterface`
A version of the G4-FLUKA interface (`FLUKA` hadron-nucleus inelastic physics)
is located at `geant4/examples/extended/hadronic/FlukaCern/FlukaInterface`.
You will first need to build the interface to `FLUKA`, and create the environment scripts.
```bash
$ cd geant4/examples/extended/hadronic/FlukaCern/FlukaInterface/
# Check with `which fluka` that fluka executable is added to your `PATH`.
$ source path_to_geant4/install/bin/geant4.sh
$ make interface
$ make env # Creates `env_FLUKA.sh` and `env_FLUKA_G4_interface.sh`
```
IMPORTANT: `env_FLUKA_G4_interface.sh` needs to be sourced in whichever terminal
you want to build / run a G4 application with the `FLUKA` interface.
# Build this example
```bash
$ cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
# Check with `which fluka` that fluka executable is added to your `PATH`.
$ source path_to_geant4/install/bin/geant4.sh
$ source ../../FlukaInterface/env_FLUKA_G4_interface.sh
$ mkdir build
$ cd build
$ cmake3 -DG4_USE_FLUKA=1 ..
$ make -j8
```
# Run this example
```bash
$ cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
# Check with `which fluka` that fluka executable is added to your `PATH`.
$ source path_to_geant4/install/bin/geant4.sh
$ source ../../FlukaInterface/env_FLUKA_G4_interface.sh
$ ./build/HadNucIneEvents
```
# Study the final states
All plots are dumped at the end of the run in `all_secondaries.ext`.
2 formats are supported: `ROOT` and `Flair`.
- You can use `ROOT`:
```bash
$ cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
$ root all_secondaries.root
```
- Alternatively, the use of `Flair` is also supported.
Please see http://flair.web.cern.ch/flair/download.html for `Flair` download.
`Flair` tutorials are also available from that website.
You can download the package corresponding to your distribution at the top of the page
(no need for `geoviewer`, which is for geometry display). Then look at the requirements & installation instructions at the bottom of the page.
If you face issues installing `Flair`, you can get support at: https://fluka-forum.web.cern.ch/c/installation/
An example file, showing how to directly visualize the final states with Flair, is provided in this G4 example.
By default, it directly provides comparison plots:
`FTFP_BERT` versus `QGSP_BERT` versus `CernFLUKAHadronInelastic`, 7TeV proton on C.
You can very easily adapt it to any study of interest (choice of physics models, choice of secondaries, etc).
```bash
$ cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
$ mkdir -p results/FLUKAHadronInelastic results/FTFP_BERT results/QGSP_BERT
$
$ # Choose physics case (modify HadNucIneEvents.cc), compile the G4 example, then run physics case:
$ cd results/FLUKAHadronInelastic
$ ../../build/HadNucIneEvents
$ # Etc for EACH physics case: FLUKAHadronInelastic, FTFP_BERT, QGSP_BERT.
$
$ cd geant4/examples/extended/hadronic/FlukaCern/ProcessLevel/FinalState/
$ ./update_final_state_flair_file.sh # Update `Det` indices in Flair file, to the ones observed in your simulation.
$ flair study_final_state.flair &
```
In the `Plot` tab, you can select the plot of interest in the left column,
and then click `Plot` (top banner, yellow button).
You can select a physics case by clicking on its name in the `Detectors` box (center). You can then decide to change its color, line width (`Options` box). You can decide to plot it or not, by selecting / unselecting `graph` in the `Show` box (in the center).
IMPORTANT: You can select any secondary data (or residual nuclei data) which was created,
by chosing in the `Det` selection (button on the right).
IMPORTANT: If a secondary does not appear in the `Det` drop-down menu, it means it is not part of the final state. In that case, you will want to unselect `graph`, so that no other secondary (see `Det`) is plotted.
You can change the path of the data file by clicking on the folder button (button on the right).
You can set the plots extrema, as well as select or unselect the log format, in the top right corner.
@@ -0,0 +1,129 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/// \file FinalStateHistoManager.hh
/// \brief Create a set of histos for final state study.
//
// Author: G.Hugo, 08 December 2022
//
// ***************************************************************************
//
// FinalStateHistoManager
//
/// Create a set of histos for final state study.
/// 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
/// (one histo per secondary).
/// In addition, the residual nuclei Z and A distributions are plotted.
///
/// All histograms are G4H1.
/// They are created and filled via the G4VAnalysisManager.
///
/// 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
/// 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.
/// 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.
/// It could also be added as an extension of core G4 Analysis Manager.
//
// ***************************************************************************
#ifndef FINAL_STATE_HISTO_MANAGER_HH
#define FINAL_STATE_HISTO_MANAGER_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 {
public:
FinalStateHistoManager();
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";
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 fNumEvents = 0;
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;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
#endif
@@ -0,0 +1,183 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/// \file HadronicGenerator.hh
/// \brief Definition of the HadronicGenerator class
//
//------------------------------------------------------------------------
// Class: HadronicGenerator
// Author: Alberto Ribon (CERN EP/SFT), May 2020
// Modified: G. Hugo, 8 December 2022
//
/// This class shows how to use Geant4 as a generator for simulating
/// inelastic hadron-nuclear interactions.
/// Some of the most used hadronic models are currently supported in
/// this class:
/// - the hadronic string models Fritiof (FTF) and Quark-Gluon-String (QGS)
/// coupled with Precompound/de-excitation
/// - the intranuclear cascade models: Bertini (BERT), Binary Cascade (BIC),
/// and Liege (INCL)
/// Combinations of two models - in a transition energy interval, with a
/// linear probability as a function of the energy - are also available to
/// "mimic" the transition between hadronic models as in the most common
/// Geant4 reference physics lists.
///
/// The current version of this class does NOT support:
/// - hadron elastic interactions
/// - neutron capture and fission
/// - precise low-energy inelastic interactions of neutrons and
/// charged particles (i.e. ParticleHP)
/// - gamma/lepton-nuclear inelastic interactions
///
/// 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.
//------------------------------------------------------------------------
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef HadronicGenerator_h
#define HadronicGenerator_h 1
#include <iomanip>
#include "globals.hh"
#include "G4ios.hh"
#include "G4ThreeVector.hh"
#include <map>
#include "G4HadronicProcess.hh"
class G4ParticleDefinition;
class G4VParticleChange;
class G4ParticleTable;
class G4Material;
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.
public:
explicit HadronicGenerator( const G4String physicsCase = "FTFP_BERT_ATL" );
// Currently supported final-state hadronic inelastic "physics cases":
// - Hadronic models : CernFLUKAHadronInelastic,
// BERT, BIC, IonBIC, INCL, FTFP, QGSP
// - "Physics-list proxies" : FTFP_BERT_ATL (default), FTFP_BERT,
// QGSP_BERT, QGSP_BIC, FTFP_INCLXX
// (i.e. they are not real, complete physics lists - for instance
// they do not have: transportation, electromagnetic physics,
// hadron elastic scattering, neutron fission and capture, etc. -
// however, they cover all hadron types and all energies by
// combining different hadronic models, i.e. there are transitions
// between two hadronic models in well-defined energy intervals,
// e.g. "FTFP_BERT" has the transition between BERT and FTFP
// hadronic models; moreover, the transition intervals used in
// our "physics cases"might not be the same as in the corresponding
// physics lists).
~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 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 );
// 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
// final-state of the inelastic hadron-nuclear collision as modelled by the
// final-state hadronic inelastic "physics case" specified in the constructor.
// If the required hadronic collision is not possible, then the method returns
// immediately an empty "G4VParticleChange", i.e. without secondaries produced.
const std::map<G4ParticleDefinition*, G4HadronicProcess*>& getAllHadronicProcesses() const {
return fProcessMap;
}
inline G4HadronicProcess* GetHadronicProcess() const;
inline G4HadronicInteraction* GetHadronicInteraction() const;
// Returns the hadronic process and the hadronic interaction, respectively,
// that handled the last call of "GenerateInteraction".
G4double GetImpactParameter() const;
G4int GetNumberOfTargetSpectatorNucleons() const;
G4int GetNumberOfProjectileSpectatorNucleons() const;
G4int GetNumberOfNNcollisions() const;
// In the case of hadronic interactions handled by the FTF model, returns,
// respectively, the impact parameter, the number of target/projectile
// spectator nucleons, and the number of nucleon-nucleon collisions,
// else, returns a negative value (-999).
private:
G4String fPhysicsCase;
G4bool fPhysicsCaseIsSupported = false;
G4HadronicProcess* fLastHadronicProcess = nullptr;
G4ParticleTable* fPartTable = nullptr;
std::map< G4ParticleDefinition*, G4HadronicProcess* > fProcessMap;
};
inline G4bool HadronicGenerator::IsPhysicsCaseSupported() const {
return fPhysicsCaseIsSupported;
}
inline G4HadronicProcess* HadronicGenerator::GetHadronicProcess() const {
return fLastHadronicProcess;
}
inline G4HadronicInteraction* HadronicGenerator::GetHadronicInteraction() const {
return fLastHadronicProcess == nullptr ? nullptr
: fLastHadronicProcess->GetHadronicInteraction();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,373 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
/// \file FinalStateHistoManager.hh
/// \brief Create a set of histos for final state study.
//
// Author: G.Hugo, 08 December 2022
//
// ***************************************************************************
//
// FinalStateHistoManager
//
/// Create a set of histos for final state study.
/// 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
/// (one histo per secondary).
/// In addition, the residual nuclei Z and A distributions are plotted.
///
/// All histograms are G4H1.
/// They are created and filled solely via G4VAnalysisManager.
///
/// 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
/// 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.
/// 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.
/// It could also be added as an extension of core G4 Analysis Manager.
//
// ***************************************************************************
#include "FinalStateHistoManager.hh"
#include "G4RootAnalysisManager.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"
//....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)
{
//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() {
// Open file.
if(!fAnalysisManager->OpenFile(fRootOutputFileName)) {
G4ExceptionDescription 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;
// 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);
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);
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() {
fNumEvents++;
}
// ***************************************************************************
// Fill all plots (WITHIN event, ie the interaction).
// ***************************************************************************
void FinalStateHistoManager::ScoreSecondary(const G4DynamicParticle* const secondary) {
// SELECT SPECIFIC SECONDARIES ONLY
// Select by angle with beam direction
/* if ( (std::pow(secondary->GetMomentumDirection().x(), 2.)
+ std::pow(secondary->GetMomentumDirection().y(), 2.))
<= 0.0001 ) {*/
// Select by production tag
/* if (secondary->GetProductionTag() == 6) {*/
// Primary track
/* if(track->GetParentID() == 0) {*/
const auto& particle = secondary->GetDefinition();
// SECONDARIES ENERGY SPECTRA
// Dynamic creation of histos, so that all encountered particles have their own histos.
// Check whether a particle has already been encountered.
const auto found = fParticleData.find(secondary->GetPDGcode());
G4H1Wrapper* particleHistoWrapper = nullptr;
// If the particle has already been encountered, use the corresponding histos.
if (found != fParticleData.end()) {
particleHistoWrapper = found->second.get();
}
// Otherwise, create histos for that particle.
else {
const G4String& particleName = particle->GetParticleName();
const G4int particlePDG = secondary->GetPDGcode();
const G4String histoTitle = (particlePDG == 0 ?
"Particle pdg==0 spectrum"
: G4String(particleName + " 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)));
}
// Fill the G4H1Wrapper.
const G4double kineticEnergy = secondary->GetKineticEnergy();
particleHistoWrapper->Fill(kineticEnergy, 1.);
// NUCLEI DISTRIBUTIONS IN Z AND A
if (particle->GetParticleType() == "nucleus") {
// Fill the G4H1Wrapper.
const G4double Z = particle->GetPDGCharge() / eplus;
fNucleiData[fNucleiZScoreIndex]->Fill(Z, 1.);
// Fill the G4H1Wrapper.
const G4double A = particle->GetBaryonNumber();
fNucleiData[fNucleiAScoreIndex]->Fill(A, 1.);
}
//} // select secondaries
}
// ***************************************************************************
// End of event: all event-level G4H1 are flushed into the Analysis Manager G4H1.
// ***************************************************************************
void FinalStateHistoManager::EndOfEvent() {
for (const auto& particleIt : fParticleData) {
particleIt.second->EndOfEvent();
}
for (const auto& nucleiScoreIt : fNucleiData) {
nucleiScoreIt.second->EndOfEvent();
}
}
// ***************************************************************************
// Printout secondary counts + dump all plots into relevant formats.
// ***************************************************************************
void FinalStateHistoManager::EndOfRun() const {
// PRINTOUT SECONDARYS COUNTS (FULL ENERGY RANGE).
// Order the histos by particles names.
std::map<G4String, const G4H1Wrapper*> particlesHistos;
for (const auto& particleIt : fParticleData) {
const G4int particlePdg = particleIt.first;
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 << "========================================================" << 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 {
if (!fAnalysisManager->Write()) {
G4ExceptionDescription 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 {
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());
++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());
++indexInOutputFile;
}
output.close();
G4cout << "### All histograms saved to " << fFlairOutputFileName << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,734 @@
# flair project file
Version: 300
Mode: fluka
Title: Study interactions final state: secondaries energy spectra + residual nuclei distribution (0.1M events).
md5: d41d8cd98f00b204e9800998ecf8427e
Input:
EndInput
Page: Plot
plotengine: Gnuplot
# Run information
Run: <default>
queue: *Default
End
Geometry: Geometry
Frame.tsplit: 1.0
End
# Plots information
Plot: proton
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 43
det.1: 44
det.2: 51
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 1
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Protons spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: anti_proton
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 23
det.1: 24
det.2: 26
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 2
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Antiprotons spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: neutron
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 38
det.1: 39
det.2: 43
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 3
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Neutrons spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: anti_neutron
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 21
det.1: 22
det.2: 21
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 4
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Antineutrons spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: pi+
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 40
det.1: 41
det.2: 48
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 5
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Pi+ spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: pi-
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 41
det.1: 42
det.2: 49
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 6
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Pi- spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: pi0
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 42
det.1: 43
det.2: 50
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 7
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Pi0 spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: kaon+
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 33
det.1: 34
det.2: 36
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 8
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Kaon+ spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: kaon-
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 34
det.1: 35
det.2: 37
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 9
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Kaon- spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: kaon0L
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 35
det.1: 36
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 10
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
show.2: 0
title: 7 GeV proton - Al nucleus collisions secondaries: kaon0L spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: kaon0S
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 36
det.1: 37
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 11
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
show.2: 0
title: 7 GeV proton - Al nucleus collisions secondaries: kaon0S spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: deuteron
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 29
det.1: 30
det.2: 32
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 12
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Deuterons spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: triton
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 47
det.1: 48
det.2: 55
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 13
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Tritons spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: He3
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 14
det.1: 14
det.2: 12
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 14
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: He3 spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: alpha
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 19
det.1: 20
det.2: 19
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 15
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Alphas spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: Li6
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 16
det.1: 16
det.2: 15
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 16
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Li6 spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: e-
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.2: 34
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 17
key.0: 0
key.1: 0
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
show.0: 0
show.1: 0
title: 7 TeV proton - C nucleus collisions secondaries: Electrons spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: gamma
Type: USR-1D
cbtics: 1
commands:
|set xtics add ('1meV' 1e-12, '10meV' 1e-11, '100meV' 1e-10, '1eV' 1e-9, '10eV' 1e-8,'100eV' 1e-7,'1keV' 1e-6, '10keV' 1e-5, '100keV' 1e-4, '1MeV' 1e-3, '10MeV' 0.01, '100MeV' 0.1, '1GeV' 1, '10GeV' 10, '100GeV' 100, '1TeV' 1000, '10TeV' 1e4, '100TeV' 1e5)
|set mxtics 10
det.0: 32
det.1: 33
det.2: 35
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 18
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Gammas spectrum (0.1M events)
xlabel: Kinetic Energy
xlog: 1
xmax: 1E4
xmin: 1E-5
y.0: 1
y.1: 1
y.2: 1
ylabel: dN / d(logE) [1/pr]
ylog: 1
ymin: 1E-5
End
Plot: nucleiA
Type: USR-1D
cbtics: 1
commands: set mxtics 10
det.0: 50
det.1: 51
det.2: 58
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 19
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Residual nuclei spectrum (0.1M events)
xlabel: A
xmax: 50.5
xmin: 0
y.0: 0
y.1: 0
y.2: 0
ylabel: N [1/pr]
ymin: 1E-5
End
Plot: nucleiZ
Type: USR-1D
cbtics: 1
commands: set mxtics 5
det.0: 51
det.1: 52
det.2: 59
file.0: results/FTFP_BERT/all_secondaries.hist
file.1: results/QGSP_BERT/all_secondaries.hist
file.2: results/FLUKAHadronInelastic/all_secondaries.hist
grid: 1
index: 20
lc.0: dark-blue
lc.1: light-blue
lc.2: green
lw.0: 2
lw.1: 2
lw.2: 2
name.0: FTFP BERT
name.1: QGSP BERT
name.2: FLUKA
ndetectors: 3
title: 7 TeV proton - C nucleus collisions secondaries: Residual nuclei spectrum (0.1M events)
xlabel: Z
xmax: 25.5
xmin: 0
y.0: 0
y.1: 0
y.2: 0
ylabel: N [1/pr]
ymin: 1E-5
End
@@ -0,0 +1,84 @@
#!/usr/bin/env bash
# This script updates the `Det` fields in the Flair file, to the ones observed during the simulations.
# This is needed because the observed particles in the final state are DYNAMICALLY observed:
# the number of particles changes from one simulation to the next, depending on the physics scenario, the number of events, etc.
# Hence, one needs to look what is the index of the `protons` histogram in the .hist file, etc.
# The use of this script is not needed in the XS G4 example case, because there, a FIXED number of XS are printed in the .hist files.
# Choose input files / number of comparison plots here
flair_file="study_final_state.flair"
num_comparison_plots=3
plot_block_max_length=100
# All plots
all_particles=$(cat $flair_file | grep "Plot:" | cut -d' ' -f2)
# Loop on all plots
for particle in ${all_particles[@]}; do
echo "particle=$particle";
# Line number of the "Plot: " block.
plot_line_number=$(grep -n -m1 "Plot: $particle" $flair_file | cut -d':' -f1)
echo "plot_line_number=$plot_line_number"
# Find out if last plot block in the flair file.
next_plot=$(grep -A$plot_block_max_length "Plot: $particle" $flair_file | grep -n -m2 "Plot: " | wc -l)
if [ "$next_plot" -eq "2" ]; then
has_next_plot=true
else
has_next_plot=false
fi
echo "has_next_plot=$has_next_plot";
# Line number of the next "Plot: " block.
if [ "$has_next_plot" = true ] ; then
next_plot_line_number=$(grep -A$plot_block_max_length "Plot: $particle" $flair_file | grep -n -m2 "Plot: " | tail -n1 | cut -d':' -f1)
# (next_plot_line_number - 1) is the extra number of lines taken by the plot block.
next_plot_line_number=$(($plot_line_number + $next_plot_line_number - 1))
else
# Last line in the flair file.
next_plot_line_number=$(cat $flair_file | wc -l)
fi
echo "next_plot_line_number=$next_plot_line_number"
# Loop on all comparison plots.
for ((i=0; i < $num_comparison_plots; i++)); do
data_file=$(sed -n "$plot_line_number,$next_plot_line_number p" $flair_file | grep "file\.$i" | cut -d' ' -f2)
echo "data_file=$data_file"
# Data file not found: do nothing.
if [ -z "$data_file" ]; then
echo "Warning: Tried to look for data file $data_file, which does not exist! Field is not updated for this file."
# Found the data file.
else
# Get detector value in the data file.
data_det=$(grep "# Detector:.* $particle" $data_file | cut -d' ' -f4)
data_det=$(($data_det - 1)) # An extra -1 because Flair detector indexing starts from 0.
echo "data_det=$data_det"
# Found detector value in data file.
if [ ! -z "$data_det" ]; then
# Look for detector field in the flair file.
flair_det=$(sed -n "$plot_line_number,$next_plot_line_number p" $flair_file | grep "det\.$i")
echo "flair_det=$flair_det"
# Update value in detector field in flair file.
if [ ! -z "$flair_det" ]; then
sed -i "$plot_line_number,$next_plot_line_number s/det\.$i.*/det\.$i: $data_det/g" $flair_file
# Flair file has no detector field in that plot: do not update field.
else
#sed -i "/file\.$i/i \ \tdet\.$i: $data_det" $flair_file
echo "Warning: No det.$i defined for plot $particle, file $data_file: field was not updated."
fi
# Detector not found in data file: remove value in detector field in flair file.
else
sed -i "$plot_line_number,$next_plot_line_number s/det\.$i.*//" $flair_file
fi
fi
done
done