Import Geant4 10.7.0 source tree

This commit is contained in:
Gabriele Cosmo
2020-12-04 12:30:43 +01:00
parent 67ba86d073
commit dab42d2018
3770 changed files with 226369 additions and 286486 deletions
@@ -0,0 +1,53 @@
///\file "hadronic/Hadr09/.README.txt"
///\brief Example Hadr09 README page
/*! \page ExampleHadr09 Example Hadr09
This example shows how to use Geant4 as a generator for simulating
inelastic hadron-nuclear interactions.
The class HadronicGenerator is the "generator".
The main hadronic models (FTFP, QGSP, BERT, BIC, IonBIC, INCL)
and some combinations of two of them - in a transition energy region,
similarly to what happens in physics lists - are available.
See include/HadronicGenerator.hh for more detailed information.
The main, Hadr09.cc, shows an example of how to use it.
It samples randomly the projectile hadron, its energy, its direction
and the target material, and then it calls the generator.
Some information regarding the secondaries which are produced can be
printed out.
See the comments in Hadr09.cc for more information and how eventually
to change some of its configurations.
Notice that Hadr09.cc does nothing really useful: users should consider
to use eventually only the class HadronicGenerator.
Notice that the Geant4 run-manager is not used.
\section Hadr09_s1 HOW TO START ?
To build it:
\verbatim
mkdir Build; cd Build
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DGeant4_DIR=/path-to-geant4-libraries ../.
make
\endverbatim
To run it:
\verbatim
./Hadr09 [Hadr09.in]
\endverbatim
which simulates 1000 hadron-nucleus collisions, randomnly selected, and
prints out some information about the secondaries produced in these
interactions. It takes only a few seconds to run.
Notice that the input file, Hadr09.in, which is empty, is not needed
by Hadr09, and can be omitted; however, it has been created because
is expected by system testing.
Note: this example has been included in Geant4 10.7, but it should work
also for early versions of Geant4, in particular 10.6, 10.5 and 10.4.
*/
@@ -0,0 +1,60 @@
#----------------------------------------------------------------------------
# Setup the project
cmake_minimum_required(VERSION 3.8...3.18)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
project(Hadr09)
#----------------------------------------------------------------------------
# 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})
#----------------------------------------------------------------------------
# Locate sources and headers for this project
#
include_directories(${PROJECT_SOURCE_DIR}/include
${Geant4_INCLUDE_DIR})
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh)
#----------------------------------------------------------------------------
# Add the executable, and link it to the Geant4 libraries
#
add_executable(Hadr09 Hadr09.cc ${sources} ${headers})
target_link_libraries(Hadr09 ${Geant4_LIBRARIES} )
#----------------------------------------------------------------------------
# Copy all scripts to the build directory, i.e. the directory in which we
# build Hadr09. This is so that we can run the executable directly because it
# relies on these scripts being in the current working directory.
#
set(Hadr09_SCRIPTS
hadr09.in
)
foreach(_script ${Hadr09_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 Hadr09 DESTINATION bin)
@@ -0,0 +1,12 @@
name := Hadr09
G4TARGET := $(name)
G4EXLIB := true
ifndef G4INSTALL
G4INSTALL = ../../..
endif
.PHONY: all
all: lib bin
include $(G4INSTALL)/config/binmake.gmk
+268
View File
@@ -0,0 +1,268 @@
//
// ********************************************************************
// * 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 Hadr09.cc
/// \brief Main program of the hadronic/Hadr09 example
//
//------------------------------------------------------------------------
// This program shows how to use the class Hadronic Generator.
// The class HadronicGenerator is a kind of "hadronic generator", i.e.
// provides Geant4 final states (i.e. secondary particles) produced by
// hadron-nuclear inelastic collisions.
// Please see the class itself for more information.
//
// The use of the class Hadronic Generator is very simple:
// the constructor needs to be invoked only once - specifying the name
// of the Geant4 "physics case" to consider ("FTFP_BERT_ATL" will be
// considered as default is 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 collision, i.e. the type of projectile hadron,
// its kinetic energy, its direction and the target material (from the
// latter, 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-nuclear inelastic collisions has
// been chosen, the method HadronicGenerator::GenerateInteraction
// returns the secondaries produced by that interaction (in the form
// of a G4VParticleChange object).
// Some information about this final-state is printed out as an example.
//
// Usage: Hadr09
//------------------------------------------------------------------------
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#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 "CLHEP/Random/Randomize.h"
#include "CLHEP/Random/Ranlux64Engine.h"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
int main( int , char** ) {
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. )
const G4String namePhysics = "FTFP_BERT_ATL"; //***LOOKHERE*** PHYSICS CASE
//const G4String namePhysics = "FTFP_BERT";
//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].
const G4double minEnergy = 1.0*CLHEP::GeV; //***LOOKHERE*** PROJECTILE MIN Ekin
const G4double maxEnergy = 30.0*CLHEP::GeV; //***LOOKHERE*** PROJECTILE MAX Ekin
const G4int numCollisions = 1000; //***LOOKHERE*** NUMBER OF COLLISIONS
// 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.
// 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" );
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" );
// 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*** : possible NIST 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_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 projectiles: " << numProjectiles << G4endl
<< "Number of materials: " << numMaterials << G4endl
<< "===================================================" << G4endl
<< G4endl;
CLHEP::Ranlux64Engine defaultEngine( 1234567, 4 );
CLHEP::HepRandom::setTheEngine( &defaultEngine );
G4int seed = time( NULL );
CLHEP::HepRandom::setTheSeed( seed );
G4cout << G4endl << " Initial seed = " << seed << G4endl << G4endl;
// 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;
}
// Loop over the collisions
G4double rnd1, rnd2, rnd3, rnd4, rnd5, rnd6, normalization, projectileEnergy;
G4VParticleChange* aChange = nullptr;
for ( G4int i = 0; i < numCollisions; ++i ) {
// 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 );
G4ThreeVector 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 ];
// 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
<< " ; Ekin(MeV)=" << projectileEnergy /* << " ; direction=" << aDirection */
<< " ; material=" << nameMaterial;
}
// Call here the "hadronic generator" to get the secondaries produced by the hadronic collision
aChange = theHadronicGenerator->GenerateInteraction( nameProjectile, projectileEnergy,
/* ********************************************** */ aDirection, material );
G4int nsec = aChange ? aChange->GetNumberOfSecondaries() : 0;
G4bool isPrintingOfSecondariesEnabled = false;
if ( isPrintingEnabled ) {
G4cout << " ---> #secondaries=" << nsec << 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;
}
delete aChange->GetSecondary(j);
}
if ( aChange ) aChange->Clear();
}
G4cout << G4endl << " Final random number = " << CLHEP::HepRandom::getTheEngine()->flat()
<< G4endl << "=== End of test ===" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
+19
View File
@@ -0,0 +1,19 @@
-------------------------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
Hadr08 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-11-20 Alberto Ribon (exhadr09-V10-06-00)
- Created this example.
+39
View File
@@ -0,0 +1,39 @@
This example shows how to use Geant4 as a generator for simulating
inelastic hadron-nuclear interactions.
The class HadronicGenerator is the "generator".
The main hadronic models (FTFP, QGSP, BERT, BIC, IonBIC, INCL)
and some combinations of two of them - in a transition energy region,
similarly to what happens in physics lists - are available.
See include/HadronicGenerator.hh for more detailed information.
The main, Hadr09.cc, shows an example of how to use it.
It samples randomly the projectile hadron, its energy, its direction
and the target material, and then it calls the generator.
Some information regarding the secondaries which are produced can be
printed out.
See the comments in Hadr09.cc for more information and how eventually
to change some of its configurations.
Notice that Hadr09.cc does nothing really useful: users should consider
to use eventually only the class HadronicGenerator.
Notice that the Geant4 run-manager is not used.
To build this example:
mkdir Build; cd Build
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DGeant4_DIR=/path-to-geant4-libraries ../.
make
To run it:
./Hadr09 [Hadr09.in]
which simulates 1000 hadron-nucleus collisions, randomnly selected, and
prints out some information about the secondaries produced in these
interactions. It takes only a few seconds to run.
Notice that the input file, Hadr09.in, which is empty, is not needed
by Hadr09, and can be omitted; however, it has been created because
is expected by system testing.
Note: this example has been included in Geant4 10.7, but it should work
also for early versions of Geant4, in particular 10.6, 10.5 and 10.4.
@@ -0,0 +1 @@
# Empty: no input is needed for Hadr09, but is expected by system testing.
@@ -0,0 +1,154 @@
//
// ********************************************************************
// * 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)
// Date: May 2020
//
// 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
// - inelastic nuclear interactions of generic-ions (i.e. projectile ions
// heavier than deuterium, triton, He3 and alpha)
//
// 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>
class G4ParticleDefinition;
class G4VParticleChange;
class G4ParticleTable;
class G4Material;
class G4HadronicProcess;
//....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 : 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();
G4bool IsPhysicsCaseSupported();
// Returns "true" if the physicsCase is supported; "false" otherwise.
G4bool IsApplicable( const G4String &nameProjectile, const G4double projectileEnergy );
G4bool IsApplicable( G4ParticleDefinition* projectileDefinition,
const G4double projectileEnergy );
// 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.
private:
G4String fPhysicsCase;
G4bool fPhysicsCaseIsSupported;
G4ParticleTable* fPartTable;
std::map< G4ParticleDefinition*, G4HadronicProcess* > fProcessMap;
};
inline G4bool HadronicGenerator::IsPhysicsCaseSupported() {
return fPhysicsCaseIsSupported;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -0,0 +1,756 @@
//
// ********************************************************************
// * 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.cc
/// \brief Implementation of the HadronicGenerator class
//
//------------------------------------------------------------------------
// Class: HadronicGenerator
// Author: Alberto Ribon (CERN EP/SFT)
// Date: May 2020
//------------------------------------------------------------------------
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "HadronicGenerator.hh"
#include <iomanip>
#include "globals.hh"
#include "G4ios.hh"
#include "G4PhysicalConstants.hh"
#include "G4Material.hh"
#include "G4ProcessManager.hh"
#include "G4VParticleChange.hh"
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
#include "G4DynamicParticle.hh"
#include "G4DecayPhysics.hh"
#include "G4Box.hh"
#include "G4PVPlacement.hh"
#include "G4Step.hh"
#include "G4UnitsTable.hh"
#include "G4SystemOfUnits.hh"
#include "G4StateManager.hh"
#include "G4TouchableHistory.hh"
#include "G4TransportationManager.hh"
#include "G4PionMinus.hh"
#include "G4PionPlus.hh"
#include "G4KaonMinus.hh"
#include "G4KaonPlus.hh"
#include "G4KaonZeroLong.hh"
#include "G4KaonZeroShort.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4Deuteron.hh"
#include "G4Triton.hh"
#include "G4He3.hh"
#include "G4Alpha.hh"
#include "G4Lambda.hh"
#include "G4SigmaPlus.hh"
#include "G4SigmaZero.hh"
#include "G4SigmaMinus.hh"
#include "G4XiMinus.hh"
#include "G4XiZero.hh"
#include "G4OmegaMinus.hh"
#include "G4AntiProton.hh"
#include "G4AntiNeutron.hh"
#include "G4AntiDeuteron.hh"
#include "G4AntiTriton.hh"
#include "G4AntiHe3.hh"
#include "G4AntiAlpha.hh"
#include "G4AntiLambda.hh"
#include "G4AntiSigmaPlus.hh"
#include "G4AntiSigmaZero.hh"
#include "G4AntiSigmaMinus.hh"
#include "G4AntiXiMinus.hh"
#include "G4AntiXiZero.hh"
#include "G4AntiOmegaMinus.hh"
#include "G4GenericIon.hh"
#include "G4HadronicProcess.hh"
#include "G4PionMinusInelasticProcess.hh"
#include "G4PionPlusInelasticProcess.hh"
#include "G4KaonMinusInelasticProcess.hh"
#include "G4KaonPlusInelasticProcess.hh"
#include "G4KaonZeroSInelasticProcess.hh"
#include "G4KaonZeroLInelasticProcess.hh"
#include "G4ProtonInelasticProcess.hh"
#include "G4NeutronInelasticProcess.hh"
#include "G4DeuteronInelasticProcess.hh"
#include "G4TritonInelasticProcess.hh"
#include "G4He3InelasticProcess.hh"
#include "G4AlphaInelasticProcess.hh"
#include "G4IonInelasticProcess.hh"
#include "G4LambdaInelasticProcess.hh"
#include "G4SigmaMinusInelasticProcess.hh"
#include "G4SigmaPlusInelasticProcess.hh"
#include "G4XiMinusInelasticProcess.hh"
#include "G4XiZeroInelasticProcess.hh"
#include "G4OmegaMinusInelasticProcess.hh"
#include "G4AntiProtonInelasticProcess.hh"
#include "G4AntiNeutronInelasticProcess.hh"
#include "G4AntiDeuteronInelasticProcess.hh"
#include "G4AntiTritonInelasticProcess.hh"
#include "G4AntiHe3InelasticProcess.hh"
#include "G4AntiAlphaInelasticProcess.hh"
#include "G4AntiLambdaInelasticProcess.hh"
#include "G4AntiSigmaMinusInelasticProcess.hh"
#include "G4AntiSigmaPlusInelasticProcess.hh"
#include "G4AntiXiMinusInelasticProcess.hh"
#include "G4AntiXiZeroInelasticProcess.hh"
#include "G4AntiOmegaMinusInelasticProcess.hh"
#include "G4CascadeInterface.hh"
#include "G4TheoFSGenerator.hh"
#include "G4GeneratorPrecompoundInterface.hh"
#include "G4ExcitationHandler.hh"
#include "G4PreCompoundModel.hh"
#include "G4LundStringFragmentation.hh"
#include "G4ExcitedStringDecay.hh"
#include "G4FTFModel.hh"
#include "G4BinaryCascade.hh"
#include "G4BinaryLightIonReaction.hh"
#include "G4INCLXXInterface.hh"
#include "G4AblaInterface.hh"
#include "G4QuasiElasticChannel.hh"
#include "G4QGSMFragmentation.hh"
#include "G4QGSModel.hh"
#include "G4QGSParticipants.hh"
#include "G4VCrossSectionDataSet.hh"
#include "G4CrossSectionInelastic.hh"
#include "G4BGGNucleonInelasticXS.hh"
#include "G4NeutronInelasticXS.hh"
#include "G4BGGPionInelasticXS.hh"
#include "G4ComponentGGHadronNucleusXsc.hh"
#include "G4ChipsHyperonInelasticXS.hh"
#include "G4ComponentAntiNuclNuclearXS.hh"
#include "G4ComponentGGNuclNuclXsc.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
HadronicGenerator::HadronicGenerator( const G4String physicsCase ) :
fPhysicsCase( physicsCase ), fPhysicsCaseIsSupported( false ), fPartTable( nullptr )
{
// The constructor set-ups all the particles, models, cross sections and
// hadronic inelastic processes.
// This should be done only once for each application.
// In the case of a multi-threaded application using this class,
// the constructor should be invoked for each thread,
// i.e. one instance of the class should be kept per thread.
// The particles and processes that are created in this constructor
// will then be used by the method GenerateInteraction at each interaction.
// Notes:
// - Neither the hadronic models nor the cross sections are used directly
// by the method GenerateInteraction, but they are associated to the
// hadronic processes and used by Geant4 to simulate the collision;
// - Although the class generates only final states, but not free mean paths,
// inelastic hadron-nuclear cross sections are needed by Geant4 to sample
// the target nucleus from the target material.
// Definition of particles
G4GenericIon* gion = G4GenericIon::GenericIon();
gion->SetProcessManager( new G4ProcessManager( gion ) );
G4DecayPhysics* decays = new G4DecayPhysics;
decays->ConstructParticle();
fPartTable = G4ParticleTable::GetParticleTable();
fPartTable->SetReadiness();
G4IonTable* ions = fPartTable->GetIonTable();
ions->CreateAllIon();
ions->CreateAllIsomer();
// Build BERT model
G4CascadeInterface* theBERTmodel = new G4CascadeInterface;
// Build BIC model
G4BinaryCascade* theBICmodel = new G4BinaryCascade;
G4PreCompoundModel* thePreEquilib = new G4PreCompoundModel( new G4ExcitationHandler );
theBICmodel->SetDeExcitation( thePreEquilib );
// Build BinaryLightIon model
G4PreCompoundModel* thePreEquilibBis = new G4PreCompoundModel( new G4ExcitationHandler );
G4BinaryLightIonReaction* theIonBICmodel = new G4BinaryLightIonReaction( thePreEquilibBis );
// Build the INCL model
G4INCLXXInterface* theINCLmodel = new G4INCLXXInterface;
const G4bool useAblaDeExcitation = false; // By default INCL uses Preco: set "true" to use
// ABLA DeExcitation
if ( theINCLmodel && useAblaDeExcitation ) {
G4AblaInterface* theAblaInterface = new G4AblaInterface;
theINCLmodel->SetDeExcitation( theAblaInterface );
}
// Build the FTFP model (FTF/Preco) : 3 instances with different energy intervals
G4TheoFSGenerator* theFTFPmodel = new G4TheoFSGenerator;
theFTFPmodel->SetMaxEnergy( 100.0*TeV ); // Needed to run above 25 GeV
G4GeneratorPrecompoundInterface* theCascade = new G4GeneratorPrecompoundInterface;
theCascade->SetDeExcitation( thePreEquilib );
theFTFPmodel->SetTransport( theCascade );
G4LundStringFragmentation* theLundFragmentation = new G4LundStringFragmentation;
G4ExcitedStringDecay* theStringDecay = new G4ExcitedStringDecay( theLundFragmentation );
G4FTFModel* theStringModel = new G4FTFModel;
theStringModel->SetFragmentationModel( theStringDecay );
theFTFPmodel->SetHighEnergyGenerator( theStringModel );
G4TheoFSGenerator* theFTFPmodel_constrained = new G4TheoFSGenerator;
theFTFPmodel_constrained->SetMaxEnergy( 100.0*TeV ); // Needed to run above 25 GeV
theFTFPmodel_constrained->SetTransport( theCascade );
theFTFPmodel_constrained->SetHighEnergyGenerator( theStringModel );
G4TheoFSGenerator* theFTFPmodel_halfConstrained = new G4TheoFSGenerator;
theFTFPmodel_halfConstrained->SetMaxEnergy( 100.0*TeV ); // Needed to run above 25 GeV
theFTFPmodel_halfConstrained->SetTransport( theCascade );
theFTFPmodel_halfConstrained->SetHighEnergyGenerator( theStringModel );
// Build the QGSP model (QGS/Preco)
G4TheoFSGenerator* theQGSPmodel = new G4TheoFSGenerator;
theQGSPmodel->SetMaxEnergy( 100.0*TeV ); // Needed to run above 25 GeV
theQGSPmodel->SetTransport( theCascade );
G4QGSMFragmentation* theQgsmFragmentation = new G4QGSMFragmentation;
G4ExcitedStringDecay* theQgsmStringDecay = new G4ExcitedStringDecay( theQgsmFragmentation );
G4VPartonStringModel* theQgsmStringModel = new G4QGSModel< G4QGSParticipants >;
theQgsmStringModel->SetFragmentationModel( theQgsmStringDecay );
theQGSPmodel->SetHighEnergyGenerator( theQgsmStringModel );
G4QuasiElasticChannel* theQuasiElastic = new G4QuasiElasticChannel; // QGSP uses quasi-elastic
theQGSPmodel->SetQuasiElasticChannel( theQuasiElastic );
// Cross sections (needed by Geant4 to sample the target nucleus from the target material)
G4VCrossSectionDataSet* thePionMinusXSdata =
new G4BGGPionInelasticXS( G4PionMinus::Definition() );
thePionMinusXSdata->BuildPhysicsTable( *(G4PionMinus::Definition()) );
G4VCrossSectionDataSet* thePionPlusXSdata =
new G4BGGPionInelasticXS( G4PionPlus::Definition() );
thePionPlusXSdata->BuildPhysicsTable( *(G4PionPlus::Definition()) );
G4VCrossSectionDataSet* theKaonXSdata =
new G4CrossSectionInelastic( new G4ComponentGGHadronNucleusXsc );
theKaonXSdata->BuildPhysicsTable( *(G4KaonMinus::Definition()) );
theKaonXSdata->BuildPhysicsTable( *(G4KaonPlus::Definition()) );
theKaonXSdata->BuildPhysicsTable( *(G4KaonZeroLong::Definition()) );
theKaonXSdata->BuildPhysicsTable( *(G4KaonZeroShort::Definition()) );
G4VCrossSectionDataSet* theProtonXSdata = new G4BGGNucleonInelasticXS( G4Proton::Proton() );
theProtonXSdata->BuildPhysicsTable( *(G4Proton::Definition()) );
G4VCrossSectionDataSet* theNeutronXSdata = new G4NeutronInelasticXS;
theNeutronXSdata->BuildPhysicsTable( *(G4Neutron::Definition()) );
// For hyperon and anti-hyperons we can use either Chips or, for G4 >= 10.5,
// Glauber-Gribov cross sections
//G4VCrossSectionDataSet* theHyperonsXSdata = new G4ChipsHyperonInelasticXS;
G4VCrossSectionDataSet* theHyperonsXSdata =
new G4CrossSectionInelastic( new G4ComponentGGHadronNucleusXsc );
G4VCrossSectionDataSet* theAntibaryonsXSdata =
new G4CrossSectionInelastic( new G4ComponentAntiNuclNuclearXS );
G4VCrossSectionDataSet* theNuclNuclXSdata =
new G4CrossSectionInelastic( new G4ComponentGGNuclNuclXsc );
// Set up inelastic processes : store them in a map (with particle definition as key)
// for convenience
typedef std::pair< G4ParticleDefinition*, G4HadronicProcess* > ProcessPair;
G4HadronicProcess* thePionMinusInelasticProcess = new G4PionMinusInelasticProcess;
fProcessMap.insert( ProcessPair( G4PionMinus::Definition(), thePionMinusInelasticProcess ) );
G4HadronicProcess* thePionPlusInelasticProcess = new G4PionPlusInelasticProcess;
fProcessMap.insert( ProcessPair( G4PionPlus::Definition(), thePionPlusInelasticProcess ) );
G4HadronicProcess* theKaonMinusInelasticProcess = new G4KaonMinusInelasticProcess;
fProcessMap.insert( ProcessPair( G4KaonMinus::Definition(), theKaonMinusInelasticProcess ) );
G4HadronicProcess* theKaonPlusInelasticProcess = new G4KaonPlusInelasticProcess;
fProcessMap.insert( ProcessPair( G4KaonPlus::Definition(), theKaonPlusInelasticProcess ) );
G4HadronicProcess* theKaonZeroLInelasticProcess = new G4KaonZeroLInelasticProcess;
fProcessMap.insert( ProcessPair( G4KaonZeroLong::Definition(), theKaonZeroLInelasticProcess ) );
G4HadronicProcess* theKaonZeroSInelasticProcess = new G4KaonZeroSInelasticProcess;
fProcessMap.insert( ProcessPair( G4KaonZeroShort::Definition(), theKaonZeroSInelasticProcess ) );
G4HadronicProcess* theProtonInelasticProcess = new G4ProtonInelasticProcess;
fProcessMap.insert( ProcessPair( G4Proton::Definition(), theProtonInelasticProcess ) );
G4HadronicProcess* theNeutronInelasticProcess = new G4NeutronInelasticProcess;
fProcessMap.insert( ProcessPair( G4Neutron::Definition(), theNeutronInelasticProcess ) );
G4HadronicProcess* theDeuteronInelasticProcess = new G4DeuteronInelasticProcess;
fProcessMap.insert( ProcessPair( G4Deuteron::Definition(), theDeuteronInelasticProcess ) );
G4HadronicProcess* theTritonInelasticProcess = new G4TritonInelasticProcess;
fProcessMap.insert( ProcessPair( G4Triton::Definition(), theTritonInelasticProcess ) );
G4HadronicProcess* theHe3InelasticProcess = new G4He3InelasticProcess;
fProcessMap.insert( ProcessPair( G4He3::Definition(), theHe3InelasticProcess ) );
G4HadronicProcess* theAlphaInelasticProcess = new G4AlphaInelasticProcess;
fProcessMap.insert( ProcessPair( G4Alpha::Definition(), theAlphaInelasticProcess ) );
G4HadronicProcess* theIonInelasticProcess = new G4IonInelasticProcess;
fProcessMap.insert( ProcessPair( G4GenericIon::Definition(), theIonInelasticProcess ) );
G4HadronicProcess* theLambdaInelasticProcess = new G4LambdaInelasticProcess;
fProcessMap.insert( ProcessPair( G4Lambda::Definition(), theLambdaInelasticProcess ) );
G4HadronicProcess* theSigmaMinusInelasticProcess = new G4SigmaMinusInelasticProcess;
fProcessMap.insert( ProcessPair( G4SigmaMinus::Definition(), theSigmaMinusInelasticProcess ) );
G4HadronicProcess* theSigmaPlusInelasticProcess = new G4SigmaPlusInelasticProcess;
fProcessMap.insert( ProcessPair( G4SigmaPlus::Definition(), theSigmaPlusInelasticProcess ) );
G4HadronicProcess* theXiMinusInelasticProcess = new G4XiMinusInelasticProcess;
fProcessMap.insert( ProcessPair( G4XiMinus::Definition(), theXiMinusInelasticProcess ) );
G4HadronicProcess* theXiZeroInelasticProcess = new G4XiZeroInelasticProcess;
fProcessMap.insert( ProcessPair( G4XiZero::Definition(), theXiZeroInelasticProcess ) );
G4HadronicProcess* theOmegaMinusInelasticProcess = new G4OmegaMinusInelasticProcess;
fProcessMap.insert( ProcessPair( G4OmegaMinus::Definition(), theOmegaMinusInelasticProcess ) );
G4HadronicProcess* theAntiProtonInelasticProcess = new G4AntiProtonInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiProton::Definition(), theAntiProtonInelasticProcess ) );
G4HadronicProcess* theAntiNeutronInelasticProcess = new G4AntiNeutronInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiNeutron::Definition(), theAntiNeutronInelasticProcess ) );
G4HadronicProcess* theAntiDeuteronInelasticProcess = new G4AntiDeuteronInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiDeuteron::Definition(),
theAntiDeuteronInelasticProcess ) );
G4HadronicProcess* theAntiTritonInelasticProcess = new G4AntiTritonInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiTriton::Definition(), theAntiTritonInelasticProcess ) );
G4HadronicProcess* theAntiHe3InelasticProcess = new G4AntiHe3InelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiHe3::Definition(), theAntiHe3InelasticProcess ) );
G4HadronicProcess* theAntiAlphaInelasticProcess = new G4AntiAlphaInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiAlpha::Definition(), theAntiAlphaInelasticProcess ) );
G4HadronicProcess* theAntiLambdaInelasticProcess = new G4AntiLambdaInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiLambda::Definition(), theAntiLambdaInelasticProcess ) );
G4HadronicProcess* theAntiSigmaMinusInelasticProcess = new G4AntiSigmaMinusInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiSigmaMinus::Definition(),
theAntiSigmaMinusInelasticProcess ) );
G4HadronicProcess* theAntiSigmaPlusInelasticProcess = new G4AntiSigmaPlusInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiSigmaPlus::Definition(),
theAntiSigmaPlusInelasticProcess ) );
G4HadronicProcess* theAntiXiMinusInelasticProcess = new G4AntiXiMinusInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiXiMinus::Definition(), theAntiXiMinusInelasticProcess ) );
G4HadronicProcess* theAntiXiZeroInelasticProcess = new G4AntiXiZeroInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiXiZero::Definition(), theAntiXiZeroInelasticProcess ) );
G4HadronicProcess* theAntiOmegaMinusInelasticProcess = new G4AntiOmegaMinusInelasticProcess;
fProcessMap.insert( ProcessPair( G4AntiOmegaMinus::Definition(),
theAntiOmegaMinusInelasticProcess ) );
// Add the cross sections to the corresponding hadronic processes
thePionMinusInelasticProcess->AddDataSet( thePionMinusXSdata );
thePionPlusInelasticProcess->AddDataSet( thePionPlusXSdata );
theKaonMinusInelasticProcess->AddDataSet( theKaonXSdata );
theKaonPlusInelasticProcess->AddDataSet( theKaonXSdata );
theKaonZeroLInelasticProcess->AddDataSet( theKaonXSdata );
theKaonZeroSInelasticProcess->AddDataSet( theKaonXSdata );
theProtonInelasticProcess->AddDataSet( theProtonXSdata );
theNeutronInelasticProcess->AddDataSet( theNeutronXSdata );
theDeuteronInelasticProcess->AddDataSet( theNuclNuclXSdata );
theTritonInelasticProcess->AddDataSet( theNuclNuclXSdata );
theHe3InelasticProcess->AddDataSet( theNuclNuclXSdata );
theAlphaInelasticProcess->AddDataSet( theNuclNuclXSdata );
theIonInelasticProcess->AddDataSet( theNuclNuclXSdata );
theLambdaInelasticProcess->AddDataSet( theHyperonsXSdata );
theSigmaMinusInelasticProcess->AddDataSet( theHyperonsXSdata );
theSigmaPlusInelasticProcess->AddDataSet( theHyperonsXSdata );
theXiMinusInelasticProcess->AddDataSet( theHyperonsXSdata );
theXiZeroInelasticProcess->AddDataSet( theHyperonsXSdata );
theOmegaMinusInelasticProcess->AddDataSet( theHyperonsXSdata );
theAntiProtonInelasticProcess->AddDataSet( theAntibaryonsXSdata );
theAntiNeutronInelasticProcess->AddDataSet( theAntibaryonsXSdata );
theAntiDeuteronInelasticProcess->AddDataSet( theAntibaryonsXSdata );
theAntiTritonInelasticProcess->AddDataSet( theAntibaryonsXSdata );
theAntiHe3InelasticProcess->AddDataSet( theAntibaryonsXSdata );
theAntiAlphaInelasticProcess->AddDataSet( theHyperonsXSdata );
theAntiLambdaInelasticProcess->AddDataSet( theHyperonsXSdata );
theAntiSigmaMinusInelasticProcess->AddDataSet( theHyperonsXSdata );
theAntiSigmaPlusInelasticProcess->AddDataSet( theHyperonsXSdata );
theAntiXiMinusInelasticProcess->AddDataSet( theHyperonsXSdata );
theAntiXiZeroInelasticProcess->AddDataSet( theHyperonsXSdata );
theAntiOmegaMinusInelasticProcess->AddDataSet( theHyperonsXSdata );
// Register the proper hadronic model(s) to the corresponding hadronic processes.
// Note: hadronic models ("BERT", "BIC", "IonBIC", "INCL", "FTFP", "QGSP") are
// used for the hadrons and energies they are applicable
// (exception for INCL, which in recent versions of Geant4 can handle
// more hadron types and higher energies than considered here).
// For "physics-list proxies" ("FTFP_BERT", "FTFP_BERT_ATL", "QGSP_BERT",
// "QGSP_BIC", "FTFP_INCLXX"), all hadron types and all energies are covered
// by combining different hadronic models - similarly (but not identically)
// to the corresponding physics lists.
if ( fPhysicsCase == "BIC" ||
fPhysicsCase == "QGSP_BIC" ) {
// The BIC model is applicable to nucleons and pions,
// whereas in the physics list QGSP_BIC it is used only for nucleons
fPhysicsCaseIsSupported = true;
theProtonInelasticProcess->RegisterMe( theBICmodel );
theNeutronInelasticProcess->RegisterMe( theBICmodel );
if ( fPhysicsCase == "BIC" ) {
thePionMinusInelasticProcess->RegisterMe( theBICmodel );
thePionPlusInelasticProcess->RegisterMe( theBICmodel );
} else {
thePionMinusInelasticProcess->RegisterMe( theBERTmodel );
thePionPlusInelasticProcess->RegisterMe( theBERTmodel );
}
} else if ( fPhysicsCase == "INCL" ||
fPhysicsCase == "FTFP_INCLXX" ) {
// We consider here for simplicity only nucleons and pions
// (although recent versions of INCL can handle others particles as well)
fPhysicsCaseIsSupported = true;
thePionMinusInelasticProcess->RegisterMe( theINCLmodel );
thePionPlusInelasticProcess->RegisterMe( theINCLmodel );
theProtonInelasticProcess->RegisterMe( theINCLmodel );
theNeutronInelasticProcess->RegisterMe( theINCLmodel );
}
if ( fPhysicsCase == "IonBIC" ||
fPhysicsCase == "FTFP_BERT_ATL" ||
fPhysicsCase == "FTFP_BERT" ||
fPhysicsCase == "FTFP_INCLXX" ||
fPhysicsCase == "QGSP_BERT" ||
fPhysicsCase == "QGSP_BIC" ) {
// The Binary Light Ion model is used for light ions in all physics lists
fPhysicsCaseIsSupported = true;
theDeuteronInelasticProcess->RegisterMe( theIonBICmodel );
theTritonInelasticProcess->RegisterMe( theIonBICmodel );
theHe3InelasticProcess->RegisterMe( theIonBICmodel );
theAlphaInelasticProcess->RegisterMe( theIonBICmodel );
}
if ( fPhysicsCase == "QGSP" ||
fPhysicsCase == "QGSP_BERT" ||
fPhysicsCase == "QGSP_BIC" ) {
// Although the QGSP model can handle also hyperons and anti-baryons,
// in the physics lists it is used only for pions, kaons and nucleons
fPhysicsCaseIsSupported = true;
thePionMinusInelasticProcess->RegisterMe( theQGSPmodel );
thePionPlusInelasticProcess->RegisterMe( theQGSPmodel );
theKaonMinusInelasticProcess->RegisterMe( theQGSPmodel );
theKaonPlusInelasticProcess->RegisterMe( theQGSPmodel );
theKaonZeroLInelasticProcess->RegisterMe( theQGSPmodel );
theKaonZeroSInelasticProcess->RegisterMe( theQGSPmodel );
theProtonInelasticProcess->RegisterMe( theQGSPmodel );
theNeutronInelasticProcess->RegisterMe( theQGSPmodel );
if ( fPhysicsCase == "QGSP" ) {
theLambdaInelasticProcess->RegisterMe( theQGSPmodel );
theSigmaMinusInelasticProcess->RegisterMe( theQGSPmodel );
theSigmaPlusInelasticProcess->RegisterMe( theQGSPmodel );
theXiMinusInelasticProcess->RegisterMe( theQGSPmodel );
theXiZeroInelasticProcess->RegisterMe( theQGSPmodel );
theOmegaMinusInelasticProcess->RegisterMe( theQGSPmodel );
theAntiProtonInelasticProcess->RegisterMe( theQGSPmodel );
theAntiNeutronInelasticProcess->RegisterMe( theQGSPmodel );
theAntiDeuteronInelasticProcess->RegisterMe( theQGSPmodel );
theAntiTritonInelasticProcess->RegisterMe( theQGSPmodel );
theAntiHe3InelasticProcess->RegisterMe( theQGSPmodel );
theAntiAlphaInelasticProcess->RegisterMe( theQGSPmodel );
theAntiLambdaInelasticProcess->RegisterMe( theQGSPmodel );
theAntiSigmaMinusInelasticProcess->RegisterMe( theQGSPmodel );
theAntiSigmaPlusInelasticProcess->RegisterMe( theQGSPmodel );
theAntiXiMinusInelasticProcess->RegisterMe( theQGSPmodel );
theAntiXiZeroInelasticProcess->RegisterMe( theQGSPmodel );
theAntiOmegaMinusInelasticProcess->RegisterMe( theQGSPmodel );
}
}
if ( fPhysicsCase == "BERT" ||
fPhysicsCase == "FTFP_BERT_ATL" ||
fPhysicsCase == "FTFP_BERT" ||
fPhysicsCase == "QGSP_BERT" ) {
// The BERT model is used for pions and nucleons in all Bertini-based physics lists
fPhysicsCaseIsSupported = true;
thePionMinusInelasticProcess->RegisterMe( theBERTmodel );
thePionPlusInelasticProcess->RegisterMe( theBERTmodel );
theProtonInelasticProcess->RegisterMe( theBERTmodel );
theNeutronInelasticProcess->RegisterMe( theBERTmodel );
}
if ( fPhysicsCase == "BERT" ||
fPhysicsCase == "FTFP_BERT_ATL" ||
fPhysicsCase == "FTFP_BERT" ||
fPhysicsCase == "FTFP_INCLXX" ||
fPhysicsCase == "QGSP_BERT" ||
fPhysicsCase == "QGSP_BIC" ) {
// The BERT model is used for kaons and hyperons in all physics lists, but not for light ions
fPhysicsCaseIsSupported = true;
theKaonMinusInelasticProcess->RegisterMe( theBERTmodel );
theKaonPlusInelasticProcess->RegisterMe( theBERTmodel );
theKaonZeroLInelasticProcess->RegisterMe( theBERTmodel );
theKaonZeroSInelasticProcess->RegisterMe( theBERTmodel );
theLambdaInelasticProcess->RegisterMe( theBERTmodel );
theSigmaMinusInelasticProcess->RegisterMe( theBERTmodel );
theSigmaPlusInelasticProcess->RegisterMe( theBERTmodel );
theXiMinusInelasticProcess->RegisterMe( theBERTmodel );
theXiZeroInelasticProcess->RegisterMe( theBERTmodel );
theOmegaMinusInelasticProcess->RegisterMe( theBERTmodel );
if ( fPhysicsCase == "BERT" ) {
theDeuteronInelasticProcess->RegisterMe( theBERTmodel );
theTritonInelasticProcess->RegisterMe( theBERTmodel );
theHe3InelasticProcess->RegisterMe( theBERTmodel );
theAlphaInelasticProcess->RegisterMe( theBERTmodel );
}
}
if ( fPhysicsCase == "FTFP" ||
fPhysicsCase == "FTFP_BERT_ATL" ||
fPhysicsCase == "FTFP_BERT" ||
fPhysicsCase == "FTFP_INCLXX" ||
fPhysicsCase == "QGSP_BERT" ||
fPhysicsCase == "QGSP_BIC" ) {
// The FTFP model is applied for all hadrons, but in different energy intervals according
// whether it is consider as a stand-alone hadronic model, or within physics lists
fPhysicsCaseIsSupported = true;
theAntiProtonInelasticProcess->RegisterMe( theFTFPmodel );
theAntiNeutronInelasticProcess->RegisterMe( theFTFPmodel );
theAntiDeuteronInelasticProcess->RegisterMe( theFTFPmodel );
theAntiTritonInelasticProcess->RegisterMe( theFTFPmodel );
theAntiHe3InelasticProcess->RegisterMe( theFTFPmodel );
theAntiAlphaInelasticProcess->RegisterMe( theFTFPmodel );
theAntiLambdaInelasticProcess->RegisterMe( theFTFPmodel );
theAntiSigmaMinusInelasticProcess->RegisterMe( theFTFPmodel );
theAntiSigmaPlusInelasticProcess->RegisterMe( theFTFPmodel );
theAntiXiMinusInelasticProcess->RegisterMe( theFTFPmodel );
theAntiXiZeroInelasticProcess->RegisterMe( theFTFPmodel );
theAntiOmegaMinusInelasticProcess->RegisterMe( theFTFPmodel );
G4TheoFSGenerator* theFTFPmodelToBeUsed = theFTFPmodel_constrained;
if ( fPhysicsCase == "FTFP" ) theFTFPmodelToBeUsed = theFTFPmodel;
thePionMinusInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
thePionPlusInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theKaonMinusInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theKaonPlusInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theKaonZeroLInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theKaonZeroSInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theProtonInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theNeutronInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theFTFPmodelToBeUsed = theFTFPmodel_halfConstrained;
if ( fPhysicsCase == "FTFP" ) theFTFPmodelToBeUsed = theFTFPmodel;
theDeuteronInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theTritonInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theHe3InelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theAlphaInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theIonInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theLambdaInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theSigmaMinusInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theSigmaPlusInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theXiMinusInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theXiZeroInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
theOmegaMinusInelasticProcess->RegisterMe( theFTFPmodelToBeUsed );
}
if ( ! fPhysicsCaseIsSupported ) {
G4cerr << "ERROR: Not supported final-state hadronic inelastic physics case !"
<< fPhysicsCase << G4endl
<< "\t Re-try by choosing one of the following:" << G4endl
<< "\t - Hadronic models : BERT, BIC, IonBIC, INCL, FTFP, QGSP" << G4endl
<< "\t - \"Physics-list proxies\" : FTFP_BERT_ATL (default), FTFP_BERT, \
QGSP_BERT, QGSP_BIC, FTFP_INCLXX"
<< G4endl;
}
// For the case of "physics-list proxies", select the energy range for each hadronic model.
// Note: the transition energy between hadronic models vary between physics lists,
// type of hadrons, and version of Geant4. Here, for simplicity, we use an uniform
// energy transition for all types of hadrons and regarless of the Geant4 version;
// moreover, for "FTFP_INCLXX" we use a different energy transition range
// between FTFP and INCL than in the real physics list.
if ( fPhysicsCase == "FTFP_BERT_ATL" ||
fPhysicsCase == "FTFP_BERT" ||
fPhysicsCase == "FTFP_INCLXX" ||
fPhysicsCase == "QGSP_BERT" ||
fPhysicsCase == "QGSP_BIC" ) {
const G4double ftfpMinE = 3.0*CLHEP::GeV;
const G4double bertMaxE = 6.0*CLHEP::GeV;
const G4double ftfpMinE_ATL = 9.0*CLHEP::GeV;
const G4double bertMaxE_ATL = 12.0*CLHEP::GeV;
const G4double ftfpMaxE = 25.0*CLHEP::GeV;
const G4double qgspMinE = 12.0*CLHEP::GeV;
theFTFPmodel->SetMinEnergy( 0.0 );
theIonBICmodel->SetMaxEnergy( bertMaxE );
theFTFPmodel_halfConstrained->SetMinEnergy( ftfpMinE );
if ( fPhysicsCase == "FTFP_BERT_ATL" ) {
theBERTmodel->SetMaxEnergy( bertMaxE_ATL );
theFTFPmodel_constrained->SetMinEnergy( ftfpMinE_ATL );
} else {
theBERTmodel->SetMaxEnergy( bertMaxE );
theFTFPmodel_constrained->SetMinEnergy( ftfpMinE );
}
if ( fPhysicsCase == "FTFP_INCLXX" ) {
theINCLmodel->SetMaxEnergy( bertMaxE );
}
if ( fPhysicsCase == "QGSP_BERT" ||
fPhysicsCase == "QGSP_BIC" ) {
theFTFPmodel_constrained->SetMaxEnergy( ftfpMaxE );
theQGSPmodel->SetMinEnergy( qgspMinE );
theBICmodel->SetMaxEnergy( bertMaxE );
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
HadronicGenerator::~HadronicGenerator() {
fPartTable->DeleteAllParticles();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool HadronicGenerator::IsApplicable( const G4String &nameProjectile,
const G4double projectileEnergy ) {
G4ParticleDefinition* projectileDefinition = fPartTable->FindParticle( nameProjectile );
return IsApplicable( projectileDefinition, projectileEnergy );
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool HadronicGenerator::IsApplicable( G4ParticleDefinition* projectileDefinition,
const G4double projectileEnergy ) {
G4bool isApplicable = true;
// No restrictions for "physics list proxies" because they cover all hadron types and energies.
// For the individual models, instead, we need to consider their limitations.
if ( fPhysicsCase == "BERT" ) {
// We consider BERT model below 15 GeV and not for antibaryons
if ( projectileEnergy > 15.0*CLHEP::GeV ||
projectileDefinition == G4AntiProton::Definition() ||
projectileDefinition == G4AntiNeutron::Definition() ||
projectileDefinition == G4AntiDeuteron::Definition() ||
projectileDefinition == G4AntiTriton::Definition() ||
projectileDefinition == G4AntiHe3::Definition() ||
projectileDefinition == G4AntiAlpha::Definition() ||
projectileDefinition == G4AntiLambda::Definition() ||
projectileDefinition == G4AntiSigmaMinus::Definition() ||
projectileDefinition == G4AntiSigmaPlus::Definition() ||
projectileDefinition == G4AntiXiMinus::Definition() ||
projectileDefinition == G4AntiXiZero::Definition() ||
projectileDefinition == G4AntiOmegaMinus::Definition() ) {
isApplicable = false;
}
} else if ( fPhysicsCase == "QGSP" ) {
// We consider QGSP above 2 GeV and not for light ions or anti-ions
if ( projectileEnergy < 2.0*CLHEP::GeV ||
projectileDefinition == G4Deuteron::Definition() ||
projectileDefinition == G4Triton::Definition() ||
projectileDefinition == G4He3::Definition() ||
projectileDefinition == G4Alpha::Definition() ||
projectileDefinition == G4AntiDeuteron::Definition() ||
projectileDefinition == G4AntiTriton::Definition() ||
projectileDefinition == G4AntiHe3::Definition() ||
projectileDefinition == G4AntiAlpha::Definition() ) {
isApplicable = false;
}
} else if ( fPhysicsCase == "BIC" || fPhysicsCase == "INCL" ) {
// We consider BIC and INCL models only for pions and nucleons below 10 GeV
// (although in recent versions INCL is capable of handling more hadrons
// and up to higher energies)
if ( ( ( projectileDefinition != G4PionMinus::Definition() ) &&
( projectileDefinition != G4PionPlus::Definition() ) &&
( projectileDefinition != G4Proton::Definition() ) &&
( projectileDefinition != G4Neutron::Definition() ) ) ||
( projectileEnergy > 10.0*CLHEP::GeV ) ) {
isApplicable = false;
}
} else if ( fPhysicsCase == "IonBIC" ) {
// We consider IonBIC models only for deuteron, triton, He3, alpha
// with energies below 10 GeV / nucleon
if ( ! ( ( projectileDefinition == G4Deuteron::Definition() &&
projectileEnergy < 2*10.0*CLHEP::GeV ) ||
( projectileDefinition == G4Triton::Definition() &&
projectileEnergy < 3*10.0*CLHEP::GeV ) ||
( projectileDefinition == G4He3::Definition() &&
projectileEnergy < 3*10.0*CLHEP::GeV ) ||
( projectileDefinition == G4Alpha::Definition() &&
projectileEnergy < 4*10.0*CLHEP::GeV ) ) ) {
isApplicable = false;
}
}
return isApplicable;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VParticleChange* HadronicGenerator::
GenerateInteraction( const G4String &nameProjectile, const G4double projectileEnergy,
const G4ThreeVector &projectileDirection, G4Material* targetMaterial ) {
G4ParticleDefinition* projectileDefinition = fPartTable->FindParticle( nameProjectile );
return GenerateInteraction( projectileDefinition, projectileEnergy,
projectileDirection, targetMaterial );
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VParticleChange* HadronicGenerator::
GenerateInteraction( G4ParticleDefinition* projectileDefinition, const G4double projectileEnergy,
const G4ThreeVector &projectileDirection, G4Material* targetMaterial ) {
// This is the most important method of the HadronicGenerator class:
// the method performs the specified hadronic interaction
// (by invoking the "PostStepDoIt" method of the corresponding hadronic process)
// and returns the final state, i.e. the secondaries produced by the collision.
// It is a relatively short method because the heavy load of setting up all
// possible hadronic processes - with their hadronic models, transition regions,
// and cross sections (the latter is needed for sampling the target nucleus from
// the target material) - was already done by the constructor of the class.
G4VParticleChange* aChange = nullptr;
if ( projectileDefinition == nullptr ) {
G4cerr << "ERROR: projectileDefinition is NULL !" << G4endl;
return aChange;
}
// Debugging print-out
//G4cout << "\t" << projectileDefinition->GetParticleName()
// << "\t" << projectileEnergy/CLHEP::GeV
// << " GeV \t" << projectileDirection
// << "\t" << ( targetMaterial ? targetMaterial->GetName() : "NULL" );
if ( ! IsApplicable( projectileDefinition, projectileEnergy ) ) {
//G4cout << " -> NOT applicable !" ; //<< G4endl; // Debugging print-out
return aChange;
}
//G4cout << G4endl;
// Check Geant4 state (not strictly needed)
//if ( ! G4StateManager::GetStateManager()->SetNewState( G4State_PreInit ) ) {
// G4cerr << "ERROR: No possible to set G4State_PreInit !" << G4endl;
// return aChange;
//}
// Geometry definition (not strictly needed)
//const G4double dimX = 1.0*mm;
//const G4double dimY = 1.0*mm;
//const G4double dimZ = 1.0*mm;
//G4Box* sFrame = new G4Box( "Box", dimX, dimY, dimZ );
//G4LogicalVolume* lFrame = new G4LogicalVolume( sFrame, targetMaterial, "Box", 0, 0, 0 );
//G4PVPlacement* pFrame = new G4PVPlacement( 0, G4ThreeVector(), "Box", lFrame, 0, false, 0 );
//G4TransportationManager::GetTransportationManager()->SetWorldForTracking( pFrame );
// Projectile track & step
G4DynamicParticle dParticle( projectileDefinition, projectileDirection, projectileEnergy );
const G4double aTime = 0.0;
const G4ThreeVector aPosition = G4ThreeVector( 0.0, 0.0, 0.0 );
G4Track* gTrack = new G4Track( &dParticle, aTime, aPosition );
G4TouchableHandle fpTouchable( new G4TouchableHistory ); // Not strictly needed
gTrack->SetTouchableHandle( fpTouchable ); // Not strictly needed
G4Step* step = new G4Step;
step->SetTrack( gTrack );
gTrack->SetStep( step );
G4StepPoint* aPoint = new G4StepPoint;
aPoint->SetPosition( aPosition );
aPoint->SetMaterial( targetMaterial );
step->SetPreStepPoint( aPoint );
dParticle.SetKineticEnergy( projectileEnergy );
gTrack->SetStep( step );
gTrack->SetKineticEnergy( projectileEnergy );
// Change Geant4 state: from "PreInit" to "Idle" (not strictly needed)
//if ( ! G4StateManager::GetStateManager()->SetNewState( G4State_Idle ) ) {
// G4cerr << "ERROR: No possible to set G4State_Idle !" << G4endl;
// return aChange;
//}
// Finally, the hadronic interaction
G4HadronicProcess* theProcess = nullptr;
auto mapIndex = fProcessMap.find( projectileDefinition );
if ( mapIndex != fProcessMap.end() ) theProcess = mapIndex->second;
if ( theProcess ) aChange = theProcess->PostStepDoIt( *gTrack, *step );
//**************************************************
//delete pFrame;
//delete lFrame;
//delete sFrame;
return aChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......